From fdf9a8a453aa9a4b93b32d1aaba9f6443bad36fa Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Fri, 16 Feb 2018 16:09:46 +0100 Subject: [PATCH] move preprocessor to submodule --- .gitmodules | 3 + Makefile.am | 15 +- configure.ac | 32 +- mex/build/bytecode.am | 2 +- preprocessor | 1 + preprocessor/CodeInterpreter.hh | 2027 ------- preprocessor/ComputingTasks.cc | 4563 --------------- preprocessor/ComputingTasks.hh | 1125 ---- preprocessor/ConfigFile.cc | 783 --- preprocessor/ConfigFile.hh | 147 - preprocessor/DataTree.cc | 755 --- preprocessor/DataTree.hh | 378 -- preprocessor/Doxyfile | 1514 ----- preprocessor/DynamicModel.cc | 6077 ------------------- preprocessor/DynamicModel.hh | 579 -- preprocessor/DynareBison.yy | 3766 ------------ preprocessor/DynareFlex.ll | 1051 ---- preprocessor/DynareMain.cc | 413 -- preprocessor/DynareMain1.cc | 54 - preprocessor/DynareMain2.cc | 82 - preprocessor/ExprNode.cc | 6406 --------------------- preprocessor/ExprNode.hh | 1093 ---- preprocessor/ExtendedPreprocessorTypes.hh | 56 - preprocessor/ExternalFunctionsTable.cc | 117 - preprocessor/ExternalFunctionsTable.hh | 127 - preprocessor/Makefile.am | 95 - preprocessor/MinimumFeedbackSet.cc | 457 -- preprocessor/MinimumFeedbackSet.hh | 84 - preprocessor/ModFile.cc | 1558 ----- preprocessor/ModFile.hh | 181 - preprocessor/ModelTree.cc | 2028 ------- preprocessor/ModelTree.hh | 412 -- preprocessor/NumericalConstants.cc | 63 - preprocessor/NumericalConstants.hh | 48 - preprocessor/NumericalInitialization.cc | 649 --- preprocessor/NumericalInitialization.hh | 190 - preprocessor/ParsingDriver.cc | 3129 ---------- preprocessor/ParsingDriver.hh | 780 --- preprocessor/Shocks.cc | 631 -- preprocessor/Shocks.hh | 168 - preprocessor/SigmaeInitialization.cc | 98 - preprocessor/SigmaeInitialization.hh | 63 - preprocessor/Statement.cc | 349 -- preprocessor/Statement.hh | 195 - preprocessor/StaticModel.cc | 2882 --------- preprocessor/StaticModel.hh | 332 -- preprocessor/SteadyStateModel.cc | 316 - preprocessor/SteadyStateModel.hh | 60 - preprocessor/SymbolList.cc | 60 - preprocessor/SymbolList.hh | 60 - preprocessor/SymbolTable.cc | 986 ---- preprocessor/SymbolTable.hh | 490 -- preprocessor/WarningConsolidation.cc | 109 - preprocessor/WarningConsolidation.hh | 68 - preprocessor/macro/MacroBison.yy | 214 - preprocessor/macro/MacroDriver.cc | 238 - preprocessor/macro/MacroDriver.hh | 240 - preprocessor/macro/MacroFlex.ll | 567 -- preprocessor/macro/MacroValue.cc | 450 -- preprocessor/macro/MacroValue.hh | 395 -- preprocessor/macro/Makefile.am | 23 - 61 files changed, 22 insertions(+), 49812 deletions(-) create mode 160000 preprocessor delete mode 100644 preprocessor/CodeInterpreter.hh delete mode 100644 preprocessor/ComputingTasks.cc delete mode 100644 preprocessor/ComputingTasks.hh delete mode 100644 preprocessor/ConfigFile.cc delete mode 100644 preprocessor/ConfigFile.hh delete mode 100644 preprocessor/DataTree.cc delete mode 100644 preprocessor/DataTree.hh delete mode 100644 preprocessor/Doxyfile delete mode 100644 preprocessor/DynamicModel.cc delete mode 100644 preprocessor/DynamicModel.hh delete mode 100644 preprocessor/DynareBison.yy delete mode 100644 preprocessor/DynareFlex.ll delete mode 100644 preprocessor/DynareMain.cc delete mode 100644 preprocessor/DynareMain1.cc delete mode 100644 preprocessor/DynareMain2.cc delete mode 100644 preprocessor/ExprNode.cc delete mode 100644 preprocessor/ExprNode.hh delete mode 100644 preprocessor/ExtendedPreprocessorTypes.hh delete mode 100644 preprocessor/ExternalFunctionsTable.cc delete mode 100644 preprocessor/ExternalFunctionsTable.hh delete mode 100644 preprocessor/Makefile.am delete mode 100644 preprocessor/MinimumFeedbackSet.cc delete mode 100644 preprocessor/MinimumFeedbackSet.hh delete mode 100644 preprocessor/ModFile.cc delete mode 100644 preprocessor/ModFile.hh delete mode 100644 preprocessor/ModelTree.cc delete mode 100644 preprocessor/ModelTree.hh delete mode 100644 preprocessor/NumericalConstants.cc delete mode 100644 preprocessor/NumericalConstants.hh delete mode 100644 preprocessor/NumericalInitialization.cc delete mode 100644 preprocessor/NumericalInitialization.hh delete mode 100644 preprocessor/ParsingDriver.cc delete mode 100644 preprocessor/ParsingDriver.hh delete mode 100644 preprocessor/Shocks.cc delete mode 100644 preprocessor/Shocks.hh delete mode 100644 preprocessor/SigmaeInitialization.cc delete mode 100644 preprocessor/SigmaeInitialization.hh delete mode 100644 preprocessor/Statement.cc delete mode 100644 preprocessor/Statement.hh delete mode 100644 preprocessor/StaticModel.cc delete mode 100644 preprocessor/StaticModel.hh delete mode 100644 preprocessor/SteadyStateModel.cc delete mode 100644 preprocessor/SteadyStateModel.hh delete mode 100644 preprocessor/SymbolList.cc delete mode 100644 preprocessor/SymbolList.hh delete mode 100644 preprocessor/SymbolTable.cc delete mode 100644 preprocessor/SymbolTable.hh delete mode 100644 preprocessor/WarningConsolidation.cc delete mode 100644 preprocessor/WarningConsolidation.hh delete mode 100644 preprocessor/macro/MacroBison.yy delete mode 100644 preprocessor/macro/MacroDriver.cc delete mode 100644 preprocessor/macro/MacroDriver.hh delete mode 100644 preprocessor/macro/MacroFlex.ll delete mode 100644 preprocessor/macro/MacroValue.cc delete mode 100644 preprocessor/macro/MacroValue.hh delete mode 100644 preprocessor/macro/Makefile.am diff --git a/.gitmodules b/.gitmodules index ef21bb2de..c6a396a39 100644 --- a/.gitmodules +++ b/.gitmodules @@ -30,3 +30,6 @@ [submodule "contrib/jsonlab"] path = contrib/jsonlab url = https://github.com/fangq/jsonlab.git +[submodule "preprocessor"] + path = preprocessor + url = https://github.com/DynareTeam/dynare-preprocessor.git diff --git a/Makefile.am b/Makefile.am index b23681f95..249478ab7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -35,6 +35,17 @@ EXTRA_DIST = \ scripts \ .dir-locals.el +all-local: preprocessor/src/dynare_m + { \ + if [ -z "`file preprocessor/src/dynare_m | grep x86.64`" ]; then \ + ARCH="32"; \ + else \ + ARCH="64"; \ + fi; \ + mkdir -p $(abs_srcdir)/matlab/preprocessor$$ARCH; \ + cp preprocessor/src/dynare_m $(abs_srcdir)/matlab/preprocessor$$ARCH; \ + } + dist-hook: rm -rf `find $(distdir)/matlab $(distdir)/examples -name *~` rm -rf $(distdir)/matlab/preprocessor* $(distdir)/matlab/dynare_version.m @@ -51,13 +62,13 @@ install-exec-local: find $(DESTDIR)$(pkglibdir) -name LICENSE.md -delete rm -rf $(DESTDIR)$(pkglibdir)/matlab/preprocessor* { \ - if [ -z "`file preprocessor/dynare_m | grep x86.64`" ]; then \ + if [ -z "`file preprocessor/src/dynare_m | grep x86.64`" ]; then \ ARCH="32"; \ else \ ARCH="64"; \ fi; \ mkdir -p $(DESTDIR)$(pkglibdir)/matlab/preprocessor$$ARCH; \ - cp preprocessor/dynare_m $(DESTDIR)$(pkglibdir)/matlab/preprocessor$$ARCH; \ + cp preprocessor/src/dynare_m $(DESTDIR)$(pkglibdir)/matlab/preprocessor$$ARCH; \ } uninstall-local: diff --git a/configure.ac b/configure.ac index 8d18442d2..7a01602d7 100755 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. -dnl Copyright (C) 2009-2017 Dynare Team +dnl Copyright (C) 2009-2018 Dynare Team dnl dnl This file is part of Dynare. dnl @@ -19,9 +19,11 @@ dnl along with Dynare. If not, see . AC_PREREQ([2.62]) AC_INIT([dynare], [4.6-unstable]) -AC_CONFIG_SRCDIR([preprocessor/DynareMain.cc]) +AC_CONFIG_SRCDIR([preprocessor/src/DynareMain.cc]) AM_INIT_AUTOMAKE([1.11 -Wall -Wno-portability foreign no-dist-gzip dist-xz tar-pax]) +AC_CONFIG_SUBDIRS([preprocessor]) + AC_PROG_CC AC_PROG_CXX @@ -61,17 +63,6 @@ AX_PROG_LN_S AC_PROG_MKDIR_P -AM_PROG_LEX -# Hack to get lex include dir, ticket #575 -AC_PATH_PROG([LEXPATH], [$LEX]) -AC_SUBST([LEXINC], [`eval "echo $LEXPATH | sed 's|\(.*\)$LEX$|\1../include|'"`]) - -AC_CHECK_PROG([YACC], [bison], [bison]) -if test "x$YACC" = "x"; then - unset YACC # AM_MISSING_PROG needs an unset variable: an empty variable won't do - AM_MISSING_PROG([YACC], [bison]) -fi - # We need 1.36 because of unordered_{set,hash} used by Dynare++ AX_BOOST_BASE([1.36], [], [AC_MSG_ERROR([Can't find Boost >= 1.36])]) @@ -121,9 +112,6 @@ if test "x$PDFLATEX" != "x" -a "x$BIBTEX" != "x"; then fi AM_CONDITIONAL([HAVE_BEAMER], [test "x$ax_latex_have_beamer" = "xyes"]) -AC_CHECK_PROG([DOXYGEN], [doxygen], [doxygen]) -AM_CONDITIONAL([HAVE_DOXYGEN], [test "x$DOXYGEN" != "x"]) - AC_CHECK_PROG([CTANGLE], [ctangle], [ctangle]) AM_CONDITIONAL([HAVE_CTANGLE], [test "x$CTANGLE" != "x"]) if test "x$CTANGLE" = "x"; then @@ -166,8 +154,6 @@ AX_PTHREAD AC_CONFIG_FILES([Makefile VERSION - preprocessor/macro/Makefile - preprocessor/Makefile doc/Makefile doc/preprocessor/Makefile doc/macroprocessor/Makefile @@ -220,8 +206,6 @@ AM_CONDITIONAL([ENABLE_ORG_EXPORT], [test "x$enable_org_export" != "x"]) # Construct final output message -BUILD_PREPROCESSOR="yes" - if test "x$ax_blas_ok" = "xyes" -a "x$ax_lapack_ok" = "xyes" -a "x$has_matio" = "xyes"; then if test x"$ax_pthread_ok" = "xyes"; then BUILD_DYNAREPLUSPLUS="yes" @@ -250,12 +234,6 @@ else BUILD_OTHER_PDF_DOC="no (missing pdflatex)" fi -if test "x$DOXYGEN" != "x"; then - BUILD_DYNARE_PREPROC_DOC="yes" -else - BUILD_DYNARE_PREPROC_DOC="no (missing doxygen)" -fi - if test "x$enable_org_export" != "x"; then BUILD_DYNARE_INTERNAL_DOC="yes" else @@ -293,7 +271,6 @@ AC_MSG_NOTICE([ Dynare is now configured for building the following components... Binaries (with "make"): - Dynare preprocessor: $BUILD_PREPROCESSOR Dynare++: $BUILD_DYNAREPLUSPLUS PDF documentation (with "make pdf"): @@ -304,7 +281,6 @@ PDF documentation (with "make pdf"): HTML documentation (with "make html"): Dynare reference manual: $BUILD_DYNARE_HTML_MANUAL - Dynare preprocessor developer doc: $BUILD_DYNARE_PREPROC_DOC Dynare internal doc: $BUILD_DYNARE_INTERNAL_DOC Info documentation (with "make info"): $BUILD_DYNARE_INFO diff --git a/mex/build/bytecode.am b/mex/build/bytecode.am index 3fff91434..8720c316a 100644 --- a/mex/build/bytecode.am +++ b/mex/build/bytecode.am @@ -1,6 +1,6 @@ mex_PROGRAMS = bytecode -bytecode_CPPFLAGS = -Wno-maybe-uninitialized $(AM_CPPFLAGS) -I$(top_srcdir)/../../sources -I$(top_srcdir)/../../sources/bytecode -I$(top_srcdir)/../../../preprocessor +bytecode_CPPFLAGS = -Wno-maybe-uninitialized $(AM_CPPFLAGS) -I$(top_srcdir)/../../sources -I$(top_srcdir)/../../sources/bytecode -I$(top_srcdir)/../../../preprocessor/src TOPDIR = $(top_srcdir)/../../sources/bytecode diff --git a/preprocessor b/preprocessor new file mode 160000 index 000000000..662d3f71c --- /dev/null +++ b/preprocessor @@ -0,0 +1 @@ +Subproject commit 662d3f71cecf0d8a32e94564071bf9cfc27eae4d diff --git a/preprocessor/CodeInterpreter.hh b/preprocessor/CodeInterpreter.hh deleted file mode 100644 index 8939950fc..000000000 --- a/preprocessor/CodeInterpreter.hh +++ /dev/null @@ -1,2027 +0,0 @@ -/* - * 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 . - */ - -#ifndef _CODEINTERPRETER_HH -#define _CODEINTERPRETER_HH -//#define DEBUGL -#include - -#include -#include -#include -#include -#include -#ifdef LINBCG -# include "linbcg.hh" -#endif -#ifdef BYTE_CODE -# ifndef DEBUG_EX -# include "mex.h" -# else -# include "mex_interface.hh" -# endif -#endif - -#include - -#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(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(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(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(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(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 -{ -public: - inline - FDIMT_() : TagWithOneArgument::TagWithOneArgument(FDIMT) - { - }; - inline - FDIMT_(unsigned int size_arg) : TagWithOneArgument::TagWithOneArgument(FDIMT, size_arg) - { - }; - inline unsigned int - get_size() - { - return arg1; - }; -}; - -class FDIMST_ : public TagWithOneArgument -{ -public: - inline - FDIMST_() : TagWithOneArgument::TagWithOneArgument(FDIMST) - { - }; - inline - FDIMST_(const unsigned int size_arg) : TagWithOneArgument::TagWithOneArgument(FDIMST, size_arg) - { - }; - inline unsigned int - get_size() - { - return arg1; - }; -}; - -class FLDC_ : public TagWithOneArgument -{ -public: - inline - FLDC_() : TagWithOneArgument::TagWithOneArgument(FLDC) - { - }; - inline - FLDC_(const double value_arg) : TagWithOneArgument::TagWithOneArgument(FLDC, value_arg) - { - }; - inline double - get_value() - { - return arg1; - }; -}; - -class FLDU_ : public TagWithOneArgument -{ -public: - inline - FLDU_() : TagWithOneArgument::TagWithOneArgument(FLDU) - { - }; - inline - FLDU_(const unsigned int pos_arg) : TagWithOneArgument::TagWithOneArgument(FLDU, pos_arg) - { - }; - inline unsigned int - get_pos() - { - return arg1; - }; -}; - -class FLDSU_ : public TagWithOneArgument -{ -public: - inline - FLDSU_() : TagWithOneArgument::TagWithOneArgument(FLDSU) - { - }; - inline - FLDSU_(const unsigned int pos_arg) : TagWithOneArgument::TagWithOneArgument(FLDSU, pos_arg) - { - }; - inline unsigned int - get_pos() - { - return arg1; - }; -}; - -class FLDR_ : public TagWithOneArgument -{ -public: - inline - FLDR_() : TagWithOneArgument::TagWithOneArgument(FLDR) - { - }; - inline - FLDR_(const unsigned int pos_arg) : TagWithOneArgument::TagWithOneArgument(FLDR, pos_arg) - { - }; - inline unsigned int - get_pos() - { - return arg1; - }; -}; - -class FLDT_ : public TagWithOneArgument -{ -public: - inline - FLDT_() : TagWithOneArgument::TagWithOneArgument(FLDT) - { - }; - inline - FLDT_(const unsigned int pos_arg) : TagWithOneArgument::TagWithOneArgument(FLDT, pos_arg) - { - }; - inline unsigned int - get_pos() - { - return arg1; - }; -}; - -class FLDST_ : public TagWithOneArgument -{ -public: - inline - FLDST_() : TagWithOneArgument::TagWithOneArgument(FLDST) - { - }; - inline - FLDST_(const unsigned int pos_arg) : TagWithOneArgument::TagWithOneArgument(FLDST, pos_arg) - { - }; - inline unsigned int - get_pos() - { - return arg1; - }; -}; - -class FSTPT_ : public TagWithOneArgument -{ -public: - inline - FSTPT_() : TagWithOneArgument::TagWithOneArgument(FSTPT) - { - }; - inline - FSTPT_(const unsigned int pos_arg) : TagWithOneArgument::TagWithOneArgument(FSTPT, pos_arg) - { - }; - inline unsigned int - get_pos() - { - return arg1; - }; -}; - -class FSTPST_ : public TagWithOneArgument -{ -public: - inline - FSTPST_() : TagWithOneArgument::TagWithOneArgument(FSTPST) - { - }; - inline - FSTPST_(const unsigned int pos_arg) : TagWithOneArgument::TagWithOneArgument(FSTPST, pos_arg) - { - }; - inline unsigned int - get_pos() - { - return arg1; - }; -}; - -class FSTPR_ : public TagWithOneArgument -{ -public: - inline - FSTPR_() : TagWithOneArgument::TagWithOneArgument(FSTPR) - { - }; - inline - FSTPR_(const unsigned int pos_arg) : TagWithOneArgument::TagWithOneArgument(FSTPR, pos_arg) - { - }; - inline unsigned int - get_pos() - { - return arg1; - }; -}; - -class FSTPU_ : public TagWithOneArgument -{ -public: - inline - FSTPU_() : TagWithOneArgument::TagWithOneArgument(FSTPU) - { - }; - inline - FSTPU_(const unsigned int pos_arg) : TagWithOneArgument::TagWithOneArgument(FSTPU, pos_arg) - { - }; - inline unsigned int - get_pos() - { - return arg1; - }; -}; - -class FSTPSU_ : public TagWithOneArgument -{ -public: - inline - FSTPSU_() : TagWithOneArgument::TagWithOneArgument(FSTPSU) - { - }; - inline - FSTPSU_(const unsigned int pos_arg) : TagWithOneArgument::TagWithOneArgument(FSTPSU, pos_arg) - { - }; - inline unsigned int - get_pos() - { - return arg1; - }; -}; - -class FSTPG_ : public TagWithOneArgument -{ -public: - inline - FSTPG_() : TagWithOneArgument::TagWithOneArgument(FSTPG, 0) - { - }; - inline - FSTPG_(const unsigned int pos_arg) : TagWithOneArgument::TagWithOneArgument(FSTPG, pos_arg) - { - }; - inline unsigned int - get_pos() - { - return arg1; - }; -}; - -class FSTPG2_ : public TagWithTwoArguments -{ -public: - inline - FSTPG2_() : TagWithTwoArguments::TagWithTwoArguments(FSTPG2, 0, 0) - { - }; - inline - FSTPG2_(const unsigned int pos_arg1, const unsigned int pos_arg2) : TagWithTwoArguments::TagWithTwoArguments(FSTPG2, pos_arg1, pos_arg2) - { - }; - inline unsigned int - get_row() - { - return arg1; - }; - inline unsigned int - get_col() - { - return arg2; - }; -}; - -class FSTPG3_ : public TagWithFourArguments -{ -public: - inline - FSTPG3_() : TagWithFourArguments::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::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 -{ -public: - inline - FUNARY_() : TagWithOneArgument::TagWithOneArgument(FUNARY) - { - }; - inline - FUNARY_(uint8_t op_type_arg) : TagWithOneArgument::TagWithOneArgument(FUNARY, op_type_arg) - { - }; - inline uint8_t - get_op_type() - { - return arg1; - }; -}; - -class FBINARY_ : public TagWithOneArgument -{ -public: - inline - FBINARY_() : TagWithOneArgument::TagWithOneArgument(FBINARY) - { - }; - inline - FBINARY_(const int op_type_arg) : TagWithOneArgument::TagWithOneArgument(FBINARY, op_type_arg) - { - }; - inline uint8_t - get_op_type() - { - return arg1; - }; -}; - -class FTRINARY_ : public TagWithOneArgument -{ -public: - inline - FTRINARY_() : TagWithOneArgument::TagWithOneArgument(FTRINARY) - { - }; - inline - FTRINARY_(const int op_type_arg) : TagWithOneArgument::TagWithOneArgument(FTRINARY, op_type_arg) - { - }; - inline uint8_t - get_op_type() - { - return arg1; - }; -}; - -class FOK_ : public TagWithOneArgument -{ -public: - inline - FOK_() : TagWithOneArgument::TagWithOneArgument(FOK) - { - }; - inline - FOK_(const int arg_arg) : TagWithOneArgument::TagWithOneArgument(FOK, arg_arg) - { - }; - inline int - get_arg() - { - return arg1; - }; -}; - -class FJMPIFEVAL_ : public TagWithOneArgument -{ -public: - inline - FJMPIFEVAL_() : TagWithOneArgument::TagWithOneArgument(FJMPIFEVAL) - { - }; - inline - FJMPIFEVAL_(unsigned int arg_pos) : TagWithOneArgument::TagWithOneArgument(FJMPIFEVAL, arg_pos) - { - }; - inline unsigned int - get_pos() - { - return arg1; - } -}; - -class FJMP_ : public TagWithOneArgument -{ -public: - inline - FJMP_() : TagWithOneArgument::TagWithOneArgument(FJMP) - { - }; - inline - FJMP_(unsigned int arg_pos) : TagWithOneArgument::TagWithOneArgument(FJMP, arg_pos) - { - }; - inline unsigned int - get_pos() - { - return arg1; - } -}; - -class FLDTEF_ : public TagWithOneArgument -{ -public: - inline - FLDTEF_() : TagWithOneArgument::TagWithOneArgument(FLDTEF) - { - }; - inline - FLDTEF_(unsigned int number) : TagWithOneArgument::TagWithOneArgument(FLDTEF, number) - { - }; - inline unsigned int - get_number() - { - return arg1; - } -}; - -class FSTPTEF_ : public TagWithOneArgument -{ -public: - inline - FSTPTEF_() : TagWithOneArgument::TagWithOneArgument(FSTPTEF) - { - }; - inline - FSTPTEF_(unsigned int number) : TagWithOneArgument::TagWithOneArgument(FSTPTEF, number) - { - }; - inline unsigned int - get_number() - { - return arg1; - } -}; - -class FLDTEFD_ : public TagWithTwoArguments -{ -public: - inline - FLDTEFD_() : TagWithTwoArguments::TagWithTwoArguments(FLDTEFD) - { - }; - inline - FLDTEFD_(unsigned int indx, unsigned int row) : TagWithTwoArguments::TagWithTwoArguments(FLDTEFD, indx, row) - { - }; - inline unsigned int - get_indx() - { - return arg1; - }; - inline unsigned int - get_row() - { - return arg2; - }; -}; - -class FSTPTEFD_ : public TagWithTwoArguments -{ -public: - inline - FSTPTEFD_() : TagWithTwoArguments::TagWithTwoArguments(FSTPTEFD) - { - }; - inline - FSTPTEFD_(unsigned int indx, unsigned int row) : TagWithTwoArguments::TagWithTwoArguments(FSTPTEFD, indx, row) - { - }; - inline unsigned int - get_indx() - { - return arg1; - }; - inline unsigned int - get_row() - { - return arg2; - }; -}; - -class FLDTEFDD_ : public TagWithThreeArguments -{ -public: - inline - FLDTEFDD_() : TagWithThreeArguments::TagWithThreeArguments(FLDTEFDD) - { - }; - inline - FLDTEFDD_(unsigned int indx, unsigned int row, unsigned int col) : TagWithThreeArguments::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 -{ -public: - inline - FSTPTEFDD_() : TagWithThreeArguments::TagWithThreeArguments(FSTPTEFDD) - { - }; - inline - FSTPTEFDD_(unsigned int indx, unsigned int row, unsigned int col) : TagWithThreeArguments::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 -{ -public: - inline - FLDVS_() : TagWithTwoArguments::TagWithTwoArguments(FLDVS) - { - }; - inline - FLDVS_(uint8_t type_arg, const unsigned int pos_arg) : TagWithTwoArguments::TagWithTwoArguments(FLDVS, type_arg, pos_arg) - { - }; - inline uint8_t - get_type() - { - return arg1; - }; - inline unsigned int - get_pos() - { - return arg2; - }; -}; - -class FLDSV_ : public TagWithTwoArguments -{ -public: - inline - FLDSV_() : TagWithTwoArguments::TagWithTwoArguments(FLDSV) - { - }; - inline - FLDSV_(const uint8_t type_arg, const unsigned int pos_arg) : - TagWithTwoArguments::TagWithTwoArguments(FLDSV, type_arg, pos_arg) - { - }; - inline uint8_t - get_type() - { - return arg1; - }; - inline unsigned int - get_pos() - { - return arg2; - }; -}; - -class FSTPSV_ : public TagWithTwoArguments -{ -public: - inline - FSTPSV_() : TagWithTwoArguments::TagWithTwoArguments(FSTPSV) - { - }; - inline - FSTPSV_(const uint8_t type_arg, const unsigned int pos_arg) : - TagWithTwoArguments::TagWithTwoArguments(FSTPSV, type_arg, pos_arg) - { - }; - inline uint8_t - get_type() - { - return arg1; - }; - inline unsigned int - get_pos() - { - return arg2; - }; -}; - -class FLDV_ : public TagWithThreeArguments -{ -public: - inline - FLDV_() : TagWithThreeArguments::TagWithThreeArguments(FLDV) - { - }; - inline - FLDV_(const int type_arg, const unsigned int pos_arg) : - TagWithThreeArguments::TagWithThreeArguments(FLDV, type_arg, pos_arg, 0) - { - }; - inline - FLDV_(const int type_arg, const unsigned int pos_arg, const int lead_lag_arg) : - TagWithThreeArguments::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 -{ -public: - inline - FSTPV_() : TagWithThreeArguments::TagWithThreeArguments(FSTPV) - { - }; - inline - FSTPV_(const int type_arg, const unsigned int pos_arg) : - TagWithThreeArguments::TagWithThreeArguments(FSTPV, type_arg, pos_arg, 0) - { - }; - inline - FSTPV_(const int type_arg, const unsigned int pos_arg, const int lead_lag_arg) : - TagWithThreeArguments::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 -{ - string func_name; - string arg_func_name; - unsigned int add_input_arguments, row, col; - external_function_type function_type; -public: - inline - FCALL_() : TagWithFourArguments::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::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(&op_code), sizeof(op_code)); - CompileCode.write(reinterpret_cast(&arg1), sizeof(arg1)); - CompileCode.write(reinterpret_cast(&arg2), sizeof(arg2)); - CompileCode.write(reinterpret_cast(&arg4), sizeof(arg4)); - CompileCode.write(reinterpret_cast(&add_input_arguments), sizeof(add_input_arguments)); - CompileCode.write(reinterpret_cast(&row), sizeof(row)); - CompileCode.write(reinterpret_cast(&col), sizeof(col)); - CompileCode.write(reinterpret_cast(&function_type), sizeof(function_type)); - size_t size = func_name.size(); - CompileCode.write(reinterpret_cast(&size), sizeof(int)); - const char *name = func_name.c_str(); - CompileCode.write(reinterpret_cast(name), func_name.size()); - size = arg_func_name.size(); - CompileCode.write(reinterpret_cast(&size), sizeof(int)); - name = arg_func_name.c_str(); - CompileCode.write(reinterpret_cast(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 -{ -private: - unsigned int equation; - uint16_t dvariable1, dvariable2, dvariable3; - int8_t lag1, lag2, lag3; -public: - inline - FNUMEXPR_() : TagWithOneArgument::TagWithOneArgument(FNUMEXPR) - { - }; - inline - FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg) : TagWithOneArgument::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::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::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::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::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::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::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(this), sizeof(FNUMEXPR_)); - instruction_number++; - }; -}; - -class FBEGINBLOCK_ -{ -private: - uint8_t op_code; - int size; - uint8_t type; - vector variable; - vector equation; - vector other_endogenous; - vector exogenous; - vector det_exogenous; - bool is_linear; - vector 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 &variable_arg, const vector &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 &det_exogenous_arg, const vector &exogenous_arg, const vector &other_endogenous_arg) - { - op_code = FBEGINBLOCK; size = size_arg; type = type_arg; - variable = vector(variable_arg.begin()+first_element, variable_arg.begin()+(first_element+block_size)); - equation = vector(equation_arg.begin()+first_element, equation_arg.begin()+(first_element+block_size)); - det_exogenous = vector(det_exogenous_arg); - exogenous = vector(exogenous_arg); - other_endogenous = vector(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 &variable_arg, const vector &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(variable_arg.begin()+first_element, variable_arg.begin()+(first_element+block_size)); - equation = vector(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 - 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 - get_endogenous() - { - return variable; - } - inline vector - get_exogenous() - { - return exogenous; - } - inline void - write(ostream &CompileCode, unsigned int &instruction_number) - { - CompileCode.write(reinterpret_cast(&op_code), sizeof(op_code)); - CompileCode.write(reinterpret_cast(&size), sizeof(size)); - CompileCode.write(reinterpret_cast(&type), sizeof(type)); - for (int i = 0; i < size; i++) - { - CompileCode.write(reinterpret_cast(&variable[i]), sizeof(variable[0])); - CompileCode.write(reinterpret_cast(&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(&is_linear), sizeof(is_linear)); - CompileCode.write(reinterpret_cast(&endo_nbr), sizeof(endo_nbr)); - CompileCode.write(reinterpret_cast(&Max_Lag), sizeof(Max_Lag)); - CompileCode.write(reinterpret_cast(&Max_Lead), sizeof(Max_Lead)); - CompileCode.write(reinterpret_cast(&u_count_int), sizeof(u_count_int)); - } - CompileCode.write(reinterpret_cast(&nb_col_jacob), sizeof(nb_col_jacob)); - CompileCode.write(reinterpret_cast(&det_exo_size), sizeof(det_exo_size)); - CompileCode.write(reinterpret_cast(&nb_col_det_exo_jacob), sizeof(nb_col_det_exo_jacob)); - CompileCode.write(reinterpret_cast(&exo_size), sizeof(exo_size)); - CompileCode.write(reinterpret_cast(&nb_col_exo_jacob), sizeof(nb_col_exo_jacob)); - CompileCode.write(reinterpret_cast(&other_endo_size), sizeof(other_endo_size)); - CompileCode.write(reinterpret_cast(&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(&det_exogenous[i]), sizeof(det_exogenous[0])); - for (unsigned int i = 0; i < exo_size; i++) - CompileCode.write(reinterpret_cast(&exogenous[i]), sizeof(exogenous[0])); - for (unsigned int i = 0; i < other_endo_size; i++) - CompileCode.write(reinterpret_cast(&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 > tags_liste_t; -class CodeLoad -{ -private: - uint8_t *code; - unsigned int nb_blocks; - vector 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(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 diff --git a/preprocessor/ComputingTasks.cc b/preprocessor/ComputingTasks.cc deleted file mode 100644 index e8372134e..000000000 --- a/preprocessor/ComputingTasks.cc +++ /dev/null @@ -1,4563 +0,0 @@ -/* - * Copyright (C) 2003-2018 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 . - */ - -#include -#include -#include -#include - -using namespace std; - -#include "ComputingTasks.hh" -#include "Statement.hh" - -#include -#include -#include -#include - -SteadyStatement::SteadyStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -SteadyStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.steady_present = true; -} - -void -SteadyStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - output << "steady;" << endl; -} - -void -SteadyStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"steady\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -CheckStatement::CheckStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -CheckStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - output << "oo_.dr.eigval = check(M_,options_,oo_);" << endl; -} - -void -CheckStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.check_present = true; -} - -void -CheckStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"check\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -ModelInfoStatement::ModelInfoStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -ModelInfoStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - //mod_file_struct.model_info_present = true; -} - -void -ModelInfoStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - output << "model_info();" << endl; -} - -void -ModelInfoStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"model_info\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -SimulStatement::SimulStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -SimulStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.perfect_foresight_solver_present = true; -} - -void -SimulStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - output << "perfect_foresight_setup;" << endl - << "perfect_foresight_solver;" << endl; -} - -void -SimulStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"simul\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -PerfectForesightSetupStatement::PerfectForesightSetupStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -PerfectForesightSetupStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - output << "perfect_foresight_setup;" << endl; -} - -void -PerfectForesightSetupStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"perfect_foresight_setup\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -PerfectForesightSolverStatement::PerfectForesightSolverStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -PerfectForesightSolverStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.perfect_foresight_solver_present = true; - // Fill in option_occbin of mod_file_struct - if (options_list.num_options.find("occbin") != options_list.num_options.end()) - mod_file_struct.occbin_option = true; -} - -void -PerfectForesightSolverStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - output << "perfect_foresight_solver;" << endl; -} - -void -PerfectForesightSolverStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"perfect_foresight_solver\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -PriorPosteriorFunctionStatement::PriorPosteriorFunctionStatement(const bool prior_func_arg, - const OptionsList &options_list_arg) : - prior_func(prior_func_arg), - options_list(options_list_arg) -{ -} - -void -PriorPosteriorFunctionStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - OptionsList::string_options_t::const_iterator it2 = options_list.string_options.find("function"); - if (it2 == options_list.string_options.end() || it2->second.empty()) - { - cerr << "ERROR: both the prior_function and posterior_function commands require the 'function' argument" - << endl; - exit(EXIT_FAILURE); - } -} - -void -PriorPosteriorFunctionStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - string type = "posterior"; - if (prior_func) - type = "prior"; - - output << "oo_ = execute_prior_posterior_function(" - << "'" << options_list.string_options.find("function")->second << "', " - << "M_, options_, oo_, estim_params_, bayestopt_, dataset_, dataset_info, " - << "'" << type << "');" << endl; -} - -void -PriorPosteriorFunctionStatement::writeJsonOutput(ostream &output) const -{ - string type = "posterior"; - if (prior_func) - type = "prior"; - output << "{\"statementName\": \"prior_posterior_function\", \"type\": \"" << type << "\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -StochSimulStatement::StochSimulStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg) : - symbol_list(symbol_list_arg), - options_list(options_list_arg) -{ -} - -void -StochSimulStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.stoch_simul_present = true; - - // Fill in option_order of mod_file_struct - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("order"); - if (it != options_list.num_options.end()) - mod_file_struct.order_option = max(mod_file_struct.order_option, atoi(it->second.c_str())); - - // Fill in mod_file_struct.partial_information - it = options_list.num_options.find("partial_information"); - if (it != options_list.num_options.end() && it->second == "1") - mod_file_struct.partial_information = true; - - // Option k_order_solver (implicit when order >= 3) - it = options_list.num_options.find("k_order_solver"); - if ((it != options_list.num_options.end() && it->second == "1") - || mod_file_struct.order_option >= 3) - mod_file_struct.k_order_solver = true; - - it = options_list.num_options.find("hp_filter"); - OptionsList::num_options_t::const_iterator it1 = options_list.num_options.find("bandpass.indicator"); - OptionsList::num_options_t::const_iterator it2 = options_list.num_options.find("one_sided_hp_filter"); - if ((it != options_list.num_options.end() && it1 != options_list.num_options.end()) - || (it != options_list.num_options.end() && it2 != options_list.num_options.end()) - || (it1 != options_list.num_options.end() && it2 != options_list.num_options.end())) - { - cerr << "ERROR: stoch_simul: can only use one of hp, one-sided hp, and bandpass filters" - << endl; - exit(EXIT_FAILURE); - } -} - -void -StochSimulStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - // Ensure that order 3 implies k_order (#844) - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("order"); - OptionsList::num_options_t::const_iterator it1 = options_list.num_options.find("k_order_solver"); - if ((it1 != options_list.num_options.end() && it1->second == "1") - || (it != options_list.num_options.end() && atoi(it->second.c_str()) >= 3)) - output << "options_.k_order_solver = 1;" << endl; - - options_list.writeOutput(output); - symbol_list.writeOutput("var_list_", output); - output << "info = stoch_simul(var_list_);" << endl; -} - -void -StochSimulStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"stoch_simul\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -ForecastStatement::ForecastStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg) : - symbol_list(symbol_list_arg), - options_list(options_list_arg) -{ -} - -void -ForecastStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - symbol_list.writeOutput("var_list_", output); - output << "[oo_.forecast,info] = dyn_forecast(var_list_,M_,options_,oo_,'simul');" << endl; -} - -void -ForecastStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"forecast\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -RamseyModelStatement::RamseyModelStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -RamseyModelStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.ramsey_model_present = true; - - /* Fill in option_order of mod_file_struct - Since ramsey model needs one further order of derivation (for example, for 1st order - approximation, it needs 2nd derivatives), we add 1 to the order declared by user */ - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("order"); - if (it != options_list.num_options.end()) - { - int order = atoi(it->second.c_str()); - if (order > 2) - { - cerr << "ERROR: ramsey_model: order > 2 is not implemented" << endl; - exit(EXIT_FAILURE); - } - mod_file_struct.order_option = max(mod_file_struct.order_option, order + 1); - } - - // Fill in mod_file_struct.partial_information - it = options_list.num_options.find("partial_information"); - if (it != options_list.num_options.end() && it->second == "1") - mod_file_struct.partial_information = true; - - // Option k_order_solver (implicit when order >= 3) - it = options_list.num_options.find("k_order_solver"); - if ((it != options_list.num_options.end() && it->second == "1") - || mod_file_struct.order_option >= 3) - mod_file_struct.k_order_solver = true; -} - -void -RamseyModelStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - // options_.ramsey_policy indicates that a Ramsey model is present in the *.mod file - // this affects the computation of the steady state that uses a special algorithm - // It should probably rather be a M_ field, but we leave it in options_ for historical reason - - // Ensure that order 3 implies k_order (#844) - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("order"); - OptionsList::num_options_t::const_iterator it1 = options_list.num_options.find("k_order_solver"); - if ((it1 != options_list.num_options.end() && it1->second == "1") - || (it != options_list.num_options.end() && atoi(it->second.c_str()) >= 3)) - output << "options_.k_order_solver = 1;" << endl; - - output << "options_.ramsey_policy = 1;" << endl; - options_list.writeOutput(output); -} - -void -RamseyModelStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"ramsey_model\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -RamseyConstraintsStatement::RamseyConstraintsStatement(const SymbolTable &symbol_table_arg, const constraints_t &constraints_arg) : - symbol_table(symbol_table_arg), - constraints(constraints_arg) -{ -} - -void -RamseyConstraintsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - if ((mod_file_struct.ramsey_model_present != true) || (mod_file_struct.ramsey_policy_present != true)) - cerr << "ramsey_constraints: can only be used with ramsey_model or ramsey_policy" << endl; -} - -void -RamseyConstraintsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "M_.ramsey_model_constraints = {" << endl; - for (RamseyConstraintsStatement::constraints_t::const_iterator it = constraints.begin(); it != constraints.end(); ++it) - { - if (it != constraints.begin()) - output << ", "; - output << "{" << it->endo + 1 << ", '"; - switch (it->code) - { - case oLess: - output << '<'; - break; - case oGreater: - output << '>'; - break; - case oLessEqual: - output << "<="; - break; - case oGreaterEqual: - output << ">="; - break; - default: - cerr << "Ramsey constraints: this shouldn't happen." << endl; - exit(EXIT_FAILURE); - } - output << "', '"; - it->expression->writeOutput(output); - output << "'}" << endl; - } - output << "};" << endl; -} - -void -RamseyConstraintsStatement::writeJsonOutput(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - output << "{\"statementName\": \"ramsey_constraints\"" - << ", \"ramsey_model_constraints\": [" << endl; - for (RamseyConstraintsStatement::constraints_t::const_iterator it = constraints.begin(); it != constraints.end(); ++it) - { - if (it != constraints.begin()) - output << ", "; - output << "{\"constraint\": \"" << symbol_table.getName(it->endo) << " "; - switch (it->code) - { - case oLess: - output << '<'; - break; - case oGreater: - output << '>'; - break; - case oLessEqual: - output << "<="; - break; - case oGreaterEqual: - output << ">="; - break; - default: - cerr << "Ramsey constraints: this shouldn't happen." << endl; - exit(1); - } - output << " "; - it->expression->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"}" << endl; - } - output << "]" << endl; - output << "}"; -} - -RamseyPolicyStatement::RamseyPolicyStatement(const SymbolTable &symbol_table_arg, - const vector &ramsey_policy_list_arg, - const OptionsList &options_list_arg) : - symbol_table(symbol_table_arg), - ramsey_policy_list(ramsey_policy_list_arg), - options_list(options_list_arg) -{ -} - -void -RamseyPolicyStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - // ramsey_model_present indicates that the model is augmented with the FOC of the planner problem - mod_file_struct.ramsey_model_present = true; - // ramsey_policy_present indicates that ramsey_policy instruction for computation of first order approximation - // of a stochastic Ramsey problem if present in the *.mod file - mod_file_struct.ramsey_policy_present = true; - - /* Fill in option_order of mod_file_struct - Since ramsey policy needs one further order of derivation (for example, for 1st order - approximation, it needs 2nd derivatives), we add 1 to the order declared by user */ - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("order"); - if (it != options_list.num_options.end()) - { - int order = atoi(it->second.c_str()); - if (order > 2) - { - cerr << "ERROR: ramsey_policy: order > 2 is not implemented" << endl; - exit(EXIT_FAILURE); - } - mod_file_struct.order_option = max(mod_file_struct.order_option, order + 1); - } - - // Fill in mod_file_struct.partial_information - it = options_list.num_options.find("partial_information"); - if (it != options_list.num_options.end() && it->second == "1") - mod_file_struct.partial_information = true; - - // Option k_order_solver (implicit when order >= 3) - it = options_list.num_options.find("k_order_solver"); - if ((it != options_list.num_options.end() && it->second == "1") - || mod_file_struct.order_option >= 3) - mod_file_struct.k_order_solver = true; -} - -void -RamseyPolicyStatement::checkRamseyPolicyList() -{ - for (vector::const_iterator it = ramsey_policy_list.begin(); - it != ramsey_policy_list.end(); it++) - { - if (!symbol_table.exists(*it)) - { - cerr << "ERROR: ramsey_policy: " << *it << " was not declared." << endl; - exit(EXIT_FAILURE); - } - if (symbol_table.getType(*it) != eEndogenous) - { - cerr << "ERROR: ramsey_policy: " << *it << " is not endogenous." << endl; - exit(EXIT_FAILURE); - } - } -} - -void -RamseyPolicyStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - // Ensure that order 3 implies k_order (#844) - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("order"); - OptionsList::num_options_t::const_iterator it1 = options_list.num_options.find("k_order_solver"); - if ((it1 != options_list.num_options.end() && it1->second == "1") - || (it != options_list.num_options.end() && atoi(it->second.c_str()) >= 3)) - output << "options_.k_order_solver = 1;" << endl; - - options_list.writeOutput(output); - output << "var_list_ = {"; - for (vector::const_iterator it = ramsey_policy_list.begin(); - it != ramsey_policy_list.end(); ++it) - { - if (it != ramsey_policy_list.begin()) - output << ";"; - output << "'" << *it << "'"; - } - output << "};" << endl - << "ramsey_policy(var_list_);" << endl; -} - -void -RamseyPolicyStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"ramsey_policy\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << ", \"ramsey_policy_list\": ["; - for (vector::const_iterator it = ramsey_policy_list.begin(); - it != ramsey_policy_list.end(); ++it) - { - if (it != ramsey_policy_list.begin()) - output << ","; - output << "\"" << *it << "\""; - } - output << "]" - << "}"; -} - -DiscretionaryPolicyStatement::DiscretionaryPolicyStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg) : - symbol_list(symbol_list_arg), - options_list(options_list_arg) -{ -} - -void -DiscretionaryPolicyStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.discretionary_policy_present = true; - - if (options_list.symbol_list_options.find("instruments") == options_list.symbol_list_options.end()) - { - cerr << "ERROR: discretionary_policy: the instruments option is required." << endl; - exit(EXIT_FAILURE); - } - - /* Fill in option_order of mod_file_struct - Since discretionary policy needs one further order of derivation (for example, for 1st order - approximation, it needs 2nd derivatives), we add 1 to the order declared by user */ - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("order"); - if (it != options_list.num_options.end()) - { - int order = atoi(it->second.c_str()); - if (order > 1) - { - cerr << "ERROR: discretionary_policy: order > 1 is not yet implemented" << endl; - exit(EXIT_FAILURE); - } - mod_file_struct.order_option = max(mod_file_struct.order_option, order + 1); - } - - // Fill in mod_file_struct.partial_information - it = options_list.num_options.find("partial_information"); - if (it != options_list.num_options.end() && it->second == "1") - mod_file_struct.partial_information = true; - - // Option k_order_solver (implicit when order >= 3) - it = options_list.num_options.find("k_order_solver"); - if ((it != options_list.num_options.end() && it->second == "1") - || mod_file_struct.order_option >= 3) - mod_file_struct.k_order_solver = true; -} - -void -DiscretionaryPolicyStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - // Ensure that order 3 implies k_order (#844) - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("order"); - OptionsList::num_options_t::const_iterator it1 = options_list.num_options.find("k_order_solver"); - if ((it1 != options_list.num_options.end() && it1->second == "1") - || (it != options_list.num_options.end() && atoi(it->second.c_str()) >= 3)) - output << "options_.k_order_solver = 1;" << endl; - - options_list.writeOutput(output); - symbol_list.writeOutput("var_list_", output); - output << "discretionary_policy(var_list_);" << endl; -} - -void -DiscretionaryPolicyStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"discretionary_policy\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -EstimationStatement::EstimationStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg) : - symbol_list(symbol_list_arg), - options_list(options_list_arg) -{ -} - -void -EstimationStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.estimation_present = true; - - // Fill in option_order of mod_file_struct - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("order"); - if (it != options_list.num_options.end()) - { - int order = atoi(it->second.c_str()); - - if (order > 2) - { - cerr << "ERROR: order > 2 is not supported in estimation" << endl; - exit(EXIT_FAILURE); - } - - mod_file_struct.order_option = max(mod_file_struct.order_option, order); - } - - // Fill in mod_file_struct.partial_information - it = options_list.num_options.find("partial_information"); - if (it != options_list.num_options.end() && it->second == "1") - mod_file_struct.partial_information = true; - - // Fill in mod_file_struct.estimation_analytic_derivation - it = options_list.num_options.find("analytic_derivation"); - if (it != options_list.num_options.end() && it->second == "1") - mod_file_struct.estimation_analytic_derivation = true; - - it = options_list.num_options.find("dsge_var"); - if (it != options_list.num_options.end()) - // Fill in mod_file_struct.dsge_var_calibrated - mod_file_struct.dsge_var_calibrated = it->second; - - // Fill in mod_file_struct.dsge_var_estimated - OptionsList::string_options_t::const_iterator it_str = options_list.string_options.find("dsge_var"); - if (it_str != options_list.string_options.end()) - mod_file_struct.dsge_var_estimated = true; - - // Fill in mod_file_struct.bayesian_irf_present - it = options_list.num_options.find("bayesian_irf"); - if (it != options_list.num_options.end() && it->second == "1") - mod_file_struct.bayesian_irf_present = true; - - it = options_list.num_options.find("dsge_varlag"); - if (it != options_list.num_options.end()) - if (mod_file_struct.dsge_var_calibrated.empty() - && !mod_file_struct.dsge_var_estimated) - { - cerr << "ERROR: The estimation statement requires a dsge_var option to be passed " - << "if the dsge_varlag option is passed." << endl; - exit(EXIT_FAILURE); - } - - if (!mod_file_struct.dsge_var_calibrated.empty() - && mod_file_struct.dsge_var_estimated) - { - cerr << "ERROR: An estimation statement cannot take more than one dsge_var option." << endl; - exit(EXIT_FAILURE); - } - - if (options_list.string_options.find("datafile") == options_list.string_options.end() - && !mod_file_struct.estimation_data_statement_present) - { - cerr << "ERROR: The estimation statement requires a data file to be supplied via the datafile option." << endl; - exit(EXIT_FAILURE); - } - - if (options_list.string_options.find("mode_file") != options_list.string_options.end() - && mod_file_struct.estim_params_use_calib) - { - cerr << "ERROR: The mode_file option of the estimation statement is incompatible with the use_calibration option of the estimated_params_init block." << endl; - exit(EXIT_FAILURE); - } -} - -void -EstimationStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - - // Special treatment for order option and particle filter - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("order"); - if (it == options_list.num_options.end()) - output << "options_.order = 1;" << endl; - else if (atoi(it->second.c_str()) == 2) - output << "options_.particle.status = 1;" << endl; - - // Do not check for the steady state in diffuse filter mode (#400) - it = options_list.num_options.find("diffuse_filter"); - if (it != options_list.num_options.end() && it->second == "1") - output << "options_.steadystate.nocheck = 1;" << endl; - - symbol_list.writeOutput("var_list_", output); - output << "oo_recursive_=dynare_estimation(var_list_);" << endl; -} - -void -EstimationStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"estimation\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -DynareSensitivityStatement::DynareSensitivityStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -DynareSensitivityStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("identification"); - if (it != options_list.num_options.end() - && it->second == "1") - mod_file_struct.identification_present = true; -} - -void -DynareSensitivityStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output, "options_gsa"); - - /* Ensure that nograph, nodisplay and graph_format are also set in top-level - options_. - \todo factorize this code between identification and dynare_sensitivity, - and provide a generic mechanism for this situation (maybe using regexps) */ - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("nodisplay"); - if (it != options_list.num_options.end()) - output << "options_.nodisplay = " << it->second << ";" << endl; - it = options_list.num_options.find("nograph"); - if (it != options_list.num_options.end()) - output << "options_.nograph = " << it->second << ";" << endl; - OptionsList::string_options_t::const_iterator it2 = options_list.string_options.find("graph_format"); - if (it2 != options_list.string_options.end()) - output << "options_.graph_format = '" << it2->second << "';" << endl; - - output << "dynare_sensitivity(options_gsa);" << endl; -} - -void -DynareSensitivityStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"dynare_sensitivity\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -RplotStatement::RplotStatement(const SymbolList &symbol_list_arg) : - symbol_list(symbol_list_arg) -{ -} - -void -RplotStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - symbol_list.writeOutput("var_list_", output); - output << "rplot(var_list_);" << endl; -} - -void -RplotStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"rplot\""; - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -UnitRootVarsStatement::UnitRootVarsStatement(void) -{ -} - -void -UnitRootVarsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "options_.diffuse_filter = 1;" << endl - << "options_.steadystate.nocheck = 1;" << endl; -} - -void -UnitRootVarsStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"unit_root_vars\", " - << "\"diffuse_filter\": 1, " - << "\"steady_state.nocheck\": 1}"; -} - -PeriodsStatement::PeriodsStatement(int periods_arg) : periods(periods_arg) -{ -} - -void -PeriodsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "options_.periods = " << periods << ";" << endl; -} - -void -PeriodsStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"periods\", " - << "\"periods\": " << periods << "}"; -} - -DsampleStatement::DsampleStatement(int val1_arg) : val1(val1_arg), val2(-1) -{ -} - -DsampleStatement::DsampleStatement(int val1_arg, int val2_arg) : val1(val1_arg), val2(val2_arg) -{ -} - -void -DsampleStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - if (val2 < 0) - output << "dsample(" << val1 << ");" << endl; - else - output << "dsample(" << val1 << ", " << val2 << ");" << endl; -} - -void -DsampleStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"dsample\", " - << "\"value1\": " << val1 << ", " - << "\"value2\": " << val2 << "}"; -} - -EstimatedParamsStatement::EstimatedParamsStatement(const vector &estim_params_list_arg, - const SymbolTable &symbol_table_arg) : - estim_params_list(estim_params_list_arg), - symbol_table(symbol_table_arg) -{ -} - -void -EstimatedParamsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - for (vector::const_iterator it = estim_params_list.begin(); - it != estim_params_list.end(); it++) - { - if (it->name == "dsge_prior_weight") - mod_file_struct.dsge_prior_weight_in_estimated_params = true; - - // Handle case of degenerate beta prior - if (it->prior == eBeta) - try - { - if (it->mean->eval(eval_context_t()) == 0.5 - && it->std->eval(eval_context_t()) == 0.5) - { - cerr << "ERROR: The prior density is not defined for the beta distribution when the mean = standard deviation = 0.5." << endl; - exit(EXIT_FAILURE); - } - } - catch (ExprNode::EvalException &e) - { - // We don't have enough information to compute the numerical value, skip the test - } - } - - // Check that no parameter/endogenous is declared twice in the block - set already_declared; - set > already_declared_corr; - for (vector::const_iterator it = estim_params_list.begin(); - it != estim_params_list.end(); it++) - { - if (it->type == 3) // Correlation - { - // Use lexical ordering for the pair of symbols - pair x = it->name < it->name2 ? make_pair(it->name, it->name2) : make_pair(it->name2, it->name); - - if (already_declared_corr.find(x) == already_declared_corr.end()) - already_declared_corr.insert(x); - else - { - cerr << "ERROR: in `estimated_params' block, the correlation between " << it->name << " and " << it->name2 << " is declared twice." << endl; - exit(EXIT_FAILURE); - } - } - else - { - if (already_declared.find(it->name) == already_declared.end()) - already_declared.insert(it->name); - else - { - cerr << "ERROR: in `estimated_params' block, the symbol " << it->name << " is declared twice." << endl; - exit(EXIT_FAILURE); - } - } - } - - // Fill in mod_file_struct.estimated_parameters (related to #469) - for (vector::const_iterator it = estim_params_list.begin(); - it != estim_params_list.end(); it++) - if (it->type == 2 && it->name != "dsge_prior_weight") - mod_file_struct.estimated_parameters.insert(symbol_table.getID(it->name)); -} - -void -EstimatedParamsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "estim_params_.var_exo = [];" << endl - << "estim_params_.var_endo = [];" << endl - << "estim_params_.corrx = [];" << endl - << "estim_params_.corrn = [];" << endl - << "estim_params_.param_vals = [];" << endl; - - for (vector::const_iterator it = estim_params_list.begin(); it != estim_params_list.end(); it++) - { - int symb_id = symbol_table.getTypeSpecificID(it->name) + 1; - SymbolType symb_type = symbol_table.getType(it->name); - - switch (it->type) - { - case 1: - if (symb_type == eExogenous) - output << "estim_params_.var_exo = [estim_params_.var_exo; "; - else if (symb_type == eEndogenous) - output << "estim_params_.var_endo = [estim_params_.var_endo; "; - output << symb_id; - break; - case 2: - output << "estim_params_.param_vals = [estim_params_.param_vals; " - << symb_id; - break; - case 3: - if (symb_type == eExogenous) - output << "estim_params_.corrx = [estim_params_.corrx; "; - else if (symb_type == eEndogenous) - output << "estim_params_.corrn = [estim_params_.corrn; "; - output << symb_id << " " << symbol_table.getTypeSpecificID(it->name2)+1; - break; - } - output << ", "; - it->init_val->writeOutput(output); - output << ", "; - it->low_bound->writeOutput(output); - output << ", "; - it->up_bound->writeOutput(output); - output << ", " - << it->prior << ", "; - it->mean->writeOutput(output); - output << ", "; - it->std->writeOutput(output); - output << ", "; - it->p3->writeOutput(output); - output << ", "; - it->p4->writeOutput(output); - output << ", "; - it->jscale->writeOutput(output); - output << " ];" << endl; - } -} - -void -EstimatedParamsStatement::writeJsonOutput(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - output << "{\"statementName\": \"estimated_params\", " - << "\"params\": ["; - for (vector::const_iterator it = estim_params_list.begin(); it != estim_params_list.end(); it++) - { - if (it != estim_params_list.begin()) - output << ", "; - output << "{"; - switch (it->type) - { - case 1: - output << "\"var\": \"" << it->name << "\""; - break; - case 2: - output << "\"param\": \"" << it->name << "\""; - break; - case 3: - output << "\"var1\": \"" << it->name << "\"," - << "\"var2\": \"" << it->name2 << "\""; - break; - } - - output << ", \"init_val\": \""; - it->init_val->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\", \"lower_bound\": \""; - it->low_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\", \"upper_bound\": \""; - it->up_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\", \"prior_distribution\": " - << it->prior - << ", \"mean\": \""; - it->mean->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\", \"std\": \""; - it->std->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\", \"p3\": \""; - it->p3->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\", \"p4\": \""; - it->p4->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\", \"jscale\": \""; - it->jscale->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"}" << endl; - } - output << "]" - << "}"; -} - -EstimatedParamsInitStatement::EstimatedParamsInitStatement(const vector &estim_params_list_arg, - const SymbolTable &symbol_table_arg, - const bool use_calibration_arg) : - estim_params_list(estim_params_list_arg), - symbol_table(symbol_table_arg), - use_calibration(use_calibration_arg) -{ -} - -void -EstimatedParamsInitStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - if (use_calibration) - mod_file_struct.estim_params_use_calib = true; -} - -void -EstimatedParamsInitStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - if (use_calibration) - output << "options_.use_calibration_initialization = 1;" << endl; - - for (vector::const_iterator it = estim_params_list.begin(); it != estim_params_list.end(); it++) - { - int symb_id = symbol_table.getTypeSpecificID(it->name) + 1; - SymbolType symb_type = symbol_table.getType(it->name); - - if (it->type < 3) - { - if (symb_type == eExogenous) - { - output << "tmp1 = find(estim_params_.var_exo(:,1)==" << symb_id << ");" << endl; - output << "estim_params_.var_exo(tmp1,2) = "; - it->init_val->writeOutput(output); - output << ";" << endl; - } - else if (symb_type == eEndogenous) - { - output << "tmp1 = find(estim_params_.var_endo(:,1)==" << symb_id << ");" << endl; - output << "estim_params_.var_endo(tmp1,2) = "; - it->init_val->writeOutput(output); - output << ";" << endl; - } - else if (symb_type == eParameter) - { - output << "tmp1 = find(estim_params_.param_vals(:,1)==" << symb_id << ");" << endl; - output << "estim_params_.param_vals(tmp1,2) = "; - it->init_val->writeOutput(output); - output << ";" << endl; - } - } - else - { - if (symb_type == eExogenous) - { - output << "tmp1 = find((estim_params_.corrx(:,1)==" << symb_id << " & estim_params_.corrx(:,2)==" << symbol_table.getTypeSpecificID(it->name2)+1 << ") | " - << "(estim_params_.corrx(:,2)==" << symb_id << " & estim_params_.corrx(:,1)==" << symbol_table.getTypeSpecificID(it->name2)+1 << "));" << endl; - output << "estim_params_.corrx(tmp1,3) = "; - it->init_val->writeOutput(output); - output << ";" << endl; - } - else if (symb_type == eEndogenous) - { - output << "tmp1 = find((estim_params_.corrn(:,1)==" << symb_id << " & estim_params_.corrn(:,2)==" << symbol_table.getTypeSpecificID(it->name2)+1 << ") | " - << "(estim_params_.corrn(:,2)==" << symb_id << " & estim_params_.corrn(:,1)==" << symbol_table.getTypeSpecificID(it->name2)+1 << "));" << endl; - output << "estim_params_.corrn(tmp1,3) = "; - it->init_val->writeOutput(output); - output << ";" << endl; - } - } - } -} - -void -EstimatedParamsInitStatement::writeJsonOutput(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - output << "{\"statementName\": \"estimated_params_init\""; - - if (use_calibration) - output << ", \"use_calibration_initialization\": 1"; - - output << ", \"params\": ["; - for (vector::const_iterator it = estim_params_list.begin(); it != estim_params_list.end(); it++) - { - if (it != estim_params_list.begin()) - output << ", "; - output << "{"; - switch (it->type) - { - case 1: - output << "\"var\": \"" << it->name << "\""; - break; - case 2: - output << "\"param\": \"" << it->name << "\""; - break; - case 3: - output << "\"var1\": \"" << it->name << "\"," - << "\"var2\": \"" << it->name2 << "\""; - break; - } - output << ", \"init_val\": \""; - it->init_val->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"}"; - } - output << "]" - << "}"; -} - -EstimatedParamsBoundsStatement::EstimatedParamsBoundsStatement(const vector &estim_params_list_arg, - const SymbolTable &symbol_table_arg) : - estim_params_list(estim_params_list_arg), - symbol_table(symbol_table_arg) -{ -} - -void -EstimatedParamsBoundsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - for (vector::const_iterator it = estim_params_list.begin(); it != estim_params_list.end(); it++) - { - int symb_id = symbol_table.getTypeSpecificID(it->name) + 1; - SymbolType symb_type = symbol_table.getType(it->name); - - if (it->type < 3) - { - if (symb_type == eExogenous) - { - output << "tmp1 = find(estim_params_.var_exo(:,1)==" << symb_id << ");" << endl; - - output << "estim_params_.var_exo(tmp1,3) = "; - it->low_bound->writeOutput(output); - output << ";" << endl; - - output << "estim_params_.var_exo(tmp1,4) = "; - it->up_bound->writeOutput(output); - output << ";" << endl; - } - else if (symb_type == eEndogenous) - { - output << "tmp1 = find(estim_params_.var_endo(:,1)==" << symb_id << ");" << endl; - - output << "estim_params_.var_endo(tmp1,3) = "; - it->low_bound->writeOutput(output); - output << ";" << endl; - - output << "estim_params_.var_endo(tmp1,4) = "; - it->up_bound->writeOutput(output); - output << ";" << endl; - } - else if (symb_type == eParameter) - { - output << "tmp1 = find(estim_params_.param_vals(:,1)==" << symb_id << ");" << endl; - - output << "estim_params_.param_vals(tmp1,3) = "; - it->low_bound->writeOutput(output); - output << ";" << endl; - - output << "estim_params_.param_vals(tmp1,4) = "; - it->up_bound->writeOutput(output); - output << ";" << endl; - } - } - else - { - if (symb_type == eExogenous) - { - output << "tmp1 = find((estim_params_.corrx(:,1)==" << symb_id << " & estim_params_.corrx(:,2)==" << symbol_table.getTypeSpecificID(it->name2)+1 << ") | " - << "(estim_params_.corrx(:,2)==" << symb_id << " & estim_params_.corrx(:,1)==" << symbol_table.getTypeSpecificID(it->name2)+1 << "));" << endl; - - output << "estim_params_.corrx(tmp1,4) = "; - it->low_bound->writeOutput(output); - output << ";" << endl; - - output << "estim_params_.corrx(tmp1,5) = "; - it->up_bound->writeOutput(output); - output << ";" << endl; - } - else if (symb_type == eEndogenous) - { - output << "tmp1 = find((estim_params_.corrn(:,1)==" << symb_id << " & estim_params_.corrn(:,2)==" << symbol_table.getTypeSpecificID(it->name2)+1 << ") | " - << "(estim_params_.corrn(:,2)==" << symb_id << " & estim_params_.corrn(:,1)==" << symbol_table.getTypeSpecificID(it->name2)+1 << "));" << endl; - - output << "estim_params_.corrn(tmp1,4) = "; - it->low_bound->writeOutput(output); - output << ";" << endl; - - output << "estim_params_.corrn(tmp1,5) = "; - it->up_bound->writeOutput(output); - output << ";" << endl; - } - } - } -} - -void -EstimatedParamsBoundsStatement::writeJsonOutput(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - output << "{\"statementName\": \"estimated_params_bounds\", " - << "\"params\": ["; - - for (vector::const_iterator it = estim_params_list.begin(); it != estim_params_list.end(); it++) - { - if (it != estim_params_list.begin()) - output << ", "; - output << "{"; - switch (it->type) - { - case 1: - output << "\"var\": \"" << it->name << "\""; - case 2: - output << "\"param\": \"" << it->name << "\""; - break; - case 3: - output << "\"var1\": \"" << it->name << "\"," - << "\"var2\": \"" << it->name2 << "\""; - break; - } - output << ", \"lower_bound\": "; - it->low_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << ", \"upper_bound\": "; - it->up_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "}"; - } - output << "]" - << "}"; -} - -ObservationTrendsStatement::ObservationTrendsStatement(const trend_elements_t &trend_elements_arg, - const SymbolTable &symbol_table_arg) : - trend_elements(trend_elements_arg), - symbol_table(symbol_table_arg) -{ -} - -void -ObservationTrendsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "options_.trend_coeff = {};" << endl; - for (trend_elements_t::const_iterator it = trend_elements.begin(); it != trend_elements.end(); it++) - { - SymbolType type = symbol_table.getType(it->first); - if (type == eEndogenous) - { - output << "tmp1 = strmatch('" << it->first << "',options_.varobs,'exact');" << endl; - output << "options_.trend_coeffs{tmp1} = '"; - it->second->writeOutput(output); - output << "';" << endl; - } - else - cerr << "Warning : Non-variable symbol used in observation_trends: " << it->first << endl; - } -} - -void -ObservationTrendsStatement::writeJsonOutput(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - output << "{\"statementName\": \"observation_trends\", " - << "\"trends\" : {"; - bool printed = false; - for (trend_elements_t::const_iterator it = trend_elements.begin(); - it != trend_elements.end(); it++) - { - if (symbol_table.getType(it->first) == eEndogenous) - { - if (printed) - output << ", "; - output << "\"" << it->first << "\": \""; - it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"" << endl; - printed = true; - } - else - cerr << "Warning : Non-variable symbol used in observation_trends: " << it->first << endl; - } - output << "}" - << "}"; -} - -OsrParamsStatement::OsrParamsStatement(const SymbolList &symbol_list_arg, const SymbolTable &symbol_table_arg) : - symbol_list(symbol_list_arg), - symbol_table(symbol_table_arg) -{ -} - -void -OsrParamsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - if (mod_file_struct.osr_params_present) - cerr << "WARNING: You have more than one osr_params statement in the .mod file." << endl; - mod_file_struct.osr_params_present = true; -} - -void -OsrParamsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - symbol_list.writeOutput("M_.osr.param_names", output); - output << "M_.osr.param_names = cellstr(M_.osr.param_names);" << endl - << "M_.osr.param_indices = zeros(length(M_.osr.param_names), 1);" << endl; - int i = 0; - vector symbols = symbol_list.get_symbols(); - for (vector::const_iterator it = symbols.begin(); it != symbols.end(); it++) - output << "M_.osr.param_indices(" << ++i <<") = " << symbol_table.getTypeSpecificID(*it) + 1 << ";" << endl; -} - -void -OsrParamsStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"osr_params\""; - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -OsrStatement::OsrStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg) : - symbol_list(symbol_list_arg), - options_list(options_list_arg) -{ -} - -OsrParamsBoundsStatement::OsrParamsBoundsStatement(const vector &osr_params_list_arg) : - osr_params_list(osr_params_list_arg) -{ -} - -void -OsrParamsBoundsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - if (!mod_file_struct.osr_params_present) - { - cerr << "ERROR: you must have an osr_params statement before the osr_params_bounds block." << endl; - exit(EXIT_FAILURE); - } -} - -void -OsrParamsBoundsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - - output << "M_.osr.param_bounds = [-inf(length(M_.osr.param_names), 1), inf(length(M_.osr.param_names), 1)];" << endl; - - for (vector::const_iterator it = osr_params_list.begin(); - it != osr_params_list.end(); it++) - { - output << "M_.osr.param_bounds(strcmp(M_.osr.param_names, '" << it->name << "'), :) = ["; - it->low_bound->writeOutput(output); - output << ", "; - it->up_bound->writeOutput(output); - output << "];" << endl; - } -} - -void -OsrParamsBoundsStatement::writeJsonOutput(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - output << "{\"statementName\": \"osr_params_bounds\"" - << ", \"bounds\": ["; - for (vector::const_iterator it = osr_params_list.begin(); - it != osr_params_list.end(); it++) - { - if (it != osr_params_list.begin()) - output << ", "; - output << "{\"parameter\": \"" << it->name << "\"," - << "\"bounds\": [\""; - it->low_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\", \""; - it->up_bound->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"]" - << "}"; - } - output << "]" - << "}"; -} - -void -OsrStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.osr_present = true; - - // Fill in option_order of mod_file_struct - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("order"); - if (it != options_list.num_options.end()) - mod_file_struct.order_option = max(mod_file_struct.order_option, atoi(it->second.c_str())); - - // Fill in mod_file_struct.partial_information - it = options_list.num_options.find("partial_information"); - if (it != options_list.num_options.end() && it->second == "1") - mod_file_struct.partial_information = true; - - // Option k_order_solver (implicit when order >= 3) - it = options_list.num_options.find("k_order_solver"); - if ((it != options_list.num_options.end() && it->second == "1") - || mod_file_struct.order_option >= 3) - mod_file_struct.k_order_solver = true; -} - -void -OsrStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - // Ensure that order 3 implies k_order (#844) - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("order"); - OptionsList::num_options_t::const_iterator it1 = options_list.num_options.find("k_order_solver"); - if ((it1 != options_list.num_options.end() && it1->second == "1") - || (it != options_list.num_options.end() && atoi(it->second.c_str()) >= 3)) - output << "options_.k_order_solver = 1;" << endl; - - options_list.writeOutput(output); - symbol_list.writeOutput("var_list_", output); - output << "oo_.osr = osr(var_list_,M_.osr.param_names,M_.osr.variable_indices,M_.osr.variable_weights);" << endl; -} - -void -OsrStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"osr\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -OptimWeightsStatement::OptimWeightsStatement(const var_weights_t &var_weights_arg, - const covar_weights_t &covar_weights_arg, - const SymbolTable &symbol_table_arg) : - var_weights(var_weights_arg), - covar_weights(covar_weights_arg), - symbol_table(symbol_table_arg) -{ -} - -void -OptimWeightsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.optim_weights_present = true; -} - -void -OptimWeightsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "%" << endl - << "% OPTIM_WEIGHTS" << endl - << "%" << endl - << "M_.osr.variable_weights = sparse(M_.endo_nbr,M_.endo_nbr);" << endl - << "M_.osr.variable_indices = [];" << endl << endl; - - for (var_weights_t::const_iterator it = var_weights.begin(); - it != var_weights.end(); it++) - { - const string &name = it->first; - const expr_t value = it->second; - int id = symbol_table.getTypeSpecificID(name) + 1; - output << "M_.osr.variable_weights(" << id << "," << id << ") = "; - value->writeOutput(output); - output << ";" << endl; - output << "M_.osr.variable_indices = [M_.osr.variable_indices; " << id << "];" << endl; - } - - for (covar_weights_t::const_iterator it = covar_weights.begin(); - it != covar_weights.end(); it++) - { - const string &name1 = it->first.first; - const string &name2 = it->first.second; - const expr_t value = it->second; - int id1 = symbol_table.getTypeSpecificID(name1) + 1; - int id2 = symbol_table.getTypeSpecificID(name2) + 1; - output << "M_.osr.variable_weights(" << id1 << "," << id2 << ") = "; - value->writeOutput(output); - output << ";" << endl; - output << "M_.osr.variable_indices = [M_.osr.variable_indices; " << id1 << "; " << id2 << "];" << endl; - } -} - -void -OptimWeightsStatement::writeJsonOutput(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - output << "{\"statementName\": \"optim_weights\", " - << "\"weights\": ["; - for (var_weights_t::const_iterator it = var_weights.begin(); - it != var_weights.end(); it++) - { - if (it != var_weights.begin()) - output << ", "; - output << "{\"name\": \"" << it->first << "\"" - << ", \"value\": \""; - it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"}"; - } - - for (covar_weights_t::const_iterator it = covar_weights.begin(); - it != covar_weights.end(); it++) - { - if (it != covar_weights.begin() || !var_weights.empty()) - output << ", "; - output << "{\"name1\": \"" << it->first.first << "\"" - << ", \"name2\": \"" << it->first.second << "\"" - << ", \"value\": \""; - it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"}"; - } - output << "]" - << "}"; -} - -DynaSaveStatement::DynaSaveStatement(const SymbolList &symbol_list_arg, - const string &filename_arg) : - symbol_list(symbol_list_arg), - filename(filename_arg) -{ -} - -void -DynaSaveStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - symbol_list.writeOutput("var_list_", output); - output << "dynasave('" << filename - << "',var_list_);" << endl; -} - -void -DynaSaveStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"dynasave\", " - << "\"filename\": \"" << filename << "\""; - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -DynaTypeStatement::DynaTypeStatement(const SymbolList &symbol_list_arg, - const string &filename_arg) : - symbol_list(symbol_list_arg), - filename(filename_arg) -{ -} - -void -DynaTypeStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - symbol_list.writeOutput("var_list_", output); - output << "dynatype('" << filename - << "',var_list_);" << endl; -} - -void -DynaTypeStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"dynatype\", " - << "\"filename\": \"" << filename << "\""; - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -ModelComparisonStatement::ModelComparisonStatement(const filename_list_t &filename_list_arg, - const OptionsList &options_list_arg) : - filename_list(filename_list_arg), - options_list(options_list_arg) -{ -} - -void -ModelComparisonStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - - output << "ModelNames_ = {};" << endl; - output << "ModelPriors_ = [];" << endl; - - for (filename_list_t::const_iterator it = filename_list.begin(); - it != filename_list.end(); it++) - { - output << "ModelNames_ = { ModelNames_{:} '" << (*it).first << "'};" << endl; - output << "ModelPriors_ = [ ModelPriors_ ; " << (*it).second << "];" << endl; - } - output << "oo_ = model_comparison(ModelNames_,ModelPriors_,oo_,options_,M_.fname);" << endl; -} - -void -ModelComparisonStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"model_comparison\""; - if (!filename_list.empty()) - output << ", \"filename_list\": {"; - - for (filename_list_t::const_iterator it = filename_list.begin(); - it != filename_list.end(); it++) - { - if (it != filename_list.begin()) - output << ", "; - output << "\"name\": \"" << it->first << "\"" - << "\"prior\": \"" << it->second << "\""; - } - - if (!filename_list.empty()) - output << "}"; - - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - - output << "}"; -} - -PlannerObjectiveStatement::PlannerObjectiveStatement(StaticModel *model_tree_arg) : - model_tree(model_tree_arg), - computing_pass_called(false) -{ -} - -PlannerObjectiveStatement::~PlannerObjectiveStatement() -{ - delete model_tree; -} - -void -PlannerObjectiveStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - assert(model_tree->equation_number() == 1); - if (model_tree->exoPresentInEqs()) - { - cerr << "ERROR: You cannot include exogenous variables in the planner objective. Please " - << "define an auxiliary endogenous variable like eps_aux=epsilon and use it instead " - << "of the varexo." << endl; - exit(EXIT_FAILURE); - } - mod_file_struct.planner_objective_present = true; -} - -StaticModel * -PlannerObjectiveStatement::getPlannerObjective() const -{ - return model_tree; -} - -void -PlannerObjectiveStatement::computingPass() -{ - model_tree->computingPass(eval_context_t(), false, true, true, none, false, false, false); - computing_pass_called = true; -} - -void -PlannerObjectiveStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - model_tree->writeStaticFile(basename + "_objective", false, false, false, false); -} - -void -PlannerObjectiveStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"planner_objective\"" - << ", "; - if (computing_pass_called) - model_tree->writeJsonComputingPassOutput(output, false); - else - model_tree->writeJsonOutput(output); - - output << "}"; -} - -BVARDensityStatement::BVARDensityStatement(int maxnlags_arg, const OptionsList &options_list_arg) : - maxnlags(maxnlags_arg), - options_list(options_list_arg) -{ -} - -void -BVARDensityStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.bvar_present = true; -} - -void -BVARDensityStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - output << "bvar_density(" << maxnlags << ");" << endl; -} - -void -BVARDensityStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"bvar_density\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -BVARForecastStatement::BVARForecastStatement(int nlags_arg, const OptionsList &options_list_arg) : - nlags(nlags_arg), - options_list(options_list_arg) -{ -} - -void -BVARForecastStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.bvar_present = true; -} - -void -BVARForecastStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - output << "bvar_forecast(" << nlags << ");" << endl; -} - -void -BVARForecastStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"bvar_forecast\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -SBVARStatement::SBVARStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -SBVARStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.bvar_present = true; -} - -void -SBVARStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - output << "sbvar(M_,options_);" << endl; -} - -void -SBVARStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"sbvar\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -MSSBVAREstimationStatement::MSSBVAREstimationStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -MSSBVAREstimationStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.bvar_present = true; - - if (options_list.num_options.find("ms.create_init") == options_list.num_options.end()) - if (options_list.string_options.find("datafile") == options_list.string_options.end() - || options_list.num_options.find("ms.initial_year") == options_list.num_options.end()) - { - cerr << "ERROR: If you do not pass no_create_init to ms_estimation, " - << "you must pass the datafile and initial_year options." << endl; - exit(EXIT_FAILURE); - } -} - -void -MSSBVAREstimationStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "options_ = initialize_ms_sbvar_options(M_, options_);" << endl - << "options_.datafile = '';" << endl; - options_list.writeOutput(output); - output << "[options_, oo_] = ms_estimation(M_, options_, oo_);" << endl; -} - -void -MSSBVAREstimationStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"ms_sbvar_estimation\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -MSSBVARSimulationStatement::MSSBVARSimulationStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -MSSBVARSimulationStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.bvar_present = true; -} - -void -MSSBVARSimulationStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "options_ = initialize_ms_sbvar_options(M_, options_);" << endl; - options_list.writeOutput(output); - - // Redeclare drop option if necessary - OptionsList::num_options_t::const_iterator mh_replic_it = options_list.num_options.find("ms.mh_replic"); - OptionsList::num_options_t::const_iterator thinning_factor_it = options_list.num_options.find("ms.thinning_factor"); - OptionsList::num_options_t::const_iterator drop_it = options_list.num_options.find("ms.drop"); - if (mh_replic_it != options_list.num_options.end() || thinning_factor_it != options_list.num_options.end()) - if (drop_it == options_list.num_options.end()) - output << "options_.ms.drop = 0.1*options_.ms.mh_replic*options_.ms.thinning_factor;" << endl; - - output << "[options_, oo_] = ms_simulation(M_, options_, oo_);" << endl; -} - -void -MSSBVARSimulationStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"ms_sbvar_simulation\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -MSSBVARComputeMDDStatement::MSSBVARComputeMDDStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -MSSBVARComputeMDDStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.bvar_present = true; -} - -void -MSSBVARComputeMDDStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "options_ = initialize_ms_sbvar_options(M_, options_);" << endl; - options_list.writeOutput(output); - output << "[options_, oo_] = ms_compute_mdd(M_, options_, oo_);" << endl; -} - -void -MSSBVARComputeMDDStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"ms_sbvar_compute_mdd\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -MSSBVARComputeProbabilitiesStatement::MSSBVARComputeProbabilitiesStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -MSSBVARComputeProbabilitiesStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.bvar_present = true; - - if (options_list.num_options.find("ms.real_time_smoothed_probabilities") != options_list.num_options.end()) - if (options_list.num_options.find("ms.filtered_probabilities") != options_list.num_options.end()) - { - cerr << "ERROR: You may only pass one of real_time_smoothed " - << "and filtered_probabilities to ms_compute_probabilities." << endl; - exit(EXIT_FAILURE); - } -} - -void -MSSBVARComputeProbabilitiesStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "options_ = initialize_ms_sbvar_options(M_, options_);" << endl; - options_list.writeOutput(output); - output << "[options_, oo_] = ms_compute_probabilities(M_, options_, oo_);" << endl; -} - -void -MSSBVARComputeProbabilitiesStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"ms_sbvar_compute_probabilities\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -MSSBVARIrfStatement::MSSBVARIrfStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg) : - symbol_list(symbol_list_arg), - options_list(options_list_arg) -{ -} - -void -MSSBVARIrfStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.bvar_present = true; - - bool regime_present = false; - bool regimes_present = false; - bool filtered_probabilities_present = false; - - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("ms.regimes"); - if (it != options_list.num_options.end()) - regimes_present = true; - - it = options_list.num_options.find("ms.regime"); - if (it != options_list.num_options.end()) - regime_present = true; - - it = options_list.num_options.find("ms.filtered_probabilities"); - if (it != options_list.num_options.end()) - filtered_probabilities_present = true; - - if ((filtered_probabilities_present && regime_present) - || (filtered_probabilities_present && regimes_present) - || (regimes_present && regime_present)) - { - cerr << "ERROR: You may only pass one of regime, regimes and " - << "filtered_probabilities to ms_irf" << endl; - exit(EXIT_FAILURE); - } -} - -void -MSSBVARIrfStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "options_ = initialize_ms_sbvar_options(M_, options_);" << endl; - symbol_list.writeOutput("var_list_", output); - options_list.writeOutput(output); - output << "[options_, oo_] = ms_irf(var_list_,M_, options_, oo_);" << endl; -} - -void -MSSBVARIrfStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"ms_sbvar_irf\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -MSSBVARForecastStatement::MSSBVARForecastStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -MSSBVARForecastStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.bvar_present = true; - - if (options_list.num_options.find("ms.regimes") != options_list.num_options.end()) - if (options_list.num_options.find("ms.regime") != options_list.num_options.end()) - { - cerr << "ERROR: You may only pass one of regime and regimes to ms_forecast" << endl; - exit(EXIT_FAILURE); - } -} - -void -MSSBVARForecastStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "options_ = initialize_ms_sbvar_options(M_, options_);" << endl; - options_list.writeOutput(output); - output << "[options_, oo_] = ms_forecast(M_, options_, oo_);" << endl; -} - -void -MSSBVARForecastStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"ms_sbvar_forecast\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -MSSBVARVarianceDecompositionStatement::MSSBVARVarianceDecompositionStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -MSSBVARVarianceDecompositionStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.bvar_present = true; - - bool regime_present = false; - bool regimes_present = false; - bool filtered_probabilities_present = false; - - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("ms.regimes"); - if (it != options_list.num_options.end()) - regimes_present = true; - - it = options_list.num_options.find("ms.regime"); - if (it != options_list.num_options.end()) - regime_present = true; - - it = options_list.num_options.find("ms.filtered_probabilities"); - if (it != options_list.num_options.end()) - filtered_probabilities_present = true; - - if ((filtered_probabilities_present && regime_present) - || (filtered_probabilities_present && regimes_present) - || (regimes_present && regime_present)) - { - cerr << "ERROR: You may only pass one of regime, regimes and " - << "filtered_probabilities to ms_variance_decomposition" << endl; - exit(EXIT_FAILURE); - } -} - -void -MSSBVARVarianceDecompositionStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "options_ = initialize_ms_sbvar_options(M_, options_);" << endl; - options_list.writeOutput(output); - output << "[options_, oo_] = ms_variance_decomposition(M_, options_, oo_);" << endl; -} - -void -MSSBVARVarianceDecompositionStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"ms_sbvar_variance_decomposition\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -IdentificationStatement::IdentificationStatement(const OptionsList &options_list_arg) -{ - options_list = options_list_arg; - if (options_list.num_options.find("max_dim_cova_group") != options_list.num_options.end()) - if (atoi(options_list.num_options["max_dim_cova_group"].c_str()) == 0) - { - cerr << "ERROR: The max_dim_cova_group option to identification only accepts integers > 0." << endl; - exit(EXIT_FAILURE); - } -} - -void -IdentificationStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.identification_present = true; -} - -void -IdentificationStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output, "options_ident"); - - /* Ensure that nograph, nodisplay and graph_format are also set in top-level - options_. - \todo factorize this code between identification and dynare_sensitivity, - and provide a generic mechanism for this situation (maybe using regexps) */ - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("nodisplay"); - if (it != options_list.num_options.end()) - output << "options_.nodisplay = " << it->second << ";" << endl; - it = options_list.num_options.find("nograph"); - if (it != options_list.num_options.end()) - output << "options_.nograph = " << it->second << ";" << endl; - OptionsList::string_options_t::const_iterator it2 = options_list.string_options.find("graph_format"); - if (it2 != options_list.string_options.end()) - output << "options_.graph_format = '" << it2->second << "';" << endl; - - output << "dynare_identification(options_ident);" << endl; -} - -void -IdentificationStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"identification\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -WriteLatexDynamicModelStatement::WriteLatexDynamicModelStatement(const DynamicModel &dynamic_model_arg, bool write_equation_tags_arg) : - dynamic_model(dynamic_model_arg), - write_equation_tags(write_equation_tags_arg) -{ -} - -void -WriteLatexDynamicModelStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - dynamic_model.writeLatexFile(basename, write_equation_tags); -} - -void -WriteLatexDynamicModelStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"write_latex_dynamic_model\"}"; -} - -WriteLatexStaticModelStatement::WriteLatexStaticModelStatement(const StaticModel &static_model_arg, bool write_equation_tags_arg) : - static_model(static_model_arg), - write_equation_tags(write_equation_tags_arg) -{ -} - -void -WriteLatexStaticModelStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - static_model.writeLatexFile(basename, write_equation_tags); -} - -void -WriteLatexStaticModelStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"write_latex_static_model\"}"; -} - -WriteLatexOriginalModelStatement::WriteLatexOriginalModelStatement(const DynamicModel &original_model_arg, bool write_equation_tags_arg) : - original_model(original_model_arg), - write_equation_tags(write_equation_tags_arg) -{ -} - -void -WriteLatexOriginalModelStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - original_model.writeLatexOriginalFile(basename, write_equation_tags); -} - -void -WriteLatexOriginalModelStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"write_latex_original_model\"}"; -} - -WriteLatexSteadyStateModelStatement::WriteLatexSteadyStateModelStatement(const SteadyStateModel &steady_state_model_arg) : - steady_state_model(steady_state_model_arg) -{ -} - -void -WriteLatexSteadyStateModelStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.write_latex_steady_state_model_present = true; -} - -void -WriteLatexSteadyStateModelStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - steady_state_model.writeLatexSteadyStateFile(basename); -} - -void -WriteLatexSteadyStateModelStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"write_latex_steady_state_model\"}"; -} - -ShockDecompositionStatement::ShockDecompositionStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg) : - symbol_list(symbol_list_arg), - options_list(options_list_arg) -{ -} - -void -ShockDecompositionStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - symbol_list.writeOutput("var_list_", output); - output << "oo_ = shock_decomposition(M_,oo_,options_,var_list_,bayestopt_,estim_params_);" << endl; -} - -void -ShockDecompositionStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"shock_decomposition\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -RealtimeShockDecompositionStatement::RealtimeShockDecompositionStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg) : - symbol_list(symbol_list_arg), - options_list(options_list_arg) -{ -} - -void -RealtimeShockDecompositionStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - symbol_list.writeOutput("var_list_", output); - output << "oo_ = realtime_shock_decomposition(M_,oo_,options_,var_list_,bayestopt_,estim_params_);" << endl; -} - -PlotShockDecompositionStatement::PlotShockDecompositionStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg) : - symbol_list(symbol_list_arg), - options_list(options_list_arg) -{ -} - -void -PlotShockDecompositionStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "options_ = set_default_plot_shock_decomposition_options(options_);" << endl; - options_list.writeOutput(output); - symbol_list.writeOutput("var_list_", output); - output << "plot_shock_decomposition(M_, oo_, options_, var_list_);" << endl; -} - -InitialConditionDecompositionStatement::InitialConditionDecompositionStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg) : - symbol_list(symbol_list_arg), - options_list(options_list_arg) -{ -} - -void -InitialConditionDecompositionStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "options_ = set_default_initial_condition_decomposition_options(options_);" << endl; - options_list.writeOutput(output); - symbol_list.writeOutput("var_list_", output); - output << "oo_ = initial_condition_decomposition(M_, oo_, options_, var_list_, bayestopt_, estim_params_);" << endl; -} - -ConditionalForecastStatement::ConditionalForecastStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -ConditionalForecastStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output, "options_cond_fcst_"); - output << "imcforecast(constrained_paths_, constrained_vars_, options_cond_fcst_);" << endl; -} - -void -ConditionalForecastStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"conditional_forecast\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -PlotConditionalForecastStatement::PlotConditionalForecastStatement(int periods_arg, const SymbolList &symbol_list_arg) : - periods(periods_arg), - symbol_list(symbol_list_arg) -{ -} - -void -PlotConditionalForecastStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - symbol_list.writeOutput("var_list_", output); - if (periods == -1) - output << "plot_icforecast(var_list_,[],options_);" << endl; - else - output << "plot_icforecast(var_list_, " << periods << ",options_);" << endl; -} - -void -PlotConditionalForecastStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"plot_conditional_forecast\", " - << "\"periods\": " << periods; - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -SvarIdentificationStatement::SvarIdentificationStatement(const svar_identification_restrictions_t &restrictions_arg, - const bool &upper_cholesky_present_arg, - const bool &lower_cholesky_present_arg, - const bool &constants_exclusion_present_arg, - const SymbolTable &symbol_table_arg) : - restrictions(restrictions_arg), - upper_cholesky_present(upper_cholesky_present_arg), - lower_cholesky_present(lower_cholesky_present_arg), - constants_exclusion_present(constants_exclusion_present_arg), - symbol_table(symbol_table_arg) -{ -} - -int -SvarIdentificationStatement::getMaxLag() const -{ - int max_lag = 0; - for (svar_identification_restrictions_t::const_iterator it = restrictions.begin(); it != restrictions.end(); it++) - if (it->lag > max_lag) - max_lag = it->lag; - - return max_lag; -} - -void -SvarIdentificationStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - // no equations OK with Svar Identification - mod_file_struct.bvar_present = true; - if (!mod_file_struct.svar_identification_present) - mod_file_struct.svar_identification_present = true; - else - { - cerr << "ERROR: You may only have one svar_identification block in your .mod file." << endl; - exit(EXIT_FAILURE); - } - - if (upper_cholesky_present && lower_cholesky_present) - { - cerr << "ERROR: Within the svar_identification statement, you may only have one of " - << "upper_cholesky and lower_cholesky." << endl; - exit(EXIT_FAILURE); - } -} - -void -SvarIdentificationStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - assert(!(upper_cholesky_present && lower_cholesky_present)); - output << "%" << endl - << "% SVAR IDENTIFICATION" << endl - << "%" << endl; - - if (upper_cholesky_present) - output << "options_.ms.upper_cholesky=1;" << endl; - - if (lower_cholesky_present) - output << "options_.ms.lower_cholesky=1;" << endl; - - if (constants_exclusion_present) - output << "options_.ms.constants_exclusion=1;" << endl; - - if (!upper_cholesky_present && !lower_cholesky_present) - { - int n = symbol_table.endo_nbr(); - int m = 1; // this is the constant, not the shocks - int r = getMaxLag(); - int k = r*n+m; - - if (k < 1) - { - cerr << "ERROR: lag = " << r - << ", number of endogenous variables = " << n - << ", number of exogenous variables = " << m - << ". If this is not a logical error in the specification" - << " of the .mod file, please report it to the Dynare Team." << endl; - exit(EXIT_FAILURE); - } - if (n < 1) - { - cerr << "ERROR: Number of endogenous variables = " << n << "< 1. If this is not a logical " - << "error in the specification of the .mod file, please report it to the Dynare Team." << endl; - exit(EXIT_FAILURE); - } - output << "options_.ms.Qi = cell(" << n << ",1);" << endl; - output << "options_.ms.Ri = cell(" << n << ",1);" << endl; - - for (svar_identification_restrictions_t::const_iterator it = restrictions.begin(); it != restrictions.end(); it++) - { - assert(it->lag >= 0); - if (it->lag == 0) - output << "options_.ms.Qi{" << it->equation << "}(" << it->restriction_nbr << ", " << it->variable + 1 << ") = "; - else - { - int col = (it->lag-1)*n+it->variable+1; - if (col > k) - { - cerr << "ERROR: lag =" << it->lag << ", num endog vars = " << n << "current endog var index = " << it->variable << ". Index " - << "out of bounds. If the above does not represent a logical error, please report this to the Dyanre Team." << endl; - exit(EXIT_FAILURE); - } - output << "options_.ms.Ri{" << it->equation << "}(" << it->restriction_nbr << ", " << col << ") = "; - } - it->value->writeOutput(output); - output << ";" << endl; - } - output << "options_.ms.nlags = " << r << ";" << endl; - } -} - -void -SvarIdentificationStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"svar_identification\""; - - if (upper_cholesky_present) - output << ", \"upper_cholesky\": 1"; - - if (lower_cholesky_present) - output << ", \"lower_cholesky\": 1"; - - if (constants_exclusion_present) - output << ", \"constants_exclusion\": 1"; - - if (!upper_cholesky_present && !lower_cholesky_present) - { - output << ", \"nlags\": " << getMaxLag() - << ", \"restrictions\": ["; - - for (svar_identification_restrictions_t::const_iterator it = restrictions.begin(); it != restrictions.end(); it++) - { - if (it != restrictions.begin()) - output << ", "; - output << "{" - << "\"equation_number\": " << it->equation << ", " - << "\"restriction_number\": " << it->restriction_nbr << ", " - << "\"variable\": \"" << symbol_table.getName(it->variable) << "\", " - << "\"expression\": \""; - it->value->writeOutput(output); - output << "\"}"; - } - output << "]"; - } - output << "}"; -} - -MarkovSwitchingStatement::MarkovSwitchingStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ - OptionsList::num_options_t::const_iterator it_num = options_list.num_options.find("ms.restrictions"); - if (it_num != options_list.num_options.end()) - { - using namespace boost; - OptionsList::num_options_t::const_iterator it_num_regimes - = options_list.num_options.find("ms.number_of_regimes"); - assert(it_num_regimes != options_list.num_options.end()); - int num_regimes = lexical_cast< int >(it_num_regimes->second); - - vector tokenizedRestrictions; - split(tokenizedRestrictions, it_num->second, is_any_of("["), token_compress_on); - for (vector::iterator it = tokenizedRestrictions.begin(); - it != tokenizedRestrictions.end(); it++) - if (it->size() > 0) - { - vector restriction; - split(restriction, *it, is_any_of("], ")); - for (vector::iterator it1 = restriction.begin(); - it1 != restriction.end();) - if (it1->empty()) - restriction.erase(it1); - else - it1++; - - if (restriction.size() != 3) - { - cerr << "ERROR: restrictions in the subsample statement must be specified in the form " - << "[current_period_regime, next_period_regime, transition_probability]" << endl; - exit(EXIT_FAILURE); - } - - try - { - int from_regime = lexical_cast< int >(restriction[0]); - int to_regime = lexical_cast< int >(restriction[1]); - if (from_regime > num_regimes || to_regime > num_regimes) - { - cerr << "ERROR: the regimes specified in the restrictions option must be " - << "<= the number of regimes specified in the number_of_regimes option" << endl; - exit(EXIT_FAILURE); - } - - if (restriction_map.find(make_pair(from_regime, to_regime)) != - restriction_map.end()) - { - cerr << "ERROR: two restrictions were given for: " << from_regime << ", " - << to_regime << endl; - exit(EXIT_FAILURE); - } - - double transition_probability = lexical_cast< double >(restriction[2]); - if (transition_probability > 1.0) - { - cerr << "ERROR: the transition probability, " << transition_probability - << " must be less than 1" << endl; - exit(EXIT_FAILURE); - } - restriction_map[make_pair(from_regime, to_regime)] = transition_probability; - } - catch (const bad_lexical_cast &) - { - cerr << "ERROR: The first two arguments for a restriction must be integers " - << "specifying the regime and the last must be a double specifying the " - << "transition probability. You wrote [" << *it << endl; - exit(EXIT_FAILURE); - } - } - } -} - -void -MarkovSwitchingStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - OptionsList::num_options_t::const_iterator itChain = options_list.num_options.find("ms.chain"); - assert(itChain != options_list.num_options.end()); - int chainNumber = atoi(itChain->second.c_str()); - if (++mod_file_struct.last_markov_switching_chain != chainNumber) - { - cerr << "ERROR: The markov_switching chain option takes consecutive integers " - << "beginning at 1." << endl; - exit(EXIT_FAILURE); - } - - OptionsList::num_options_t::const_iterator it_num = options_list.num_options.find("ms.restrictions"); - if (it_num != options_list.num_options.end()) - { - using namespace boost; - OptionsList::num_options_t::const_iterator it_num_regimes - = options_list.num_options.find("ms.number_of_regimes"); - assert(it_num_regimes != options_list.num_options.end()); - int num_regimes = lexical_cast< int >(it_num_regimes->second); - vector col_trans_prob_sum(num_regimes, 0); - vector row_trans_prob_sum(num_regimes, 0); - vector all_restrictions_in_row(num_regimes, true); - vector all_restrictions_in_col(num_regimes, true); - for (int row = 0; row < num_regimes; row++) - for (int col = 0; col < num_regimes; col++) - if (restriction_map.find(make_pair(row+1, col+1)) != restriction_map.end()) - { - row_trans_prob_sum[row] += restriction_map[make_pair(row+1, col+1)]; - col_trans_prob_sum[col] += restriction_map[make_pair(row+1, col+1)]; - } - else - { - all_restrictions_in_row[row] = false; - all_restrictions_in_col[col] = false; - } - - for (int i = 0; i < num_regimes; i++) - { - if (all_restrictions_in_row[i]) - { - if (row_trans_prob_sum[i] != 1.0) - { - cerr << "ERROR: When all transitions probabilities are specified for a certain " - << "regime, they must sum to 1" << endl; - exit(EXIT_FAILURE); - } - } - else - if (row_trans_prob_sum[i] >= 1.0) - { - cerr << "ERROR: When transition probabilites are not specified for every regime, " - << "their sum must be < 1" << endl; - exit(EXIT_FAILURE); - } - - if (all_restrictions_in_col[i]) - { - if (col_trans_prob_sum[i] != 1.0) - { - cerr << "ERROR: When all transitions probabilities are specified for a certain " - << "regime, they must sum to 1" << endl; - exit(EXIT_FAILURE); - } - } - else - if (col_trans_prob_sum[i] >= 1.0) - { - cerr << "ERROR: When transition probabilites are not specified for every regime, " - << "their sum must be < 1" << endl; - exit(EXIT_FAILURE); - } - } - } - - if (options_list.symbol_list_options.find("ms.parameters") != options_list.symbol_list_options.end()) - mod_file_struct.ms_dsge_present = true; -} - -void -MarkovSwitchingStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - bool isDurationAVec = true; - string infStr("Inf"); - OptionsList::num_options_t::const_iterator itChain, itNOR, itDuration; - map, double >::const_iterator itR; - - itChain = options_list.num_options.find("ms.chain"); - assert(itChain != options_list.num_options.end()); - - itDuration = options_list.num_options.find("ms.duration"); - assert(itDuration != options_list.num_options.end()); - if (atof(itDuration->second.c_str()) || infStr.compare(itDuration->second) == 0) - isDurationAVec = false; - output << "options_.ms.duration = " << itDuration->second << ";" << endl; - - itNOR = options_list.num_options.find("ms.number_of_regimes"); - assert(itNOR != options_list.num_options.end()); - for (int i = 0; i < atoi(itNOR->second.c_str()); i++) - { - output << "options_.ms.ms_chain(" << itChain->second << ").regime(" - << i+1 << ").duration = options_.ms.duration"; - if (isDurationAVec) - output << "(" << i+1 << ")"; - output << ";" << endl; - } - - int restrictions_index = 0; - for (itR = restriction_map.begin(); itR != restriction_map.end(); itR++) - output << "options_.ms.ms_chain(" << itChain->second << ").restrictions(" - << ++restrictions_index << ") = {[" << itR->first.first << ", " - << itR->first.second << ", " << itR->second << "]};" << endl; -} - -void -MarkovSwitchingStatement::writeCOutput(ostream &output, const string &basename) -{ - output << endl; - - OptionsList::num_options_t::const_iterator it - = options_list.num_options.find("ms.chain"); - assert(it != options_list.num_options.end()); - output << "chain = " << it->second << ";" << endl; - - it = options_list.num_options.find("ms.number_of_regimes"); - assert(it != options_list.num_options.end()); - output << "number_of_regimes = " << it->second << ";" << endl; - - it = options_list.num_options.find("ms.number_of_lags"); - if (it != options_list.num_options.end()) - output << "number_of_lags = " << it->second << ";" << endl - << "number_of_lags_was_passed = true;" << endl; - else - output << "number_of_lags_was_passed = false;" << endl; - - it = options_list.num_options.find("ms.duration"); - assert(it != options_list.num_options.end()); - output << "duration.clear();" << endl; - using namespace boost; - vector tokenizedDomain; - split(tokenizedDomain, it->second, is_any_of("[ ]"), token_compress_on); - for (vector::iterator itvs = tokenizedDomain.begin(); - itvs != tokenizedDomain.end(); itvs++) - if (!itvs->empty()) - output << "duration.push_back(" << *itvs << ");" << endl; - - OptionsList::symbol_list_options_t::const_iterator itsl - = options_list.symbol_list_options.find("ms.parameters"); - assert(itsl != options_list.symbol_list_options.end()); - vector parameters = itsl->second.get_symbols(); - output << "parameters.clear();" << endl; - for (vector::iterator itp = parameters.begin(); - itp != parameters.end(); itp++) - output << "parameters.push_back(param_names[\"" << *itp << "\"]);" << endl; - - output << "restriction_map.clear();" << endl; - for (map , double >::iterator itrm = restriction_map.begin(); - itrm != restriction_map.end(); itrm++) - output << "restriction_map[make_pair(" << itrm->first.first << "," - << itrm->first.second << ")] = " << itrm->second << ";" << endl; - - output << "msdsgeinfo->addMarkovSwitching(new MarkovSwitching(" << endl - << " chain, number_of_regimes, number_of_lags, number_of_lags_was_passed, parameters, duration, restriction_map));" << endl; -} - -void -MarkovSwitchingStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"markov_switching\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - - if (!restriction_map.empty()) - output << ", {"; - for (map, double >::const_iterator it = restriction_map.begin(); - it != restriction_map.end(); it++) - { - if (it != restriction_map.begin()) - output << ", "; - output << "{\"current_period_regime\": " << it->first.first - << ", \"next_period_regime\": " << it->first.second - << ", \"transition_probability\": "<< it->second - << "}"; - } - if (!restriction_map.empty()) - output << "}"; - output << "}"; -} - -SvarStatement::SvarStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -SvarStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - OptionsList::num_options_t::const_iterator it0, it1, it2; - it0 = options_list.string_options.find("ms.coefficients"); - it1 = options_list.string_options.find("ms.variances"); - it2 = options_list.string_options.find("ms.constants"); - assert((it0 != options_list.string_options.end() - && it1 == options_list.string_options.end() - && it2 == options_list.string_options.end()) - || (it0 == options_list.string_options.end() - && it1 != options_list.string_options.end() - && it2 == options_list.string_options.end()) - || (it0 == options_list.string_options.end() - && it1 == options_list.string_options.end() - && it2 != options_list.string_options.end())); -} - -void -SvarStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - OptionsList::num_options_t::const_iterator it0, it1, it2; - OptionsList::vec_int_options_t::const_iterator itv; - - it0 = options_list.num_options.find("ms.chain"); - assert(it0 != options_list.num_options.end()); - output << "options_.ms.ms_chain(" << it0->second << ")"; - - it0 = options_list.string_options.find("ms.coefficients"); - it1 = options_list.string_options.find("ms.variances"); - it2 = options_list.string_options.find("ms.constants"); - - if (it0 != options_list.string_options.end()) - output << "." << it0->second; - else if (it1 != options_list.string_options.end()) - output << "." << it1->second; - else - output << "." << it2->second; - - itv = options_list.vector_int_options.find("ms.equations"); - output << ".equations = "; - if (itv != options_list.vector_int_options.end()) - { - assert(itv->second.size() >= 1); - if (itv->second.size() > 1) - { - output << "["; - for (vector::const_iterator viit = itv->second.begin(); - viit != itv->second.end(); viit++) - output << *viit << ";"; - output << "];" << endl; - } - else - output << itv->second.front() << ";" << endl; - } - else - output << "'ALL';" << endl; -} - -void -SvarStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"svar\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -SvarGlobalIdentificationCheckStatement::SvarGlobalIdentificationCheckStatement(void) -{ -} - -void -SvarGlobalIdentificationCheckStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "svar_global_identification_check(options_);" << std::endl; -} - -void -SvarGlobalIdentificationCheckStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"svar_global_identification\"}"; -} - -SetTimeStatement::SetTimeStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -SetTimeStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); -} - -void -SetTimeStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"set_time\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -EstimationDataStatement::EstimationDataStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -EstimationDataStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.estimation_data_statement_present = true; - - OptionsList::num_options_t::const_iterator it = options_list.num_options.find("nobs"); - if (it != options_list.num_options.end()) - if (atoi(it->second.c_str()) <= 0) - { - cerr << "ERROR: The nobs option of the data statement only accepts positive integers." << endl; - exit(EXIT_FAILURE); - } - - if ((options_list.string_options.find("file") == options_list.string_options.end()) - && (options_list.string_options.find("series") == options_list.string_options.end())) - { - cerr << "ERROR: The file or series option must be passed to the data statement." << endl; - exit(EXIT_FAILURE); - } - - if ((options_list.string_options.find("file") != options_list.string_options.end()) - && (options_list.string_options.find("series") != options_list.string_options.end())) - { - cerr << "ERROR: The file and series options cannot be used simultaneously in the data statement." << endl; - exit(EXIT_FAILURE); - } -} - -void -EstimationDataStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output, "options_.dataset"); -} - -void -EstimationDataStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"estimation_data\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -SubsamplesStatement::SubsamplesStatement(const string &name1_arg, - const string &name2_arg, - const subsample_declaration_map_t subsample_declaration_map_arg, - const SymbolTable &symbol_table_arg) : - name1(name1_arg), - name2(name2_arg), - subsample_declaration_map(subsample_declaration_map_arg), - symbol_table(symbol_table_arg) -{ -} - -void -SubsamplesStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ -} - -void -SubsamplesStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "subsamples_indx = get_new_or_existing_ei_index('subsamples_index', '" - << name1 << "','" << name2 << "');" << endl - << "estimation_info.subsamples_index(subsamples_indx) = {'" << name1; - if (!name2.empty()) - output << ":" << name2; - output << "'};" << endl - << "estimation_info.subsamples(subsamples_indx).range = {};" << endl - << "estimation_info.subsamples(subsamples_indx).range_index = {};" << endl; - - int map_indx = 1; - for (subsample_declaration_map_t::const_iterator it = subsample_declaration_map.begin(); - it != subsample_declaration_map.end(); it++, map_indx++) - output << "estimation_info.subsamples(subsamples_indx).range_index(" << map_indx << ") = {'" - << it->first << "'};" << endl - << "estimation_info.subsamples(subsamples_indx).range(" << map_indx << ").date1 = " - << it->second.first << ";" << endl - << "estimation_info.subsamples(subsamples_indx).range(" << map_indx << ").date2 = " - << it->second.second << ";" << endl; - - // Initialize associated subsample substructures in estimation_info - const SymbolType symb_type = symbol_table.getType(name1); - string lhs_field; - if (symb_type == eParameter) - lhs_field = "parameter"; - else if (symb_type == eExogenous || symb_type == eExogenousDet) - lhs_field = "structural_innovation"; - else - lhs_field = "measurement_error"; - - output << "eifind = get_new_or_existing_ei_index('" << lhs_field; - - if (!name2.empty()) - output << "_corr"; - output << "_prior_index', '" - << name1 << "', '"; - if (!name2.empty()) - output << name2; - output << "');" << endl; - - lhs_field = "estimation_info." + lhs_field; - if (!name2.empty()) - lhs_field += "_corr"; - output << lhs_field << "_prior_index(eifind) = {'" << name1; - if (!name2.empty()) - output << ":" << name2; - output << "'};" << endl; - - output << lhs_field << "(eifind).subsample_prior = estimation_info.empty_prior;" << endl - << lhs_field << "(eifind).subsample_prior(1:" << subsample_declaration_map.size() - << ") = estimation_info.empty_prior;" << endl - << lhs_field << "(eifind).range_index = estimation_info.subsamples(subsamples_indx).range_index;" - << endl; -} - -void -SubsamplesStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"subsamples\"" - << ", \"name1\": \"" << name1 << "\""; - if (!name2.empty()) - output << ", \"name2\": \"" << name2 << "\""; - - output << ", \"declarations\": {"; - for (subsample_declaration_map_t::const_iterator it = subsample_declaration_map.begin(); - it != subsample_declaration_map.end(); it++) - { - if (it != subsample_declaration_map.begin()) - output << ","; - output << "{" - << "\"range_index\": \"" << it->first << "\"" - << ", \"date1\": \"" << it->second.first << "\"" - << ", \"date2\": \"" << it->second.second << "\"" - << "}"; - } - output << "}" - << "}"; -} - -SubsamplesEqualStatement::SubsamplesEqualStatement(const string &to_name1_arg, - const string &to_name2_arg, - const string &from_name1_arg, - const string &from_name2_arg, - const SymbolTable &symbol_table_arg) : - to_name1(to_name1_arg), - to_name2(to_name2_arg), - from_name1(from_name1_arg), - from_name2(from_name2_arg), - symbol_table(symbol_table_arg) -{ -} - -void -SubsamplesEqualStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "subsamples_to_indx = get_new_or_existing_ei_index('subsamples_index', '" - << to_name1 << "','" << to_name2 << "');" << endl - << "estimation_info.subsamples_index(subsamples_to_indx) = {'" << to_name1; - if (!to_name2.empty()) - output << ":" << to_name2; - output << "'};" << endl - << "subsamples_from_indx = get_existing_subsamples_indx('" << from_name1 << "','" << from_name2 << "');" - << endl - << "estimation_info.subsamples(subsamples_to_indx) = estimation_info.subsamples(subsamples_from_indx);" - << endl; - - // Initialize associated subsample substructures in estimation_info - const SymbolType symb_type = symbol_table.getType(to_name1); - string lhs_field; - if (symb_type == eParameter) - lhs_field = "parameter"; - else if (symb_type == eExogenous || symb_type == eExogenousDet) - lhs_field = "structural_innovation"; - else - lhs_field = "measurement_error"; - - output << "eifind = get_new_or_existing_ei_index('" << lhs_field; - - if (!to_name2.empty()) - output << "_corr"; - output << "_prior_index', '" - << to_name1 << "', '"; - if (!to_name2.empty()) - output << to_name2; - output << "');" << endl; - - lhs_field = "estimation_info." + lhs_field; - if (!to_name2.empty()) - lhs_field += "_corr"; - output << lhs_field << "_prior_index(eifind) = {'" << to_name1; - if (!to_name2.empty()) - output << ":" << to_name2; - output << "'};" << endl; - - output << lhs_field << "(eifind).subsample_prior = estimation_info.empty_prior;" << endl - << lhs_field << "(eifind).subsample_prior(1:size(estimation_info.subsamples(subsamples_to_indx).range_index,2)) = estimation_info.empty_prior;" - << endl - << lhs_field << "(eifind).range_index = estimation_info.subsamples(subsamples_to_indx).range_index;" - << endl; -} - -void -SubsamplesEqualStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"subsamples_equal\"" - << ", \"to_name1\": \"" << to_name1 << "\""; - if (!to_name2.empty()) - output << ", \"to_name2\": \"" << to_name2 << "\""; - output << ", \"from_name1\": \"" << from_name1 << "\""; - if (!from_name2.empty()) - output << ", \"from_name2\": \"" << from_name2 << "\""; - output << "}"; -} - -JointPriorStatement::JointPriorStatement(const vector joint_parameters_arg, - const PriorDistributions &prior_shape_arg, - const OptionsList &options_list_arg) : - joint_parameters(joint_parameters_arg), - prior_shape(prior_shape_arg), - options_list(options_list_arg) -{ -} - -void -JointPriorStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - if (joint_parameters.size() < 2) - { - cerr << "ERROR: you must pass at least two parameters to the joint prior statement" << endl; - exit(EXIT_FAILURE); - } - - if (prior_shape == eNoShape) - { - cerr << "ERROR: You must pass the shape option to the prior statement." << endl; - exit(EXIT_FAILURE); - } - - if (options_list.num_options.find("mean") == options_list.num_options.end() - && options_list.num_options.find("mode") == options_list.num_options.end()) - { - cerr << "ERROR: You must pass at least one of mean and mode to the prior statement." << endl; - exit(EXIT_FAILURE); - } - - OptionsList::num_options_t::const_iterator it_num = options_list.num_options.find("domain"); - if (it_num != options_list.num_options.end()) - { - using namespace boost; - vector tokenizedDomain; - split(tokenizedDomain, it_num->second, is_any_of("[ ]"), token_compress_on); - if (tokenizedDomain.size() != 4) - { - cerr << "ERROR: You must pass exactly two values to the domain option." << endl; - exit(EXIT_FAILURE); - } - } -} - -void -JointPriorStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - for (vector::const_iterator it = joint_parameters.begin(); it != joint_parameters.end(); it++) - output << "eifind = get_new_or_existing_ei_index('joint_parameter_prior_index', '" - << *it << "', '');" << endl - << "estimation_info.joint_parameter_prior_index(eifind) = {'" << *it << "'};" << endl; - - output << "key = {["; - for (vector::const_iterator it = joint_parameters.begin(); it != joint_parameters.end(); it++) - output << "get_new_or_existing_ei_index('joint_parameter_prior_index', '" << *it << "', '') ..." - << endl << " "; - output << "]};" << endl; - - string lhs_field("estimation_info.joint_parameter_tmp"); - - writeOutputHelper(output, "domain", lhs_field); - writeOutputHelper(output, "interval", lhs_field); - writeOutputHelper(output, "mean", lhs_field); - writeOutputHelper(output, "median", lhs_field); - writeOutputHelper(output, "mode", lhs_field); - - assert(prior_shape != eNoShape); - output << lhs_field << ".shape = " << prior_shape << ";" << endl; - - writeOutputHelper(output, "shift", lhs_field); - writeOutputHelper(output, "stdev", lhs_field); - writeOutputHelper(output, "truncate", lhs_field); - writeOutputHelper(output, "variance", lhs_field); - - output << "estimation_info.joint_parameter_tmp = [key, ..." << endl - << " " << lhs_field << ".domain , ..." << endl - << " " << lhs_field << ".interval , ..." << endl - << " " << lhs_field << ".mean , ..." << endl - << " " << lhs_field << ".median , ..." << endl - << " " << lhs_field << ".mode , ..." << endl - << " " << lhs_field << ".shape , ..." << endl - << " " << lhs_field << ".shift , ..." << endl - << " " << lhs_field << ".stdev , ..." << endl - << " " << lhs_field << ".truncate , ..." << endl - << " " << lhs_field << ".variance];" << endl - << "estimation_info.joint_parameter = [estimation_info.joint_parameter; estimation_info.joint_parameter_tmp];" << endl - << "estimation_info=rmfield(estimation_info, 'joint_parameter_tmp');" << endl; -} - -void -JointPriorStatement::writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const -{ - OptionsList::num_options_t::const_iterator itn = options_list.num_options.find(field); - output << lhs_field << "." << field << " = {"; - if (field == "variance") - output << "{"; - if (itn != options_list.num_options.end()) - output << itn->second; - else - output << "{}"; - if (field == "variance") - output << "}"; - output << "};" << endl; -} - -void -JointPriorStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"joint_prior\"" - << ", \"key\": ["; - for (vector::const_iterator it = joint_parameters.begin(); it != joint_parameters.end(); it++) - { - if (it != joint_parameters.begin()) - output << ", "; - output << "\"" << *it << "\""; - } - output << "]"; - - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - - output << ", \"shape\": "; - switch (prior_shape) - { - case eBeta: - output << "\"beta\""; - break; - case eGamma: - output << "\"gamma\""; - break; - case eNormal: - output << "\"normal\""; - break; - case eInvGamma: - output << "\"inv_gamma\""; - break; - case eUniform: - output << "\"uniform\""; - break; - case eInvGamma2: - output << "\"inv_gamma2\""; - break; - case eDirichlet: - output << "\"dirichlet\""; - break; - case eWeibull: - output << "\"weibull\""; - break; - case eNoShape: - cerr << "Impossible case." << endl; - exit(EXIT_FAILURE); - } - output << "}"; -} - -BasicPriorStatement::~BasicPriorStatement() -{ -} - -BasicPriorStatement::BasicPriorStatement(const string &name_arg, - const string &subsample_name_arg, - const PriorDistributions &prior_shape_arg, - const expr_t &variance_arg, - const OptionsList &options_list_arg) : - name(name_arg), - subsample_name(subsample_name_arg), - prior_shape(prior_shape_arg), - variance(variance_arg), - options_list(options_list_arg) -{ -} - -void -BasicPriorStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - if (prior_shape == eNoShape) - { - cerr << "ERROR: You must pass the shape option to the prior statement." << endl; - exit(EXIT_FAILURE); - } - - if (options_list.num_options.find("mean") == options_list.num_options.end() - && options_list.num_options.find("mode") == options_list.num_options.end()) - { - cerr << "ERROR: You must pass at least one of mean and mode to the prior statement." << endl; - exit(EXIT_FAILURE); - } - - OptionsList::num_options_t::const_iterator it_stdev = options_list.num_options.find("stdev"); - if ((it_stdev == options_list.num_options.end() && variance == NULL) - || (it_stdev != options_list.num_options.end() && variance != NULL)) - { - cerr << "ERROR: You must pass exactly one of stdev and variance to the prior statement." << endl; - exit(EXIT_FAILURE); - } - - OptionsList::num_options_t::const_iterator it_num = options_list.num_options.find("domain"); - if (it_num != options_list.num_options.end()) - { - using namespace boost; - vector tokenizedDomain; - split(tokenizedDomain, it_num->second, is_any_of("[ ]"), token_compress_on); - if (tokenizedDomain.size() != 4) - { - cerr << "ERROR: You must pass exactly two values to the domain option." << endl; - exit(EXIT_FAILURE); - } - } -} - -bool -BasicPriorStatement::is_structural_innovation(const SymbolType symb_type) const -{ - if (symb_type == eExogenous || symb_type == eExogenousDet) - return true; - return false; -} - -void -BasicPriorStatement::get_base_name(const SymbolType symb_type, string &lhs_field) const -{ - if (symb_type == eExogenous || symb_type == eExogenousDet) - lhs_field = "structural_innovation"; - else - lhs_field = "measurement_error"; -} - -void -BasicPriorStatement::writeCommonOutput(ostream &output, const string &lhs_field) const -{ - output << lhs_field << " = estimation_info.empty_prior;" << endl; - - writeCommonOutputHelper(output, "domain", lhs_field); - writeCommonOutputHelper(output, "interval", lhs_field); - writeCommonOutputHelper(output, "mean", lhs_field); - writeCommonOutputHelper(output, "median", lhs_field); - writeCommonOutputHelper(output, "mode", lhs_field); - - assert(prior_shape != eNoShape); - output << lhs_field << ".shape = " << prior_shape << ";" << endl; - - writeCommonOutputHelper(output, "shift", lhs_field); - writeCommonOutputHelper(output, "stdev", lhs_field); - writeCommonOutputHelper(output, "truncate", lhs_field); - - if (variance) - { - output << lhs_field << ".variance = "; - variance->writeOutput(output); - output << ";" << endl; - } -} - -void -BasicPriorStatement::writeCommonOutputHelper(ostream &output, const string &field, const string &lhs_field) const -{ - OptionsList::num_options_t::const_iterator itn = options_list.num_options.find(field); - if (itn != options_list.num_options.end()) - output << lhs_field << "." << field << " = "<< itn->second << ";" << endl; -} - -void -BasicPriorStatement::writePriorOutput(ostream &output, string &lhs_field, const string &name2) const -{ - if (subsample_name.empty()) - lhs_field += ".prior(1)"; - else - { - output << "subsamples_indx = get_existing_subsamples_indx('" << name << "','" << name2 << "');" << endl - << "eisind = get_subsamples_range_indx(subsamples_indx, '" << subsample_name << "');" << endl; - lhs_field += ".subsample_prior(eisind)"; - } - writeCommonOutput(output, lhs_field); -} - -void -BasicPriorStatement::writeJsonPriorOutput(ostream &output) const -{ - output << ", \"name\": \"" << name << "\"" - << ", \"subsample\": \"" << subsample_name << "\"" - << ", "; - writeJsonShape(output); - if (variance != NULL) - { - deriv_node_temp_terms_t tef_terms; - output << ", \"variance\": \""; - variance->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\""; - } - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } -} - -void -BasicPriorStatement::writeCVarianceOption(ostream &output) const -{ - output << "variance = "; - if (variance) - variance->writeOutput(output); - else - output << "numeric_limits::quiet_NaN()"; - output << ";" << endl; -} - -void -BasicPriorStatement::writeCDomain(ostream &output) const -{ - output << "domain.clear();" << endl; - OptionsList::num_options_t::const_iterator it_num = options_list.num_options.find("domain"); - if (it_num != options_list.num_options.end()) - { - using namespace boost; - vector tokenizedDomain; - split(tokenizedDomain, it_num->second, is_any_of("[ ]"), token_compress_on); - for (vector::iterator it = tokenizedDomain.begin(); - it != tokenizedDomain.end(); it++) - if (!it->empty()) - output << "domain.push_back(" << *it << ");" << endl; - } -} - -void -BasicPriorStatement::writeCOutputHelper(ostream &output, const string &field) const -{ - OptionsList::num_options_t::const_iterator itn = options_list.num_options.find(field); - if (itn != options_list.num_options.end()) - output << field << " = " << itn->second << ";" << endl; - else - output << field << " = " << "numeric_limits::quiet_NaN();" << endl; -} - -void -BasicPriorStatement::writeCShape(ostream &output) const -{ - output << "shape = "; - switch (prior_shape) - { - case eBeta: - output << "\"beta\";" << endl; - break; - case eGamma: - output << "\"gamma\";" << endl; - break; - case eNormal: - output << "\"normal\";" << endl; - break; - case eInvGamma: - output << "\"inv_gamma\";" << endl; - break; - case eUniform: - output << "\"uniform\";" << endl; - break; - case eInvGamma2: - output << "\"inv_gamma2\";" << endl; - break; - case eDirichlet: - output << "\"dirichlet\";" << endl; - break; - case eWeibull: - output << "\"weibull\";" << endl; - break; - case eNoShape: - assert(prior_shape != eNoShape); - } -} - -void -BasicPriorStatement::writeJsonShape(ostream &output) const -{ - output << "\"shape\": "; - switch (prior_shape) - { - case eBeta: - output << "\"beta\""; - break; - case eGamma: - output << "\"gamma\""; - break; - case eNormal: - output << "\"normal\""; - break; - case eInvGamma: - output << "\"inv_gamma\""; - break; - case eUniform: - output << "\"uniform\""; - break; - case eInvGamma2: - output << "\"inv_gamma2\""; - break; - case eDirichlet: - output << "\"dirichlet\""; - break; - case eWeibull: - output << "\"weibull\""; - break; - case eNoShape: - assert(prior_shape != eNoShape); - } -} - -PriorStatement::PriorStatement(const string &name_arg, - const string &subsample_name_arg, - const PriorDistributions &prior_shape_arg, - const expr_t &variance_arg, - const OptionsList &options_list_arg) : - BasicPriorStatement(name_arg, subsample_name_arg, prior_shape_arg, variance_arg, options_list_arg) -{ -} - -void -PriorStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - string lhs_field = "estimation_info.parameter(eifind)"; - output << "eifind = get_new_or_existing_ei_index('parameter_prior_index', '" - << name << "', '');" << endl - << "estimation_info.parameter_prior_index(eifind) = {'" << name << "'};" << endl; - writePriorOutput(output, lhs_field, ""); -} - -void -PriorStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"prior\""; - writeJsonPriorOutput(output); - output << "}"; -} - -void -PriorStatement::writeCOutput(ostream &output, const string &basename) -{ - output << endl - << "index = param_names[\""<< name << "\"];" << endl; - writeCShape(output); - writeCOutputHelper(output, "mean"); - writeCOutputHelper(output, "mode"); - writeCOutputHelper(output, "stdev"); - writeCVarianceOption(output); - writeCDomain(output); - - output << "msdsgeinfo->addPrior(new ModFilePrior(" << endl - << " index, shape, mean, mode, stdev, variance, domain));" << endl; -} - -StdPriorStatement::StdPriorStatement(const string &name_arg, - const string &subsample_name_arg, - const PriorDistributions &prior_shape_arg, - const expr_t &variance_arg, - const OptionsList &options_list_arg, - const SymbolTable &symbol_table_arg) : - BasicPriorStatement(name_arg, subsample_name_arg, prior_shape_arg, variance_arg, options_list_arg), - symbol_table(symbol_table_arg) -{ -} - -void -StdPriorStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - string lhs_field; - get_base_name(symbol_table.getType(name), lhs_field); - output << "eifind = get_new_or_existing_ei_index('" << lhs_field << "_prior_index', '" - << name << "', '');" << endl - << "estimation_info." << lhs_field << "_prior_index(eifind) = {'" << name << "'};" << endl; - - lhs_field = "estimation_info." + lhs_field + "(eifind)"; - writePriorOutput(output, lhs_field, ""); -} - -void -StdPriorStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"std_prior\""; - writeJsonPriorOutput(output); - output << "}"; -} - -void -StdPriorStatement::writeCOutput(ostream &output, const string &basename) -{ - output << endl - << "index = "; - if (is_structural_innovation(symbol_table.getType(name))) - output << "exo_names"; - else - output << "endo_names"; - output << "[\""<< name << "\"];" << endl; - - writeCShape(output); - writeCOutputHelper(output, "mean"); - writeCOutputHelper(output, "mode"); - writeCOutputHelper(output, "stdev"); - writeCVarianceOption(output); - writeCDomain(output); - - if (is_structural_innovation(symbol_table.getType(name))) - output << "msdsgeinfo->addStructuralInnovationPrior(new ModFileStructuralInnovationPrior("; - else - output << "msdsgeinfo->addMeasurementErrorPrior(new ModFileMeasurementErrorPrior("; - output << endl << " index, shape, mean, mode, stdev, variance, domain));" << endl; -} - -CorrPriorStatement::CorrPriorStatement(const string &name_arg1, const string &name_arg2, - const string &subsample_name_arg, - const PriorDistributions &prior_shape_arg, - const expr_t &variance_arg, - const OptionsList &options_list_arg, - const SymbolTable &symbol_table_arg) : - BasicPriorStatement(name_arg1, subsample_name_arg, prior_shape_arg, variance_arg, options_list_arg), - name1(name_arg2), - symbol_table(symbol_table_arg) -{ -} - -void -CorrPriorStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - BasicPriorStatement::checkPass(mod_file_struct, warnings); - if (symbol_table.getType(name) != symbol_table.getType(name1)) - { - cerr << "ERROR: In the corr(A,B).prior statement, A and B must be of the same type. " - << "In your case, " << name << " and " << name1 << " are of different " - << "types." << endl; - exit(EXIT_FAILURE); - } -} - -void -CorrPriorStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - string lhs_field; - get_base_name(symbol_table.getType(name), lhs_field); - - output << "eifind = get_new_or_existing_ei_index('" << lhs_field << "_corr_prior_index', '" - << name << "', '" << name1 << "');" << endl - << "estimation_info." << lhs_field << "_corr_prior_index(eifind) = {'" - << name << ":" << name1 << "'};" << endl; - - lhs_field = "estimation_info." + lhs_field + "_corr(eifind)"; - writePriorOutput(output, lhs_field, name1); -} - -void -CorrPriorStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"corr_prior\"" - << ", \"name2\": \"" << name1 << "\""; - writeJsonPriorOutput(output); - output << "}"; -} - -void -CorrPriorStatement::writeCOutput(ostream &output, const string &basename) -{ - output << endl - << "index = "; - if (is_structural_innovation(symbol_table.getType(name))) - output << "exo_names"; - else - output << "endo_names"; - output << "[\""<< name << "\"];" << endl; - - output << "index1 = "; - if (is_structural_innovation(symbol_table.getType(name1))) - output << "exo_names"; - else - output << "endo_names"; - output << "[\""<< name1 << "\"];" << endl; - - writeCShape(output); - writeCOutputHelper(output, "mean"); - writeCOutputHelper(output, "mode"); - writeCOutputHelper(output, "stdev"); - writeCVarianceOption(output); - writeCDomain(output); - - if (is_structural_innovation(symbol_table.getType(name))) - output << "msdsgeinfo->addStructuralInnovationCorrPrior(new ModFileStructuralInnovationCorrPrior("; - else - output << "msdsgeinfo->addMeasurementErrorCorrPrior(new ModFileMeasurementErrorCorrPrior("; - output << endl <<" index, index1, shape, mean, mode, stdev, variance, domain));" << endl; -} - -PriorEqualStatement::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) : - to_declaration_type(to_declaration_type_arg), - to_name1(to_name1_arg), - to_name2(to_name2_arg), - to_subsample_name(to_subsample_name_arg), - from_declaration_type(from_declaration_type_arg), - from_name1(from_name1_arg), - from_name2(from_name2_arg), - from_subsample_name(from_subsample_name_arg), - symbol_table(symbol_table_arg) -{ -} - -void -PriorEqualStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - if ((to_declaration_type != "par" && to_declaration_type != "std" && to_declaration_type != "corr") - || (from_declaration_type != "par" && from_declaration_type != "std" && from_declaration_type != "corr")) - { - cerr << "Internal Dynare Error" << endl; - exit(EXIT_FAILURE); - } -} - -void -PriorEqualStatement::get_base_name(const SymbolType symb_type, string &lhs_field) const -{ - if (symb_type == eExogenous || symb_type == eExogenousDet) - lhs_field = "structural_innovation"; - else - lhs_field = "measurement_error"; -} - -void -PriorEqualStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - string lhs_field, rhs_field; - - if (to_declaration_type == "par") - lhs_field = "parameter"; - else - get_base_name(symbol_table.getType(to_name1), lhs_field); - - if (from_declaration_type == "par") - rhs_field = "parameter"; - else - get_base_name(symbol_table.getType(from_name1), rhs_field); - - if (to_declaration_type == "corr") - lhs_field += "_corr"; - - if (from_declaration_type == "corr") - rhs_field += "_corr"; - - output << "ei_to_ind = get_new_or_existing_ei_index('" << lhs_field << "_prior_index', '" - << to_name1 << "', '" << to_name2<< "');" << endl - << "ei_from_ind = get_new_or_existing_ei_index('" << rhs_field << "_prior_index', '" - << from_name1 << "', '" << from_name2<< "');" << endl - << "estimation_info." << lhs_field << "_prior_index(ei_to_ind) = {'" << to_name1; - - if (to_declaration_type == "corr") - output << ":" << to_name2; - output << "'};" << endl; - - if (to_declaration_type == "par") - lhs_field = "parameter"; - - if (from_declaration_type == "par") - rhs_field = "parameter"; - - lhs_field = "estimation_info." + lhs_field + "(ei_to_ind)"; - rhs_field = "estimation_info." + rhs_field + "(ei_from_ind)"; - - if (to_subsample_name.empty()) - lhs_field += ".prior"; - else - { - output << "subsamples_to_indx = get_existing_subsamples_indx('" << to_name1 << "','" << to_name2 << "');" << endl - << "ei_to_ss_ind = get_subsamples_range_indx(subsamples_to_indx, '" << to_subsample_name << "');" << endl; - lhs_field += ".subsample_prior(ei_to_ss_ind)"; - } - - if (from_subsample_name.empty()) - rhs_field += ".prior"; - else - { - output << "subsamples_from_indx = get_existing_subsamples_indx('" << from_name1 << "','" << from_name2 << "');" << endl - << "ei_from_ss_ind = get_subsamples_range_indx(subsamples_from_indx, '" << from_subsample_name << "');" << endl; - rhs_field += ".subsample_prior(ei_from_ss_ind)"; - } - - output << lhs_field << " = " << rhs_field << ";" << endl; -} - -void -PriorEqualStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"prior_equal\"" - << ", \"to_name1\": \"" << to_name1 << "\""; - if (to_declaration_type == "corr") - output << ", \"to_name2\": \"" << to_name2 << "\""; - output << ", \"to_subsample\": \"" << to_subsample_name << "\"" - << ", \"from_name1\": \"" << from_name1 << "\""; - if (to_declaration_type == "corr") - output << ", \"from_name2\": \"" << from_name2 << "\""; - output << ", \"from_subsample\": \"" << from_subsample_name << "\"" - << "}"; -} - -BasicOptionsStatement::~BasicOptionsStatement() -{ -} - -BasicOptionsStatement::BasicOptionsStatement(const string &name_arg, - const string &subsample_name_arg, - const OptionsList &options_list_arg) : - name(name_arg), - subsample_name(subsample_name_arg), - options_list(options_list_arg) -{ -} - -void -BasicOptionsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ -} - -bool -BasicOptionsStatement::is_structural_innovation(const SymbolType symb_type) const -{ - if (symb_type == eExogenous || symb_type == eExogenousDet) - return true; - return false; -} - -void -BasicOptionsStatement::get_base_name(const SymbolType symb_type, string &lhs_field) const -{ - if (symb_type == eExogenous || symb_type == eExogenousDet) - lhs_field = "structural_innovation"; - else - lhs_field = "measurement_error"; -} - -void -BasicOptionsStatement::writeCommonOutput(ostream &output, const string &lhs_field) const -{ - output << lhs_field << " = estimation_info.empty_options;" << endl; - - writeCommonOutputHelper(output, "bounds", lhs_field); - writeCommonOutputHelper(output, "init", lhs_field); - writeCommonOutputHelper(output, "jscale", lhs_field); -} - -void -BasicOptionsStatement::writeCommonOutputHelper(ostream &output, const string &field, const string &lhs_field) const -{ - OptionsList::num_options_t::const_iterator itn = options_list.num_options.find(field); - if (itn != options_list.num_options.end()) - output << lhs_field << "." << field << " = " << itn->second << ";" << endl; -} - -void -BasicOptionsStatement::writeCOutputHelper(ostream &output, const string &field) const -{ - OptionsList::num_options_t::const_iterator itn = options_list.num_options.find(field); - if (itn != options_list.num_options.end()) - output << field << " = " << itn->second << ";" << endl; - else - output << field << " = " << "numeric_limits::quiet_NaN();" << endl; -} - -void -BasicOptionsStatement::writeOptionsOutput(ostream &output, string &lhs_field, const string &name2) const -{ - if (subsample_name.empty()) - lhs_field += ".options(1)"; - else - { - output << "subsamples_indx = get_existing_subsamples_indx('" << name << "','" << name2 << "');" << endl - << "eisind = get_subsamples_range_indx(subsamples_indx, '" << subsample_name << "');" << endl; - lhs_field += ".subsample_options(eisind)"; - } - writeCommonOutput(output, lhs_field); -} - -void -BasicOptionsStatement::writeJsonOptionsOutput(ostream &output) const -{ - output << ", \"name\": \"" << name << "\""; - if (!subsample_name.empty()) - output << ", \"subsample_name\": \"" << subsample_name << "\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } -} - -OptionsStatement::OptionsStatement(const string &name_arg, - const string &subsample_name_arg, - const OptionsList &options_list_arg) : - BasicOptionsStatement(name_arg, subsample_name_arg, options_list_arg) -{ -} - -void -OptionsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - string lhs_field = "estimation_info.parameter(eifind)"; - output << "eifind = get_new_or_existing_ei_index('parameter_options_index', '" - << name << "', '');" << endl - << "estimation_info.parameter_options_index(eifind) = {'" << name << "'};" << endl; - writeOptionsOutput(output, lhs_field, ""); -} - -void -OptionsStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"options\""; - writeJsonOptionsOutput(output); - output << "}"; -} - -void -OptionsStatement::writeCOutput(ostream &output, const string &basename) -{ - output << endl - << "index = param_names[\""<< name << "\"];" << endl; - writeCOutputHelper(output, "init"); - output << "msdsgeinfo->addOption(new ModFileOption(index, init));" << endl; -} - -StdOptionsStatement::StdOptionsStatement(const string &name_arg, - const string &subsample_name_arg, - const OptionsList &options_list_arg, - const SymbolTable &symbol_table_arg) : - BasicOptionsStatement(name_arg, subsample_name_arg, options_list_arg), - symbol_table(symbol_table_arg) -{ -} - -void -StdOptionsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - string lhs_field; - get_base_name(symbol_table.getType(name), lhs_field); - output << "eifind = get_new_or_existing_ei_index('" << lhs_field << "_options_index', '" - << name << "', '');" << endl - << "estimation_info." << lhs_field << "_options_index(eifind) = {'" << name << "'};" << endl; - - lhs_field = "estimation_info." + lhs_field + "(eifind)"; - writeOptionsOutput(output, lhs_field, ""); -} - -void -StdOptionsStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"std_options\""; - writeJsonOptionsOutput(output); - output << "}"; -} - -void -StdOptionsStatement::writeCOutput(ostream &output, const string &basename) -{ - output << endl - << "index = "; - if (is_structural_innovation(symbol_table.getType(name))) - output << "exo_names"; - else - output << "endo_names"; - output << "[\""<< name << "\"];" << endl; - - writeCOutputHelper(output, "init"); - - if (is_structural_innovation(symbol_table.getType(name))) - output << "msdsgeinfo->addStructuralInnovationOption(new ModFileStructuralInnovationOption("; - else - output << "msdsgeinfo->addMeasurementErrorOption(new ModFileMeasurementErrorOption("; - output << "index, init));" << endl; -} - -CorrOptionsStatement::CorrOptionsStatement(const string &name_arg1, const string &name_arg2, - const string &subsample_name_arg, - const OptionsList &options_list_arg, - const SymbolTable &symbol_table_arg) : - BasicOptionsStatement(name_arg1, subsample_name_arg, options_list_arg), - name1(name_arg2), - symbol_table(symbol_table_arg) -{ -} - -void -CorrOptionsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - if (symbol_table.getType(name) != symbol_table.getType(name1)) - { - cerr << "ERROR: In the corr(A,B).options statement, A and B must be of the same type. " - << "In your case, " << name << " and " << name1 << " are of different " - << "types." << endl; - exit(EXIT_FAILURE); - } -} - -void -CorrOptionsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - string lhs_field; - get_base_name(symbol_table.getType(name), lhs_field); - - output << "eifind = get_new_or_existing_ei_index('" << lhs_field << "_corr_options_index', '" - << name << "', '" << name1 << "');" << endl - << "estimation_info." << lhs_field << "_corr_options_index(eifind) = {'" - << name << ":" << name1 << "'};" << endl; - - lhs_field = "estimation_info." + lhs_field + "_corr(eifind)"; - writeOptionsOutput(output, lhs_field, name1); -} - -void -CorrOptionsStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"corr_options\"" - << ", \"name2\": \"" << name1 << "\""; - writeJsonOptionsOutput(output); - output << "}"; -} - -void -CorrOptionsStatement::writeCOutput(ostream &output, const string &basename) -{ - output << endl - << "index = "; - if (is_structural_innovation(symbol_table.getType(name))) - output << "exo_names"; - else - output << "endo_names"; - output << "[\""<< name << "\"];" << endl; - - output << "index1 = "; - if (is_structural_innovation(symbol_table.getType(name1))) - output << "exo_names"; - else - output << "endo_names"; - output << "[\""<< name1 << "\"];" << endl; - - writeCOutputHelper(output, "init"); - - if (is_structural_innovation(symbol_table.getType(name))) - output << "msdsgeinfo->addStructuralInnovationCorrOption(new ModFileStructuralInnovationCorrOption("; - else - output << "msdsgeinfo->addMeasurementErrorCorrOption(new ModFileMeasurementErrorCorrOption("; - output << "index, index1, init));" << endl; -} - -OptionsEqualStatement::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) : - to_declaration_type(to_declaration_type_arg), - to_name1(to_name1_arg), - to_name2(to_name2_arg), - to_subsample_name(to_subsample_name_arg), - from_declaration_type(from_declaration_type_arg), - from_name1(from_name1_arg), - from_name2(from_name2_arg), - from_subsample_name(from_subsample_name_arg), - symbol_table(symbol_table_arg) -{ -} - -void -OptionsEqualStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - if ((to_declaration_type != "par" && to_declaration_type != "std" && to_declaration_type != "corr") - || (from_declaration_type != "par" && from_declaration_type != "std" && from_declaration_type != "corr")) - { - cerr << "Internal Dynare Error" << endl; - exit(EXIT_FAILURE); - } -} - -void -OptionsEqualStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"options_equal\"" - << ", \"to_name1\": \"" << to_name1 << "\""; - if (to_declaration_type == "corr") - output << ", \"to_name2\": \"" << to_name2 << "\""; - output << ", \"to_subsample\": \"" << to_subsample_name << "\"" - << ", \"from_name1\": \"" << from_name1 << "\""; - if (to_declaration_type == "corr") - output << ", \"from_name2\": \"" << from_name2 << "\""; - output << ", \"from_subsample\": \"" << from_subsample_name << "\"" - << "}"; -} - -void -OptionsEqualStatement::get_base_name(const SymbolType symb_type, string &lhs_field) const -{ - if (symb_type == eExogenous || symb_type == eExogenousDet) - lhs_field = "structural_innovation"; - else - lhs_field = "measurement_error"; -} - -void -OptionsEqualStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - string lhs_field, rhs_field; - - if (to_declaration_type == "par") - lhs_field = "parameter"; - else - get_base_name(symbol_table.getType(to_name1), lhs_field); - - if (from_declaration_type == "par") - rhs_field = "parameter"; - else - get_base_name(symbol_table.getType(from_name1), rhs_field); - - if (to_declaration_type == "corr") - lhs_field += "_corr"; - - if (from_declaration_type == "corr") - rhs_field += "_corr"; - - output << "ei_to_ind = get_new_or_existing_ei_index('" << lhs_field << "_options_index', '" - << to_name1 << "', '" << to_name2<< "');" << endl - << "ei_from_ind = get_new_or_existing_ei_index('" << rhs_field << "_options_index', '" - << from_name1 << "', '" << from_name2<< "');" << endl - << "estimation_info." << lhs_field << "_options_index(ei_to_ind) = {'" << to_name1; - - if (to_declaration_type == "corr") - output << ":" << to_name2; - output << "'};" << endl; - - if (to_declaration_type == "par") - lhs_field = "parameter"; - - if (from_declaration_type == "par") - rhs_field = "parameter"; - - lhs_field = "estimation_info." + lhs_field + "(ei_to_ind)"; - rhs_field = "estimation_info." + rhs_field + "(ei_from_ind)"; - - if (to_subsample_name.empty()) - lhs_field += ".options"; - else - { - output << "subsamples_to_indx = get_existing_subsamples_indx('" << to_name1 << "','" << to_name2 << "');" << endl - << "ei_to_ss_ind = get_subsamples_range_indx(subsamples_to_indx, '" << to_subsample_name << "');" << endl; - lhs_field += ".subsample_options(ei_to_ss_ind)"; - } - - if (from_subsample_name.empty()) - rhs_field += ".options"; - else - { - output << "subsamples_from_indx = get_existing_subsamples_indx('" << from_name1 << "','" << from_name2 << "');" << endl - << "ei_from_ss_ind = get_subsamples_range_indx(subsamples_from_indx, '" << from_subsample_name << "');" << endl; - rhs_field += ".subsample_options(ei_from_ss_ind)"; - } - - output << lhs_field << " = " << rhs_field << ";" << endl; -} - -CalibSmootherStatement::CalibSmootherStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg) - : symbol_list(symbol_list_arg), options_list(options_list_arg) -{ -} - -void -CalibSmootherStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.calib_smoother_present = true; -} - -void -CalibSmootherStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - OptionsList::string_options_t::const_iterator it = options_list.string_options.find("parameter_set"); - if (it == options_list.string_options.end()) - output << "options_.parameter_set = 'calibration';" << endl; - symbol_list.writeOutput("var_list_", output); - output << "options_.smoother = 1;" << endl - << "options_.order = 1;" << endl - << "[oo_, M_, options_, bayestopt_] = evaluate_smoother(options_.parameter_set, var_list_, M_, oo_, options_, bayestopt_, estim_params_);" << endl; -} - -void -CalibSmootherStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"calib_smoother\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -ExtendedPathStatement::ExtendedPathStatement(const OptionsList &options_list_arg) - : options_list(options_list_arg) -{ -} - -void -ExtendedPathStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - mod_file_struct.extended_path_present = true; - - if (options_list.num_options.find("periods") == options_list.num_options.end()) - { - cerr << "ERROR: the 'periods' option of 'extended_path' is mandatory" << endl; - exit(EXIT_FAILURE); - } - - // Fill in option_occbin of mod_file_struct - OptionsList::string_options_t::const_iterator it = options_list.num_options.find("occbin"); - if (it != options_list.string_options.end()) - mod_file_struct.occbin_option = true; -} - -void -ExtendedPathStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - // Beware: options do not have the same name in the interface and in the M code... - - for (OptionsList::num_options_t::const_iterator it = options_list.num_options.begin(); - it != options_list.num_options.end(); ++it) - if (it->first != string("periods")) - output << "options_." << it->first << " = " << it->second << ";" << endl; - - output << "extended_path([], " << options_list.num_options.find("periods")->second - << ", [], options_, M_, oo_);" << endl; -} - -void -ExtendedPathStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"extended_path\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -ModelDiagnosticsStatement::ModelDiagnosticsStatement() -{ -} - -void -ModelDiagnosticsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "model_diagnostics(M_,options_,oo_);" << endl; -} - -void -ModelDiagnosticsStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"model_diagnostics\"}"; -} - -Smoother2histvalStatement::Smoother2histvalStatement(const OptionsList &options_list_arg) : - options_list(options_list_arg) -{ -} - -void -Smoother2histvalStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output, "options_smoother2histval"); - output << "smoother2histval(options_smoother2histval);" << endl; -} - -void -Smoother2histvalStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"smoother_2_histval\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - output << "}"; -} - -GMMEstimationStatement::GMMEstimationStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg) : - symbol_list(symbol_list_arg), - options_list(options_list_arg) -{ -} - -void -GMMEstimationStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - symbol_list.writeOutput("var_list_", output); - options_list.writeOutput(output); - output << "[M_, oo_, estim_params_, bayestopt_, dataset_, dataset_info] = " - << "GMM_SMM_estimation_core(var_list_, M_, options_, oo_, estim_params_, bayestopt_, dataset_, dataset_info, 'GMM');" << endl; -} - -void -GMMEstimationStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"gmm_estimation\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -SMMEstimationStatement::SMMEstimationStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg) : - symbol_list(symbol_list_arg), - options_list(options_list_arg) -{ -} - -void -SMMEstimationStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - symbol_list.writeOutput("var_list_", output); - options_list.writeOutput(output); - output << "[M_, oo_, estim_params_, bayestopt_, dataset_, dataset_info] = " - << "GMM_SMM_estimation_core(var_list_, M_, options_, oo_, estim_params_, bayestopt_, dataset_, dataset_info, 'SMM');" << endl; -} - -void -SMMEstimationStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"smm_estimation\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - if (!symbol_list.empty()) - { - output << ", "; - symbol_list.writeJsonOutput(output); - } - output << "}"; -} - -GenerateIRFsStatement::GenerateIRFsStatement(const OptionsList &options_list_arg, - const vector &generate_irf_names_arg, - const vector > &generate_irf_elements_arg) : - options_list(options_list_arg), - generate_irf_names(generate_irf_names_arg), - generate_irf_elements(generate_irf_elements_arg) -{ -} - -void -GenerateIRFsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - - if (generate_irf_names.empty()) - return; - - output << "options_.irf_opt.irf_shock_graphtitles = { "; - for (vector::const_iterator it = generate_irf_names.begin(); - it != generate_irf_names.end(); it++) - output << "'" << *it << "'; "; - output << "};" << endl; - - output << "options_.irf_opt.irf_shocks = zeros(M_.exo_nbr, " - << generate_irf_names.size() << ");" << endl; - - for (size_t i = 0; i < generate_irf_names.size(); i++) - { - map m = generate_irf_elements[i]; - for (map::const_iterator it = m.begin(); - it != m.end(); it++) - output << "options_.irf_opt.irf_shocks(M_.exo_names == '" - << it->first << "', " << i + 1 << ") = " - << it->second << ";" << endl; - } -} - -void -GenerateIRFsStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"generate_irfs\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - - if (!generate_irf_names.empty()) - { - output << ", \"irf_elements\": ["; - for (size_t i = 0; i < generate_irf_names.size(); i++) - { - output << "{\"name\": \"" << generate_irf_names[i] << "\", \"shocks\": ["; - map m = generate_irf_elements[i]; - size_t idx = 0; - for (map::const_iterator it = m.begin(); - it != m.end(); it++, idx++) - { - output << "{\"exogenous_variable\": \"" << it->first << "\", " - << "\"exogenous_variable_value\": \"" << it->second << "\"}"; - if (idx + 1 < m.size()) - output << ", "; - } - output << "]}"; - if (i + 1 < generate_irf_names.size()) - output << ", "; - } - output << "]"; - } - output << "}"; -} diff --git a/preprocessor/ComputingTasks.hh b/preprocessor/ComputingTasks.hh deleted file mode 100644 index 195475d00..000000000 --- a/preprocessor/ComputingTasks.hh +++ /dev/null @@ -1,1125 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#ifndef _COMPUTINGTASKS_HH -#define _COMPUTINGTASKS_HH - -#include - -#include "SymbolList.hh" -#include "SymbolTable.hh" -#include "Statement.hh" -#include "StaticModel.hh" -#include "DynamicModel.hh" -#include "SteadyStateModel.hh" - -class SteadyStatement : public Statement -{ -private: - const OptionsList options_list; -public: - SteadyStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class CheckStatement : public Statement -{ -private: - const OptionsList options_list; -public: - CheckStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class SimulStatement : public Statement -{ -private: - const OptionsList options_list; -public: - SimulStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class PerfectForesightSetupStatement : public Statement -{ -private: - const OptionsList options_list; -public: - PerfectForesightSetupStatement(const OptionsList &options_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class PerfectForesightSolverStatement : public Statement -{ -private: - const OptionsList options_list; -public: - PerfectForesightSolverStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class PriorPosteriorFunctionStatement : public Statement -{ -private: - const bool prior_func; - const OptionsList options_list; -public: - PriorPosteriorFunctionStatement(const bool prior_func_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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class ModelInfoStatement : public Statement -{ -private: - const OptionsList options_list; -public: - ModelInfoStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class StochSimulStatement : public Statement -{ -private: - const SymbolList symbol_list; - const OptionsList options_list; -public: - StochSimulStatement(const SymbolList &symbol_list_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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class ForecastStatement : public Statement -{ -private: - const SymbolList symbol_list; - const OptionsList options_list; -public: - ForecastStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class RamseyModelStatement : public Statement -{ -private: - const OptionsList options_list; -public: - RamseyModelStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class RamseyConstraintsStatement : public Statement -{ -public: - struct Constraint - { - int endo; - BinaryOpcode code; - expr_t expression; - }; - typedef vector constraints_t; -private: - const SymbolTable &symbol_table; - const constraints_t constraints; -public: - RamseyConstraintsStatement(const SymbolTable &symbol_table_arg, const constraints_t &constraints_arg); - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class RamseyPolicyStatement : public Statement -{ -private: - const SymbolTable &symbol_table; - const vector ramsey_policy_list; - const OptionsList options_list; -public: - RamseyPolicyStatement(const SymbolTable &symbol_table_arg, - const vector &ramsey_policy_list_arg, - const OptionsList &options_list_arg); - 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 -{ -private: - const SymbolList symbol_list; - const OptionsList options_list; -public: - DiscretionaryPolicyStatement(const SymbolList &symbol_list_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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class RplotStatement : public Statement -{ -private: - const SymbolList symbol_list; -public: - RplotStatement(const SymbolList &symbol_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class UnitRootVarsStatement : public Statement -{ -public: - UnitRootVarsStatement(void); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class PeriodsStatement : public Statement -{ -private: - const int periods; -public: - PeriodsStatement(int periods_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class DsampleStatement : public Statement -{ -private: - const int val1, val2; -public: - DsampleStatement(int val1_arg); - DsampleStatement(int val1_arg, int val2_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class EstimationStatement : public Statement -{ -private: - const SymbolList symbol_list; - const OptionsList options_list; -public: - EstimationStatement(const SymbolList &symbol_list_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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class DynareSensitivityStatement : public Statement -{ -private: - const OptionsList options_list; -public: - DynareSensitivityStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class ObservationTrendsStatement : public Statement -{ -public: - typedef map trend_elements_t; -private: - const trend_elements_t trend_elements; - const SymbolTable &symbol_table; -public: - ObservationTrendsStatement(const trend_elements_t &trend_elements_arg, - const SymbolTable &symbol_table_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class OsrParamsStatement : public Statement -{ -private: - const SymbolList symbol_list; - const SymbolTable &symbol_table; -public: - OsrParamsStatement(const SymbolList &symbol_list_arg, const SymbolTable &symbol_table_arg); - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class OsrStatement : public Statement -{ -private: - const SymbolList symbol_list; - const OptionsList options_list; -public: - OsrStatement(const SymbolList &symbol_list_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; - virtual void writeJsonOutput(ostream &output) const; -}; - -//! Temporary structure used when parsing estimation_params* statements -class OsrParams -{ -public: - string name; - expr_t low_bound, up_bound; - - void - init(const DataTree &datatree) - { - name = ""; - low_bound = datatree.MinusInfinity; - up_bound = datatree.Infinity; - } -}; - -class OsrParamsBoundsStatement : public Statement -{ -private: - const vector osr_params_list; -public: - OsrParamsBoundsStatement(const vector &osr_params_list_arg); - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class DynaTypeStatement : public Statement -{ -private: - const SymbolList symbol_list; - const string filename; -public: - DynaTypeStatement(const SymbolList &symbol_list_arg, - const string &filename_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class DynaSaveStatement : public Statement -{ -private: - const SymbolList symbol_list; - const string filename; -public: - DynaSaveStatement(const SymbolList &symbol_list_arg, - const string &filename_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class ModelComparisonStatement : public Statement -{ -public: - typedef vector > filename_list_t; -private: - filename_list_t filename_list; - OptionsList options_list; -public: - ModelComparisonStatement(const filename_list_t &filename_list_arg, - const OptionsList &options_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -//! Temporary structure used when parsing estimation_params* statements -class EstimationParams -{ -public: - int type; - string name, name2; - PriorDistributions prior; - expr_t init_val, low_bound, up_bound, mean, std, p3, p4, jscale; - - void - init(const DataTree &datatree) - { - type = 0; - name = ""; - name2 = ""; - prior = eNoShape; - init_val = datatree.NaN; - low_bound = datatree.MinusInfinity; - up_bound = datatree.Infinity; - mean = datatree.NaN; - std = datatree.NaN; - p3 = datatree.NaN; - p4 = datatree.NaN; - jscale = datatree.NaN; - } -}; - -class EstimatedParamsStatement : public Statement -{ -private: - const vector estim_params_list; - const SymbolTable &symbol_table; -public: - EstimatedParamsStatement(const vector &estim_params_list_arg, - const SymbolTable &symbol_table_arg); - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class EstimatedParamsInitStatement : public Statement -{ -private: - const vector estim_params_list; - const SymbolTable &symbol_table; - const bool use_calibration; -public: - EstimatedParamsInitStatement(const vector &estim_params_list_arg, - const SymbolTable &symbol_table_arg, - const bool use_calibration_arg); - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class EstimatedParamsBoundsStatement : public Statement -{ -private: - const vector estim_params_list; - const SymbolTable &symbol_table; -public: - EstimatedParamsBoundsStatement(const vector &estim_params_list_arg, - const SymbolTable &symbol_table_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class OptimWeightsStatement : public Statement -{ -public: - typedef map var_weights_t; - typedef map, expr_t> covar_weights_t; -private: - const var_weights_t var_weights; - const covar_weights_t covar_weights; - const SymbolTable &symbol_table; -public: - OptimWeightsStatement(const var_weights_t &var_weights_arg, - const covar_weights_t &covar_weights_arg, - const SymbolTable &symbol_table_arg); - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -/*! \todo Make model_tree a member instead of a pointer */ -class PlannerObjectiveStatement : public Statement -{ -private: - StaticModel *model_tree; - bool computing_pass_called; -public: - //! Constructor - /*! \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 - (no exogenous, no lead/lag) */ - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - /*! \todo allow for the possibility of disabling temporary terms */ - virtual void computingPass(); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; - //! Return the Planner Objective - StaticModel *getPlannerObjective() const; -}; - -class BVARDensityStatement : public Statement -{ -private: - const int maxnlags; - const OptionsList options_list; -public: - BVARDensityStatement(int maxnlags_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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class BVARForecastStatement : public Statement -{ -private: - const int nlags; - const OptionsList options_list; -public: - BVARForecastStatement(int nlags_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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class SBVARStatement : public Statement -{ -private: - const OptionsList options_list; -public: - SBVARStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class MSSBVAREstimationStatement : public Statement -{ -private: - const OptionsList options_list; -public: - MSSBVAREstimationStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class MSSBVARSimulationStatement : public Statement -{ -private: - const OptionsList options_list; -public: - MSSBVARSimulationStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class MSSBVARComputeMDDStatement : public Statement -{ -private: - const OptionsList options_list; -public: - MSSBVARComputeMDDStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class MSSBVARComputeProbabilitiesStatement : public Statement -{ -private: - const OptionsList options_list; -public: - MSSBVARComputeProbabilitiesStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class MSSBVARIrfStatement : public Statement -{ -private: - const SymbolList symbol_list; - const OptionsList options_list; -public: - MSSBVARIrfStatement(const SymbolList &symbol_list_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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class MSSBVARForecastStatement : public Statement -{ -private: - const OptionsList options_list; -public: - MSSBVARForecastStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class MSSBVARVarianceDecompositionStatement : public Statement -{ -private: - const OptionsList options_list; -public: - MSSBVARVarianceDecompositionStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class IdentificationStatement : public Statement -{ -private: - OptionsList options_list; -public: - IdentificationStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class WriteLatexDynamicModelStatement : public Statement -{ -private: - const DynamicModel &dynamic_model; - const bool write_equation_tags; -public: - WriteLatexDynamicModelStatement(const DynamicModel &dynamic_model_arg, bool write_equation_tags_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class WriteLatexStaticModelStatement : public Statement -{ -private: - const StaticModel &static_model; - const bool write_equation_tags; -public: - WriteLatexStaticModelStatement(const StaticModel &static_model_arg, bool write_equation_tags_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class WriteLatexOriginalModelStatement : public Statement -{ -private: - const DynamicModel &original_model; - const bool write_equation_tags; -public: - WriteLatexOriginalModelStatement(const DynamicModel &original_model_arg, bool write_equation_tags_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class WriteLatexSteadyStateModelStatement : public Statement -{ -private: - const SteadyStateModel &steady_state_model; -public: - WriteLatexSteadyStateModelStatement(const SteadyStateModel &steady_state_model_arg); - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class ShockDecompositionStatement : public Statement -{ -private: - const SymbolList symbol_list; - const OptionsList options_list; -public: - ShockDecompositionStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class RealtimeShockDecompositionStatement : public Statement -{ -private: - const SymbolList symbol_list; - const OptionsList options_list; -public: - RealtimeShockDecompositionStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; -}; - -class PlotShockDecompositionStatement : public Statement -{ -private: - const SymbolList symbol_list; - const OptionsList options_list; -public: - PlotShockDecompositionStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; -}; - -class InitialConditionDecompositionStatement : public Statement -{ -private: - const SymbolList symbol_list; - const OptionsList options_list; -public: - InitialConditionDecompositionStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; -}; - -class ConditionalForecastStatement : public Statement -{ -private: - const OptionsList options_list; -public: - ConditionalForecastStatement(const OptionsList &options_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class PlotConditionalForecastStatement : public Statement -{ -private: - //! A value of -1 indicates that the user didn't specify a value - const int periods; - const SymbolList symbol_list; -public: - PlotConditionalForecastStatement(int periods_arg, const SymbolList &symbol_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class CalibSmootherStatement : public Statement -{ -private: - const SymbolList symbol_list; - const OptionsList options_list; -public: - CalibSmootherStatement(const SymbolList &symbol_list_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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class ExtendedPathStatement : public Statement -{ -private: - const OptionsList options_list; -public: - ExtendedPathStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class SvarIdentificationStatement : public Statement -{ -public: - // typedef map, vector > svar_identification_exclusion_t; - struct svar_identification_restriction - { - int equation; - int restriction_nbr; - int lag; - int variable; - expr_t value; - }; - - typedef vector< svar_identification_restriction > svar_identification_restrictions_t; -private: - const svar_identification_restrictions_t restrictions; - const bool upper_cholesky_present; - const bool lower_cholesky_present; - const bool constants_exclusion_present; - const SymbolTable &symbol_table; - int getMaxLag() const; -public: - SvarIdentificationStatement(const svar_identification_restrictions_t &restrictions_arg, - const bool &upper_cholesky_present_arg, - const bool &lower_cholesky_present_arg, - const bool &constants_exclusion_present_arg, - const SymbolTable &symbol_table_arg); - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class MarkovSwitchingStatement : public Statement -{ -private: - const OptionsList options_list; - map , double > restriction_map; -public: - MarkovSwitchingStatement(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; - virtual void writeCOutput(ostream &output, const string &basename); - virtual void writeJsonOutput(ostream &output) const; -}; - -class SvarStatement : public Statement -{ -private: - const OptionsList options_list; -public: - SvarStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class SvarGlobalIdentificationCheckStatement : public Statement -{ -public: - SvarGlobalIdentificationCheckStatement(); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class SetTimeStatement : public Statement -{ -private: - const OptionsList options_list; -public: - SetTimeStatement(const OptionsList &options_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class EstimationDataStatement : public Statement -{ -private: - const OptionsList options_list; -public: - EstimationDataStatement(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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class SubsamplesStatement : public Statement -{ -public: - //! Storage for declaring subsamples: map - typedef map > subsample_declaration_map_t; -private: - const string name1; - const string name2; - const subsample_declaration_map_t subsample_declaration_map; - const SymbolTable symbol_table; -public: - SubsamplesStatement(const string &name1_arg, - const string &name2_arg, - const subsample_declaration_map_t subsample_declaration_map_arg, - const SymbolTable &symbol_table_arg); - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class SubsamplesEqualStatement : public Statement -{ -private: - const string to_name1; - const string to_name2; - const string from_name1; - const string from_name2; - const SymbolTable symbol_table; -public: - SubsamplesEqualStatement(const string &to_name1_arg, - const string &to_name2_arg, - const string &from_name1_arg, - const string &from_name2_arg, - 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 -{ -private: - const vector joint_parameters; - const PriorDistributions prior_shape; - const OptionsList options_list; -public: - JointPriorStatement(const vector 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; - virtual void writeJsonOutput(ostream &output) const; -}; - -class BasicPriorStatement : public Statement -{ -public: - virtual - ~BasicPriorStatement(); -protected: - const string name; - const string subsample_name; - const PriorDistributions prior_shape; - const expr_t variance; - const OptionsList options_list; - BasicPriorStatement(const string &name_arg, - const string &subsample_name_arg, - const PriorDistributions &prior_shape_arg, - const expr_t &variance_arg, - 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 writeCommonOutput(ostream &output, const string &lhs_field) const; - void writeCommonOutputHelper(ostream &output, const string &field, const string &lhs_field) const; - void writePriorOutput(ostream &output, string &lhs_field, const string &name2) const; - bool is_structural_innovation(const SymbolType symb_type) const; - void writePriorIndex(ostream &output, const string &lhs_field) const; - void writeVarianceOption(ostream &output, const string &lhs_field) const; - void writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const; - void writeShape(ostream &output, const string &lhs_field) const; - void 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 writeJsonPriorOutput(ostream &output) const; -}; - -class PriorStatement : public BasicPriorStatement -{ -public: - PriorStatement(const string &name_arg, - const string &subsample_name_arg, - const PriorDistributions &prior_shape_arg, - const expr_t &variance_arg, - 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 -{ -private: - const SymbolTable symbol_table; -public: - StdPriorStatement(const string &name_arg, - const string &subsample_name_arg, - const PriorDistributions &prior_shape_arg, - const expr_t &variance_arg, - const OptionsList &options_list_arg, - const SymbolTable &symbol_table_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 CorrPriorStatement : public BasicPriorStatement -{ -private: - const string name1; - const SymbolTable symbol_table; -public: - CorrPriorStatement(const string &name_arg1, - const string &name_arg2, - const string &subsample_name_arg, - const PriorDistributions &prior_shape_arg, - const expr_t &variance_arg, - const OptionsList &options_list_arg, - const SymbolTable &symbol_table_arg); - 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 -{ -private: - const string to_declaration_type; - const string to_name1; - const string to_name2; - const string to_subsample_name; - const string from_declaration_type; - const string from_name1; - const string from_name2; - const string from_subsample_name; - 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); - void get_base_name(const SymbolType symb_type, string &lhs_field) const; - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class BasicOptionsStatement : public Statement -{ -public: - virtual - ~BasicOptionsStatement(); -protected: - const string name; - const string subsample_name; - const OptionsList options_list; - BasicOptionsStatement(const string &name_arg, - const string &subsample_name_arg, - const OptionsList &options_list_arg); - 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 writeCommonOutput(ostream &output, const string &lhs_field) const; - void writeCommonOutputHelper(ostream &output, const string &field, const string &lhs_field) const; - bool is_structural_innovation(const SymbolType symb_type) const; - void writeOptionsIndex(ostream &output, const string &lhs_field) const; - void writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const; - void writeCOutputHelper(ostream &output, const string &field) const; - void writeJsonOptionsOutput(ostream &output) const; -}; - -class OptionsStatement : public BasicOptionsStatement -{ -public: - OptionsStatement(const string &name_arg, const string &subsample_name_arg, 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 StdOptionsStatement : public BasicOptionsStatement -{ -private: - const SymbolTable symbol_table; -public: - StdOptionsStatement(const string &name_arg, - const string &subsample_name_arg, - const OptionsList &options_list_arg, - const SymbolTable &symbol_table_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 CorrOptionsStatement : public BasicOptionsStatement -{ -private: - const string name1; - const SymbolTable symbol_table; -public: - CorrOptionsStatement(const string &name_arg1, const string &name_arg2, - const string &subsample_name_arg, - const OptionsList &options_list_arg, - const SymbolTable &symbol_table_arg); - 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 OptionsEqualStatement : public Statement -{ -private: - const string to_declaration_type; - const string to_name1; - const string to_name2; - const string to_subsample_name; - const string from_declaration_type; - const string from_name1; - const string from_name2; - const string from_subsample_name; - const SymbolTable symbol_table; -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; - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class ModelDiagnosticsStatement : public Statement -{ -public: - ModelDiagnosticsStatement(); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class Smoother2histvalStatement : public Statement -{ -private: - const OptionsList options_list; -public: - Smoother2histvalStatement(const OptionsList &options_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class GMMEstimationStatement : public Statement -{ -private: - const SymbolList symbol_list; - const OptionsList options_list; -public: - GMMEstimationStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class SMMEstimationStatement : public Statement -{ -private: - const SymbolList symbol_list; - const OptionsList options_list; -public: - SMMEstimationStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class GenerateIRFsStatement : public Statement -{ -public: -private: - const OptionsList options_list; - const vector generate_irf_names; - const vector > generate_irf_elements; -public: - GenerateIRFsStatement(const OptionsList &options_list_arg, - const vector &generate_irf_names_arg, - const vector > &generate_irf_elements_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -#endif diff --git a/preprocessor/ConfigFile.cc b/preprocessor/ConfigFile.cc deleted file mode 100644 index 64d899e13..000000000 --- a/preprocessor/ConfigFile.cc +++ /dev/null @@ -1,783 +0,0 @@ -/* - * 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 . - */ - -#include -#include -#include -#include - -#include "ConfigFile.hh" -#include -#include -#include -#include - -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 &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 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 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 tokenizedPath; - split(tokenizedPath, tokenizedLine.back(), is_any_of(":"), token_compress_on); - for (vector::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 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 = " << endl - << " or 2) CPUnbr = [:]" << endl - << " where is an Integer > 0." << endl; - exit(EXIT_FAILURE); - } - - minCpuNbr--; - maxCpuNbr--; - if (minCpuNbr > maxCpuNbr) - { - int tmp = maxCpuNbr; - maxCpuNbr = minCpuNbr; - minCpuNbr = tmp; - } - } - else if (!tokenizedLine.front().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 sep(" ,;", "()", drop_empty_tokens); - tokenizer > tokens(tokenizedLine.back(), sep); - bool begin_weight = false; - string node_name; - for (tokenizer >::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(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 &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::const_iterator it = hooks.begin(); it != hooks.end(); it++) - { - const map hookmap = (*it)->get_hooks(); - for (map ::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::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::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::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::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 -ConfigFile::getIncludePaths() const -{ - vector include_paths; - for (vector::const_iterator it = paths.begin(); it != paths.end(); it++) - { - map > pathmap = (*it)->get_paths(); - for (map >::const_iterator mapit = pathmap.begin(); mapit != pathmap.end(); mapit++) - for (vector::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::const_iterator it = hooks.begin(); it != hooks.end(); it++) - { - map hookmap = (*it)->get_hooks(); - for (map ::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::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::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; -} diff --git a/preprocessor/ConfigFile.hh b/preprocessor/ConfigFile.hh deleted file mode 100644 index e3d9143eb..000000000 --- a/preprocessor/ConfigFile.hh +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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 . - */ - -#ifndef _CONFIG_FILE_HH -#define _CONFIG_FILE_HH - -#include -#include - -#include "WarningConsolidation.hh" - -using namespace std; - -typedef map member_nodes_t; - -class Hook -{ -public: - Hook(string &global_init_file_arg); - ~Hook(); -private: - map hooks; -public: - inline map - get_hooks() - { - return hooks; - }; -}; - -class Path -{ -public: - Path(vector &includepath_arg); - ~Path(); -private: - map > paths; -public: - inline map > - 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 hooks; - //! Paths - vector paths; - //! Cluster Table - map clusters; - //! Node Map - map slave_nodes; - //! Add Hooks - void addHooksConfFileElement(string &global_init_file); - //! Add Paths - void addPathsConfFileElement(vector &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 ¶llel_config_file); - //! Check Pass - void checkPass(WarningConsolidation &warnings) const; - //! Check Pass - void transformPass(); - //! Get Path Info - vector 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 diff --git a/preprocessor/DataTree.cc b/preprocessor/DataTree.cc deleted file mode 100644 index dac7c157b..000000000 --- a/preprocessor/DataTree.cc +++ /dev/null @@ -1,755 +0,0 @@ -/* - * Copyright (C) 2003-2016 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 . - */ - -#include -#include -#include - -#include "DataTree.hh" - -DataTree::DataTree(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg) : - symbol_table(symbol_table_arg), - num_constants(num_constants_arg), - external_functions_table(external_functions_table_arg), - node_counter(0) -{ - Zero = AddNonNegativeConstant("0"); - One = AddNonNegativeConstant("1"); - Two = AddNonNegativeConstant("2"); - - MinusOne = AddUMinus(One); - - NaN = AddNonNegativeConstant("NaN"); - Infinity = AddNonNegativeConstant("Inf"); - MinusInfinity = AddUMinus(Infinity); - - Pi = AddNonNegativeConstant("3.141592653589793"); -} - -DataTree::~DataTree() -{ - for (node_list_t::iterator it = node_list.begin(); it != node_list.end(); it++) - delete *it; -} - -expr_t -DataTree::AddNonNegativeConstant(const string &value) -{ - int id = num_constants.AddNonNegativeConstant(value); - - num_const_node_map_t::iterator it = num_const_node_map.find(id); - if (it != num_const_node_map.end()) - return it->second; - else - return new NumConstNode(*this, id); -} - -VariableNode * -DataTree::AddVariableInternal(int symb_id, int lag) -{ - variable_node_map_t::iterator it = variable_node_map.find(make_pair(symb_id, lag)); - if (it != variable_node_map.end()) - return it->second; - else - return new VariableNode(*this, symb_id, lag); -} - -bool -DataTree::ParamUsedWithLeadLagInternal() const -{ - for (variable_node_map_t::const_iterator it = variable_node_map.begin(); - it != variable_node_map.end(); it++) - if (symbol_table.getType(it->first.first) == eParameter && it->first.second != 0) - return true; - return false; -} - -VariableNode * -DataTree::AddVariable(int symb_id, int lag) -{ - assert(lag == 0); - return AddVariableInternal(symb_id, lag); -} - -expr_t -DataTree::AddPlus(expr_t iArg1, expr_t iArg2) -{ - if (iArg1 != Zero && iArg2 != Zero) - { - // Simplify x+(-y) in x-y - UnaryOpNode *uarg2 = dynamic_cast(iArg2); - if (uarg2 != NULL && uarg2->get_op_code() == oUminus) - return AddMinus(iArg1, uarg2->get_arg()); - - // To treat commutativity of "+" - // Nodes iArg1 and iArg2 are sorted by index - if (iArg1->idx > iArg2->idx) - { - expr_t tmp = iArg1; - 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 -DataTree::AddMinus(expr_t iArg1, expr_t iArg2) -{ - if (iArg2 == Zero) - return iArg1; - - if (iArg1 == Zero) - return AddUMinus(iArg2); - - if (iArg1 == iArg2) - return Zero; - - return AddBinaryOp(iArg1, oMinus, iArg2); -} - -expr_t -DataTree::AddUMinus(expr_t iArg1) -{ - if (iArg1 != Zero) - { - // Simplify -(-x) in x - UnaryOpNode *uarg = dynamic_cast(iArg1); - if (uarg != NULL && uarg->get_op_code() == oUminus) - return uarg->get_arg(); - - return AddUnaryOp(oUminus, iArg1); - } - else - return Zero; -} - -expr_t -DataTree::AddTimes(expr_t iArg1, expr_t iArg2) -{ - if (iArg1 == MinusOne) - return AddUMinus(iArg2); - else if (iArg2 == MinusOne) - return AddUMinus(iArg1); - else if (iArg1 != Zero && iArg1 != One && iArg2 != Zero && iArg2 != One) - { - // To treat commutativity of "*" - // Nodes iArg1 and iArg2 are sorted by index - if (iArg1->idx > iArg2->idx) - { - expr_t tmp = iArg1; - 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 -DataTree::AddDivide(expr_t iArg1, expr_t iArg2) throw (DivisionByZeroException) -{ - if (iArg2 == One) - return iArg1; - - // This test should be before the next two, otherwise 0/0 won't be rejected - if (iArg2 == Zero) - { - cerr << "ERROR: Division by zero!" << endl; - throw DivisionByZeroException(); - } - - if (iArg1 == Zero) - return Zero; - - if (iArg1 == iArg2) - return One; - - return AddBinaryOp(iArg1, oDivide, iArg2); -} - -expr_t -DataTree::AddLess(expr_t iArg1, expr_t iArg2) -{ - return AddBinaryOp(iArg1, oLess, iArg2); -} - -expr_t -DataTree::AddGreater(expr_t iArg1, expr_t iArg2) -{ - return AddBinaryOp(iArg1, oGreater, iArg2); -} - -expr_t -DataTree::AddLessEqual(expr_t iArg1, expr_t iArg2) -{ - return AddBinaryOp(iArg1, oLessEqual, iArg2); -} - -expr_t -DataTree::AddGreaterEqual(expr_t iArg1, expr_t iArg2) -{ - return AddBinaryOp(iArg1, oGreaterEqual, iArg2); -} - -expr_t -DataTree::AddEqualEqual(expr_t iArg1, expr_t iArg2) -{ - return AddBinaryOp(iArg1, oEqualEqual, iArg2); -} - -expr_t -DataTree::AddDifferent(expr_t iArg1, expr_t iArg2) -{ - return AddBinaryOp(iArg1, oDifferent, iArg2); -} - -expr_t -DataTree::AddPower(expr_t iArg1, expr_t iArg2) -{ - if (iArg1 != Zero && iArg2 != Zero && iArg1 != One && iArg2 != One) - return AddBinaryOp(iArg1, oPower, iArg2); - else if (iArg1 == One) - return One; - else if (iArg2 == One) - return iArg1; - else if (iArg2 == Zero) - return One; - else - return Zero; -} - -expr_t -DataTree::AddPowerDeriv(expr_t iArg1, expr_t iArg2, int powerDerivOrder) -{ - assert(powerDerivOrder > 0); - return AddBinaryOp(iArg1, oPowerDeriv, iArg2, powerDerivOrder); -} - -expr_t -DataTree::AddExp(expr_t iArg1) -{ - if (iArg1 != Zero) - return AddUnaryOp(oExp, iArg1); - else - return One; -} - -expr_t -DataTree::AddLog(expr_t iArg1) -{ - if (iArg1 != Zero && iArg1 != One) - return AddUnaryOp(oLog, iArg1); - else if (iArg1 == One) - return Zero; - else - { - cerr << "ERROR: log(0) not defined!" << endl; - exit(EXIT_FAILURE); - } -} - -expr_t -DataTree::AddLog10(expr_t iArg1) -{ - if (iArg1 != Zero && iArg1 != One) - return AddUnaryOp(oLog10, iArg1); - else if (iArg1 == One) - return Zero; - else - { - cerr << "ERROR: log10(0) not defined!" << endl; - exit(EXIT_FAILURE); - } -} - -expr_t -DataTree::AddCos(expr_t iArg1) -{ - if (iArg1 != Zero) - return AddUnaryOp(oCos, iArg1); - else - return One; -} - -expr_t -DataTree::AddSin(expr_t iArg1) -{ - if (iArg1 != Zero) - return AddUnaryOp(oSin, iArg1); - else - return Zero; -} - -expr_t -DataTree::AddTan(expr_t iArg1) -{ - if (iArg1 != Zero) - return AddUnaryOp(oTan, iArg1); - else - return Zero; -} - -expr_t -DataTree::AddAcos(expr_t iArg1) -{ - if (iArg1 != One) - return AddUnaryOp(oAcos, iArg1); - else - return Zero; -} - -expr_t -DataTree::AddAsin(expr_t iArg1) -{ - if (iArg1 != Zero) - return AddUnaryOp(oAsin, iArg1); - else - return Zero; -} - -expr_t -DataTree::AddAtan(expr_t iArg1) -{ - if (iArg1 != Zero) - return AddUnaryOp(oAtan, iArg1); - else - return Zero; -} - -expr_t -DataTree::AddCosh(expr_t iArg1) -{ - if (iArg1 != Zero) - return AddUnaryOp(oCosh, iArg1); - else - return One; -} - -expr_t -DataTree::AddSinh(expr_t iArg1) -{ - if (iArg1 != Zero) - return AddUnaryOp(oSinh, iArg1); - else - return Zero; -} - -expr_t -DataTree::AddTanh(expr_t iArg1) -{ - if (iArg1 != Zero) - return AddUnaryOp(oTanh, iArg1); - else - return Zero; -} - -expr_t -DataTree::AddAcosh(expr_t iArg1) -{ - if (iArg1 != One) - return AddUnaryOp(oAcosh, iArg1); - else - return Zero; -} - -expr_t -DataTree::AddAsinh(expr_t iArg1) -{ - if (iArg1 != Zero) - return AddUnaryOp(oAsinh, iArg1); - else - return Zero; -} - -expr_t -DataTree::AddAtanh(expr_t iArg1) -{ - if (iArg1 != Zero) - return AddUnaryOp(oAtanh, iArg1); - else - return Zero; -} - -expr_t -DataTree::AddSqrt(expr_t iArg1) -{ - if (iArg1 != Zero) - return AddUnaryOp(oSqrt, iArg1); - else - return Zero; -} - -expr_t -DataTree::AddAbs(expr_t iArg1) -{ - if (iArg1 == Zero) - return Zero; - if (iArg1 == One) - return One; - else - return AddUnaryOp(oAbs, iArg1); -} - -expr_t -DataTree::AddSign(expr_t iArg1) -{ - if (iArg1 == Zero) - return Zero; - if (iArg1 == One) - return One; - else - return AddUnaryOp(oSign, iArg1); -} - -expr_t -DataTree::AddErf(expr_t iArg1) -{ - if (iArg1 != Zero) - return AddUnaryOp(oErf, iArg1); - else - return Zero; -} - -expr_t -DataTree::AddMax(expr_t iArg1, expr_t iArg2) -{ - return AddBinaryOp(iArg1, oMax, iArg2); -} - -expr_t -DataTree::AddMin(expr_t iArg1, expr_t iArg2) -{ - return AddBinaryOp(iArg1, oMin, iArg2); -} - -expr_t -DataTree::AddNormcdf(expr_t iArg1, expr_t iArg2, expr_t iArg3) -{ - return AddTrinaryOp(iArg1, oNormcdf, iArg2, iArg3); -} - -expr_t -DataTree::AddNormpdf(expr_t iArg1, expr_t iArg2, expr_t iArg3) -{ - return AddTrinaryOp(iArg1, oNormpdf, iArg2, iArg3); -} - -expr_t -DataTree::AddSteadyState(expr_t iArg1) -{ - return AddUnaryOp(oSteadyState, iArg1); -} - -expr_t -DataTree::AddSteadyStateParamDeriv(expr_t iArg1, int param_symb_id) -{ - return AddUnaryOp(oSteadyStateParamDeriv, iArg1, 0, param_symb_id); -} - -expr_t -DataTree::AddSteadyStateParam2ndDeriv(expr_t iArg1, int param1_symb_id, int param2_symb_id) -{ - return AddUnaryOp(oSteadyStateParam2ndDeriv, iArg1, 0, param1_symb_id, param2_symb_id); -} - -expr_t -DataTree::AddExpectation(int iArg1, expr_t iArg2) -{ - return AddUnaryOp(oExpectation, iArg2, iArg1); -} - -expr_t -DataTree::AddEqual(expr_t iArg1, expr_t iArg2) -{ - return AddBinaryOp(iArg1, oEqual, iArg2); -} - -void -DataTree::AddLocalVariable(int symb_id, expr_t value) throw (LocalVariableException) -{ - assert(symbol_table.getType(symb_id) == eModelLocalVariable); - - // Throw an exception if symbol already declared - map::iterator it = local_variables_table.find(symb_id); - if (it != local_variables_table.end()) - throw LocalVariableException(symbol_table.getName(symb_id)); - - local_variables_table[symb_id] = value; - local_variables_vector.push_back(symb_id); -} - -expr_t -DataTree::AddExternalFunction(int symb_id, const vector &arguments) -{ - assert(symbol_table.getType(symb_id) == eExternalFunction); - - external_function_node_map_t::iterator it = external_function_node_map.find(make_pair(arguments, symb_id)); - if (it != external_function_node_map.end()) - return it->second; - - return new ExternalFunctionNode(*this, symb_id, arguments); -} - -expr_t -DataTree::AddFirstDerivExternalFunction(int top_level_symb_id, const vector &arguments, int input_index) -{ - assert(symbol_table.getType(top_level_symb_id) == eExternalFunction); - - first_deriv_external_function_node_map_t::iterator it - = first_deriv_external_function_node_map.find(make_pair(make_pair(arguments, input_index), - top_level_symb_id)); - if (it != first_deriv_external_function_node_map.end()) - return it->second; - - return new FirstDerivExternalFunctionNode(*this, top_level_symb_id, arguments, input_index); -} - -expr_t -DataTree::AddSecondDerivExternalFunction(int top_level_symb_id, const vector &arguments, int input_index1, int input_index2) -{ - assert(symbol_table.getType(top_level_symb_id) == eExternalFunction); - - second_deriv_external_function_node_map_t::iterator it - = second_deriv_external_function_node_map.find(make_pair(make_pair(arguments, - make_pair(input_index1, input_index2)), - top_level_symb_id)); - if (it != second_deriv_external_function_node_map.end()) - return it->second; - - return new SecondDerivExternalFunctionNode(*this, top_level_symb_id, arguments, input_index1, input_index2); -} - -bool -DataTree::isSymbolUsed(int symb_id) const -{ - for (variable_node_map_t::const_iterator it = variable_node_map.begin(); - it != variable_node_map.end(); it++) - if (it->first.first == symb_id) - return true; - - if (local_variables_table.find(symb_id) != local_variables_table.end()) - return true; - - return false; -} - -int -DataTree::getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException) -{ - throw UnknownDerivIDException(); -} - -SymbolType -DataTree::getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException) -{ - throw UnknownDerivIDException(); -} - -int -DataTree::getLagByDerivID(int deriv_id) const throw (UnknownDerivIDException) -{ - throw UnknownDerivIDException(); -} - -int -DataTree::getSymbIDByDerivID(int deriv_id) const throw (UnknownDerivIDException) -{ - throw UnknownDerivIDException(); -} - -void -DataTree::addAllParamDerivId(set &deriv_id_set) -{ -} - -int -DataTree::getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDException) -{ - throw UnknownDerivIDException(); -} - -bool -DataTree::isUnaryOpUsed(UnaryOpcode opcode) const -{ - 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 -DataTree::isBinaryOpUsed(BinaryOpcode opcode) const -{ - for (binary_op_node_map_t::const_iterator it = binary_op_node_map.begin(); - it != binary_op_node_map.end(); it++) - if (it->first.second == opcode) - return true; - - return false; -} - -bool -DataTree::isTrinaryOpUsed(TrinaryOpcode opcode) const -{ - for (trinary_op_node_map_t::const_iterator it = trinary_op_node_map.begin(); - it != trinary_op_node_map.end(); it++) - if (it->first.second == 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(); - it != external_function_node_map.end(); it++) - if (it->first.second == symb_id) - return true; - - return false; -} - -bool -DataTree::isFirstDerivExternalFunctionUsed(int symb_id) const -{ - for (first_deriv_external_function_node_map_t::const_iterator it = first_deriv_external_function_node_map.begin(); - it != first_deriv_external_function_node_map.end(); it++) - if (it->first.second == symb_id) - return true; - - return false; -} - -bool -DataTree::isSecondDerivExternalFunctionUsed(int symb_id) const -{ - for (second_deriv_external_function_node_map_t::const_iterator it = second_deriv_external_function_node_map.begin(); - it != second_deriv_external_function_node_map.end(); it++) - if (it->first.second == symb_id) - return true; - - return false; -} - -int -DataTree::minLagForSymbol(int symb_id) const -{ - int r = 0; - for (variable_node_map_t::const_iterator it = variable_node_map.begin(); - it != variable_node_map.end(); ++it) - if (it->first.first == symb_id && it->first.second < r) - r = it->first.second; - return r; -} - -void -DataTree::writePowerDerivCHeader(ostream &output) const -{ - if (isBinaryOpUsed(oPowerDeriv)) - output << "double getPowerDeriv(double, double, int);" << 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 - << "#ifdef _MSC_VER" << endl - << "# define nearbyint(x) (fabs((x)-floor(x)) < fabs((x)-ceil(x)) ? floor(x) : ceil(x))" << endl - << "#endif" << endl - << " if ( fabs(x) < " << NEAR_ZERO << " && p > 0 && k > p && fabs(p-nearbyint(p)) < " << NEAR_ZERO << " )" << endl - << " return 0.0;" << endl - << " else" << endl - << " {" << endl - << " int i = 0;" << endl - << " double dxp = pow(x, p-k);" << endl - << " for (; i= 1700" << endl - << " return 0.5 * erfc(-x * M_SQRT1_2);" << endl - << "#else" << endl - << " // From http://www.johndcook.com/blog/cpp_phi" << endl - << " double a1 = 0.254829592;" << endl - << " double a2 = -0.284496736;" << endl - << " double a3 = 1.421413741;" << endl - << " double a4 = -1.453152027;" << endl - << " double a5 = 1.061405429;" << endl - << " 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 -} diff --git a/preprocessor/DataTree.hh b/preprocessor/DataTree.hh deleted file mode 100644 index 26a438604..000000000 --- a/preprocessor/DataTree.hh +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#ifndef _DATATREE_HH -#define _DATATREE_HH - -using namespace std; - -#include -#include -#include -#include -#include -#include - -#include "SymbolTable.hh" -#include "NumericalConstants.hh" -#include "ExternalFunctionsTable.hh" -#include "ExprNode.hh" - -#define CONSTANTS_PRECISION 16 - -class DataTree -{ - friend class ExprNode; - 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 - SymbolTable &symbol_table; - //! Reference to numerical constants table - NumericalConstants &num_constants; - //! A reference to the external functions table - ExternalFunctionsTable &external_functions_table; - - typedef map num_const_node_map_t; - num_const_node_map_t num_const_node_map; - //! Pair (symbol_id, lag) used as key - typedef map, VariableNode *> variable_node_map_t; - 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 > >, UnaryOpNode *> unary_op_node_map_t; - unary_op_node_map_t unary_op_node_map; - //! Pair( Pair( Pair(arg1, arg2), order of Power Derivative), opCode) - typedef map, int>, BinaryOpcode>, BinaryOpNode *> binary_op_node_map_t; - binary_op_node_map_t binary_op_node_map; - typedef map, expr_t>, TrinaryOpcode>, TrinaryOpNode *> trinary_op_node_map_t; - trinary_op_node_map_t trinary_op_node_map; - - // (arguments, symb_id) -> ExternalFunctionNode - typedef map, int>, ExternalFunctionNode *> external_function_node_map_t; - external_function_node_map_t external_function_node_map; - - // ((arguments, deriv_idx), symb_id) -> FirstDerivExternalFunctionNode - typedef map, int>, int>, FirstDerivExternalFunctionNode *> first_deriv_external_function_node_map_t; - first_deriv_external_function_node_map_t first_deriv_external_function_node_map; - - // ((arguments, (deriv_idx1, deriv_idx2)), symb_id) -> SecondDerivExternalFunctionNode - typedef map, pair >, int>, SecondDerivExternalFunctionNode *> second_deriv_external_function_node_map_t; - second_deriv_external_function_node_map_t second_deriv_external_function_node_map; - - //! Stores local variables value (maps symbol ID to corresponding node) - map local_variables_table; - //! Stores the order of appearance of local variables in the model block. Needed following change in #563 - vector local_variables_vector; - - //! Internal implementation of AddVariable(), without the check on the lag - VariableNode *AddVariableInternal(int symb_id, int lag); - - //! Internal implementation of ParamUsedWithLeadLag() - bool ParamUsedWithLeadLagInternal() const; -private: - typedef list node_list_t; - //! 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); - 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); - 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); - -public: - DataTree(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_arg); - virtual - ~DataTree(); - - //! Some predefined constants - expr_t Zero, One, Two, MinusOne, NaN, Infinity, MinusInfinity, Pi; - - //! Raised when a local parameter is declared twice - class LocalVariableException - { - public: - string name; - LocalVariableException(const string &name_arg) : name(name_arg) - { - } - }; - - class DivisionByZeroException - { - }; - - //! Adds a non-negative numerical constant (possibly Inf or NaN) - expr_t AddNonNegativeConstant(const string &value); - //! Adds a variable - /*! The default implementation of the method refuses any lag != 0 */ - virtual VariableNode *AddVariable(int symb_id, int lag = 0); - //! Adds "arg1+arg2" to model tree - expr_t AddPlus(expr_t iArg1, expr_t iArg2); - //! Adds "arg1-arg2" to model tree - expr_t AddMinus(expr_t iArg1, expr_t iArg2); - //! Adds "-arg" to model tree - expr_t AddUMinus(expr_t iArg1); - //! Adds "arg1*arg2" to model tree - expr_t AddTimes(expr_t iArg1, expr_t iArg2); - //! Adds "arg1/arg2" to model tree - expr_t AddDivide(expr_t iArg1, expr_t iArg2) throw (DivisionByZeroException); - //! Adds "arg1arg2" to model tree - expr_t AddGreater(expr_t iArg1, expr_t iArg2); - //! Adds "arg1<=arg2" to model tree - expr_t AddLessEqual(expr_t iArg1, expr_t iArg2); - //! Adds "arg1>=arg2" to model tree - expr_t AddGreaterEqual(expr_t iArg1, expr_t iArg2); - //! Adds "arg1==arg2" to model tree - expr_t AddEqualEqual(expr_t iArg1, expr_t iArg2); - //! Adds "arg1!=arg2" to model tree - expr_t AddDifferent(expr_t iArg1, expr_t iArg2); - //! Adds "arg1^arg2" to model tree - expr_t AddPower(expr_t iArg1, expr_t iArg2); - //! Adds "getPowerDeriv(arg1, arg2, powerDerivOrder)" to model tree - expr_t AddPowerDeriv(expr_t iArg1, expr_t iArg2, int powerDerivOrder); - //! Adds "E(arg1)(arg2)" to model tree - expr_t AddExpectation(int iArg1, expr_t iArg2); - //! Adds "exp(arg)" to model tree - expr_t AddExp(expr_t iArg1); - //! Adds "log(arg)" to model tree - expr_t AddLog(expr_t iArg1); - //! Adds "log10(arg)" to model tree - expr_t AddLog10(expr_t iArg1); - //! Adds "cos(arg)" to model tree - expr_t AddCos(expr_t iArg1); - //! Adds "sin(arg)" to model tree - expr_t AddSin(expr_t iArg1); - //! Adds "tan(arg)" to model tree - expr_t AddTan(expr_t iArg1); - //! Adds "acos(arg)" to model tree - expr_t AddAcos(expr_t iArg1); - //! Adds "asin(arg)" to model tree - expr_t AddAsin(expr_t iArg1); - //! Adds "atan(arg)" to model tree - expr_t AddAtan(expr_t iArg1); - //! Adds "cosh(arg)" to model tree - expr_t AddCosh(expr_t iArg1); - //! Adds "sinh(arg)" to model tree - expr_t AddSinh(expr_t iArg1); - //! Adds "tanh(arg)" to model tree - expr_t AddTanh(expr_t iArg1); - //! Adds "acosh(arg)" to model tree - expr_t AddAcosh(expr_t iArg1); - //! Adds "asinh(arg)" to model tree - expr_t AddAsinh(expr_t iArg1); - //! Adds "atanh(args)" to model tree - expr_t AddAtanh(expr_t iArg1); - //! Adds "sqrt(arg)" to model tree - expr_t AddSqrt(expr_t iArg1); - //! Adds "abs(arg)" to model tree - expr_t AddAbs(expr_t iArg1); - //! Adds "sign(arg)" to model tree - expr_t AddSign(expr_t iArg1); - //! Adds "erf(arg)" to model tree - expr_t AddErf(expr_t iArg1); - //! Adds "max(arg1,arg2)" to model tree - expr_t AddMax(expr_t iArg1, expr_t iArg2); - //! Adds "min(arg1,arg2)" to model tree - expr_t AddMin(expr_t iArg1, expr_t iArg2); - //! Adds "normcdf(arg1,arg2,arg3)" to model tree - expr_t AddNormcdf(expr_t iArg1, expr_t iArg2, expr_t iArg3); - //! Adds "normpdf(arg1,arg2,arg3)" to model tree - expr_t AddNormpdf(expr_t iArg1, expr_t iArg2, expr_t iArg3); - //! Adds "steadyState(arg)" to model tree - expr_t AddSteadyState(expr_t iArg1); - //! Add derivative of steady state w.r.t. parameter to model tree - expr_t AddSteadyStateParamDeriv(expr_t iArg1, int param_symb_id); - //! Add 2nd derivative of steady state w.r.t. parameter to model tree - expr_t AddSteadyStateParam2ndDeriv(expr_t iArg1, int param1_symb_id, int param2_symb_id); - //! Adds "arg1=arg2" to model tree - expr_t AddEqual(expr_t iArg1, expr_t iArg2); - //! Adds a model local variable with its value - void AddLocalVariable(int symb_id, expr_t value) throw (LocalVariableException); - //! Adds an external function node - expr_t AddExternalFunction(int symb_id, const vector &arguments); - //! Adds an external function node for the first derivative of an external function - expr_t AddFirstDerivExternalFunction(int top_level_symb_id, const vector &arguments, int input_index); - //! Adds an external function node for the second derivative of an external function - expr_t AddSecondDerivExternalFunction(int top_level_symb_id, const vector &arguments, int input_index1, int input_index2); - //! Checks if a given symbol is used somewhere in the data tree - bool isSymbolUsed(int symb_id) const; - //! Checks if a given unary op is used somewhere in the data tree - bool isUnaryOpUsed(UnaryOpcode opcode) const; - //! Checks if a given binary op is used somewhere in the data tree - bool isBinaryOpUsed(BinaryOpcode opcode) const; - //! Checks if a given trinary op is used somewhere in the data tree - bool isTrinaryOpUsed(TrinaryOpcode opcode) const; - //! Checks if a given external function is used somewhere in the data tree - bool isExternalFunctionUsed(int symb_id) const; - //! 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 */ - int minLagForSymbol(int symb_id) const; - //! Write the C Header for getPowerDeriv when use_dll is used - void writePowerDerivCHeader(ostream &output) const; - //! Write getPowerDeriv in C - void writePowerDeriv(ostream &output) const; - //! Write the C Header for normcdf when use_dll is used - void writeNormcdfCHeader(ostream &output) const; - //! Write normcdf in C - void writeNormcdf(ostream &output) const; - //! Thrown when trying to access an unknown variable by deriv_id - class UnknownDerivIDException - { - }; - - //! Raised when a trend is declared twice - class TrendException - { - public: - 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 - 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 - virtual void addAllParamDerivId(set &deriv_id_set); - - //! Returns bool indicating whether DataTree represents a Dynamic Model (returns true in DynamicModel.hh) - virtual bool - isDynamic() const - { - return false; - }; -}; - -inline expr_t -DataTree::AddPossiblyNegativeConstant(double v) -{ - /* Treat NaN and Inf separately. In particular, under Windows, converting - them to a string does not work as expected */ - if (isnan(v)) - return NaN; - if (isinf(v)) - return (v < 0 ? MinusInfinity : Infinity); - - bool neg = false; - if (v < 0) - { - v = -v; - neg = true; - } - ostringstream ost; - ost << setprecision(CONSTANTS_PRECISION) << v; - - expr_t cnode = AddNonNegativeConstant(ost.str()); - - if (neg) - return AddUMinus(cnode); - else - return cnode; -} - -inline expr_t -DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int param1_symb_id, int param2_symb_id) -{ - // 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 (it != unary_op_node_map.end()) - return it->second; - - // 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 - NumConstNode *carg = dynamic_cast(arg); - if (op_code != oUminus || carg == NULL) - { - try - { - double argval = arg->eval(eval_context_t()); - double val = UnaryOpNode::eval_opcode(op_code, argval); - return AddPossiblyNegativeConstant(val); - } - catch (ExprNode::EvalException &e) - { - } - } - return new UnaryOpNode(*this, op_code, arg, arg_exp_info_set, param1_symb_id, param2_symb_id); -} - -inline expr_t -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 (it != binary_op_node_map.end()) - return it->second; - - // Try to reduce to a constant - try - { - double argval1 = arg1->eval(eval_context_t()); - double argval2 = arg2->eval(eval_context_t()); - double val = BinaryOpNode::eval_opcode(argval1, op_code, argval2, powerDerivOrder); - return AddPossiblyNegativeConstant(val); - } - catch (ExprNode::EvalException &e) - { - } - return new BinaryOpNode(*this, arg1, op_code, arg2, powerDerivOrder); -} - -inline expr_t -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 (it != trinary_op_node_map.end()) - return it->second; - - // Try to reduce to a constant - try - { - double argval1 = arg1->eval(eval_context_t()); - double argval2 = arg2->eval(eval_context_t()); - double argval3 = arg3->eval(eval_context_t()); - double val = TrinaryOpNode::eval_opcode(argval1, op_code, argval2, argval3); - return AddPossiblyNegativeConstant(val); - } - catch (ExprNode::EvalException &e) - { - } - return new TrinaryOpNode(*this, arg1, op_code, arg2, arg3); -} - -#endif diff --git a/preprocessor/Doxyfile b/preprocessor/Doxyfile deleted file mode 100644 index 4b0f13f0f..000000000 --- a/preprocessor/Doxyfile +++ /dev/null @@ -1,1514 +0,0 @@ -# Doxyfile 1.5.9 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = "Dynare Pre-Processor" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = " Version 4" - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = doc - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it parses. -# With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this tag. -# The format is ext=language, where ext is a file extension, and language is one of -# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, -# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat -# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = YES - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by -# doxygen. The layout file controls the global structure of the generated output files -# in an output format independent way. The create the layout file that represents -# doxygen's defaults, run doxygen with the -l option. You can optionally specify a -# file name after the option, if omitted DoxygenLayout.xml will be used as the name -# of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text " - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER -# are set, an additional index file will be generated that can be used as input for -# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated -# HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. -# For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's -# filter section matches. -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to FRAME, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. Other possible values -# for this tag are: HIERARCHIES, which will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list; -# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which -# disables this behavior completely. For backwards compatibility with previous -# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE -# respectively. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = FreeSans - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Options related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc deleted file mode 100644 index 49d58ba2d..000000000 --- a/preprocessor/DynamicModel.cc +++ /dev/null @@ -1,6077 +0,0 @@ -/* - * Copyright (C) 2003-2018 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "DynamicModel.hh" - -// For mkdir() and chdir() -#ifdef _WIN32 -# include -#else -# include -# include -# include -#endif - -DynamicModel::DynamicModel(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg) : - ModelTree(symbol_table_arg, num_constants_arg, external_functions_table_arg), - max_lag(0), max_lead(0), - max_endo_lag(0), max_endo_lead(0), - max_exo_lag(0), max_exo_lead(0), - max_exo_det_lag(0), max_exo_det_lead(0), - max_lag_orig(0), max_lead_orig(0), - max_endo_lag_orig(0), max_endo_lead_orig(0), - max_exo_lag_orig(0), max_exo_lead_orig(0), - max_exo_det_lag_orig(0), max_exo_det_lead_orig(0), - dynJacobianColsNbr(0), - global_temporary_terms(true) -{ -} - -VariableNode * -DynamicModel::AddVariable(int symb_id, int lag) -{ - return AddVariableInternal(symb_id, lag); -} - -void -DynamicModel::compileDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int symb_id, int lag, const map_idx_t &map_idx) const -{ - first_derivatives_t::const_iterator it = first_derivatives.find(make_pair(eq, getDerivID(symbol_table.getID(eEndogenous, symb_id), lag))); - if (it != first_derivatives.end()) - (it->second)->compile(code_file, instruction_number, false, temporary_terms, map_idx, true, false); - else - { - FLDZ_ fldz; - fldz.write(code_file, instruction_number); - } -} - -void -DynamicModel::compileChainRuleDerivative(ofstream &code_file, unsigned int &instruction_number, int eqr, int varr, int lag, const map_idx_t &map_idx) const -{ - map >, expr_t>::const_iterator it = first_chain_rule_derivatives.find(make_pair(eqr, make_pair(varr, lag))); - if (it != first_chain_rule_derivatives.end()) - (it->second)->compile(code_file, instruction_number, false, temporary_terms, map_idx, true, false); - else - { - FLDZ_ fldz; - fldz.write(code_file, instruction_number); - } -} - -void -DynamicModel::computeTemporaryTermsOrdered() -{ - map > first_occurence; - map reference_count; - BinaryOpNode *eq_node; - first_derivatives_t::const_iterator it; - first_chain_rule_derivatives_t::const_iterator it_chr; - ostringstream tmp_s; - v_temporary_terms.clear(); - map_idx.clear(); - - unsigned int nb_blocks = getNbBlocks(); - v_temporary_terms = vector >(nb_blocks); - v_temporary_terms_inuse = vector(nb_blocks); - temporary_terms.clear(); - - if (!global_temporary_terms) - { - for (unsigned int block = 0; block < nb_blocks; block++) - { - reference_count.clear(); - temporary_terms.clear(); - unsigned int block_size = getBlockSize(block); - unsigned int block_nb_mfs = getBlockMfs(block); - unsigned int block_nb_recursives = block_size - block_nb_mfs; - v_temporary_terms[block] = vector(block_size); - for (unsigned int i = 0; i < block_size; i++) - { - if (i < block_nb_recursives && isBlockEquationRenormalized(block, i)) - getBlockEquationRenormalizedExpr(block, i)->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, i); - else - { - eq_node = (BinaryOpNode *) getBlockEquationExpr(block, i); - eq_node->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, i); - } - } - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - { - expr_t id = it->second.second; - id->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, block_size-1); - } - for (derivative_t::const_iterator it = derivative_endo[block].begin(); it != derivative_endo[block].end(); it++) - it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, block_size-1); - for (derivative_t::const_iterator it = derivative_other_endo[block].begin(); it != derivative_other_endo[block].end(); it++) - it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, block_size-1); - set temporary_terms_in_use; - temporary_terms_in_use.clear(); - v_temporary_terms_inuse[block] = temporary_terms_in_use; - } - } - else - { - for (unsigned int block = 0; block < nb_blocks; block++) - { - // Compute the temporary terms reordered - unsigned int block_size = getBlockSize(block); - unsigned int block_nb_mfs = getBlockMfs(block); - unsigned int block_nb_recursives = block_size - block_nb_mfs; - v_temporary_terms[block] = vector(block_size); - for (unsigned int i = 0; i < block_size; i++) - { - if (i < block_nb_recursives && isBlockEquationRenormalized(block, i)) - getBlockEquationRenormalizedExpr(block, i)->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, i); - else - { - eq_node = (BinaryOpNode *) getBlockEquationExpr(block, i); - eq_node->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, i); - } - } - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - { - expr_t id = it->second.second; - id->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, block_size-1); - } - for (derivative_t::const_iterator it = derivative_endo[block].begin(); it != derivative_endo[block].end(); it++) - it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, block_size-1); - for (derivative_t::const_iterator it = derivative_other_endo[block].begin(); it != derivative_other_endo[block].end(); it++) - it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, block_size-1); - } - for (unsigned int block = 0; block < nb_blocks; block++) - { - // Collect the temporary terms reordered - unsigned int block_size = getBlockSize(block); - unsigned int block_nb_mfs = getBlockMfs(block); - unsigned int block_nb_recursives = block_size - block_nb_mfs; - set temporary_terms_in_use; - for (unsigned int i = 0; i < block_size; i++) - { - if (i < block_nb_recursives && isBlockEquationRenormalized(block, i)) - getBlockEquationRenormalizedExpr(block, i)->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block); - else - { - eq_node = (BinaryOpNode *) getBlockEquationExpr(block, i); - eq_node->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block); - } - } - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - { - expr_t id = it->second.second; - id->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block); - } - for (derivative_t::const_iterator it = derivative_endo[block].begin(); it != derivative_endo[block].end(); it++) - it->second->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block); - for (derivative_t::const_iterator it = derivative_other_endo[block].begin(); it != derivative_other_endo[block].end(); it++) - it->second->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block); - for (derivative_t::const_iterator it = derivative_exo[block].begin(); it != derivative_exo[block].end(); it++) - it->second->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block); - for (derivative_t::const_iterator it = derivative_exo_det[block].begin(); it != derivative_exo_det[block].end(); it++) - it->second->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block); - v_temporary_terms_inuse[block] = temporary_terms_in_use; - } - computeTemporaryTermsMapping(); - } -} - -void -DynamicModel::computeTemporaryTermsMapping() -{ - // Add a mapping form node ID to temporary terms order - int j = 0; - for (temporary_terms_t::const_iterator it = temporary_terms.begin(); - it != temporary_terms.end(); it++) - map_idx[(*it)->idx] = j++; -} - -void -DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const -{ - string tmp_s, sps; - ostringstream tmp_output, tmp1_output, global_output; - expr_t lhs = NULL, rhs = NULL; - BinaryOpNode *eq_node; - ostringstream Ufoss; - vector Uf(symbol_table.endo_nbr(), ""); - map reference_count; - temporary_terms_t local_temporary_terms; - ofstream output; - int nze, nze_exo, nze_exo_det, nze_other_endo; - vector feedback_variables; - ExprNodeOutputType local_output_type; - Ufoss.str(""); - - local_output_type = oMatlabDynamicModelSparse; - if (global_temporary_terms) - local_temporary_terms = temporary_terms; - - //---------------------------------------------------------------------- - //For each block - for (unsigned int block = 0; block < getNbBlocks(); block++) - { - - //recursive_variables.clear(); - feedback_variables.clear(); - //For a block composed of a single equation determines wether we have to evaluate or to solve the equation - nze = derivative_endo[block].size(); - nze_other_endo = derivative_other_endo[block].size(); - nze_exo = derivative_exo[block].size(); - nze_exo_det = derivative_exo_det[block].size(); - BlockSimulationType simulation_type = getBlockSimulationType(block); - unsigned int block_size = getBlockSize(block); - unsigned int block_mfs = getBlockMfs(block); - unsigned int block_recursive = block_size - block_mfs; - deriv_node_temp_terms_t tef_terms; - local_output_type = oMatlabDynamicModelSparse; - if (global_temporary_terms) - local_temporary_terms = temporary_terms; - - int prev_lag; - unsigned int prev_var, count_col, count_col_endo, count_col_exo, count_col_exo_det, count_col_other_endo; - map >, expr_t> tmp_block_endo_derivative; - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - tmp_block_endo_derivative[make_pair(it->second.first, make_pair(it->first.second, it->first.first))] = it->second.second; - prev_var = 999999999; - prev_lag = -9999999; - count_col_endo = 0; - for (map >, expr_t>::const_iterator it = tmp_block_endo_derivative.begin(); it != tmp_block_endo_derivative.end(); it++) - { - int lag = it->first.first; - unsigned int var = it->first.second.first; - if (var != prev_var || lag != prev_lag) - { - prev_var = var; - prev_lag = lag; - count_col_endo++; - } - } - map >, expr_t> tmp_block_exo_derivative; - for (derivative_t::const_iterator it = derivative_exo[block].begin(); it != (derivative_exo[block]).end(); it++) - tmp_block_exo_derivative[make_pair(it->first.first, make_pair(it->first.second.second, it->first.second.first))] = it->second; - prev_var = 999999999; - prev_lag = -9999999; - count_col_exo = 0; - for (map >, expr_t>::const_iterator it = tmp_block_exo_derivative.begin(); it != tmp_block_exo_derivative.end(); it++) - { - int lag = it->first.first; - unsigned int var = it->first.second.first; - if (var != prev_var || lag != prev_lag) - { - prev_var = var; - prev_lag = lag; - count_col_exo++; - } - } - map >, expr_t> tmp_block_exo_det_derivative; - for (derivative_t::const_iterator it = derivative_exo_det[block].begin(); it != (derivative_exo_det[block]).end(); it++) - tmp_block_exo_det_derivative[make_pair(it->first.first, make_pair(it->first.second.second, it->first.second.first))] = it->second; - prev_var = 999999999; - prev_lag = -9999999; - count_col_exo_det = 0; - for (map >, expr_t>::const_iterator it = tmp_block_exo_derivative.begin(); it != tmp_block_exo_derivative.end(); it++) - { - int lag = it->first.first; - unsigned int var = it->first.second.first; - if (var != prev_var || lag != prev_lag) - { - prev_var = var; - prev_lag = lag; - count_col_exo_det++; - } - } - map >, expr_t> tmp_block_other_endo_derivative; - for (derivative_t::const_iterator it = derivative_other_endo[block].begin(); it != (derivative_other_endo[block]).end(); it++) - tmp_block_other_endo_derivative[make_pair(it->first.first, make_pair(it->first.second.second, it->first.second.first))] = it->second; - prev_var = 999999999; - prev_lag = -9999999; - count_col_other_endo = 0; - for (map >, expr_t>::const_iterator it = tmp_block_other_endo_derivative.begin(); it != tmp_block_other_endo_derivative.end(); it++) - { - int lag = it->first.first; - unsigned int var = it->first.second.first; - if (var != prev_var || lag != prev_lag) - { - prev_var = var; - prev_lag = lag; - count_col_other_endo++; - } - } - - tmp1_output.str(""); - tmp1_output << dynamic_basename << "_" << block+1 << ".m"; - output.open(tmp1_output.str().c_str(), ios::out | ios::binary); - output << "%\n"; - output << "% " << tmp1_output.str() << " : Computes dynamic model for Dynare\n"; - output << "%\n"; - output << "% Warning : this file is generated automatically by Dynare\n"; - output << "% from model file (.mod)\n\n"; - output << "%/\n"; - if (simulation_type == EVALUATE_BACKWARD || simulation_type == EVALUATE_FORWARD) - { - output << "function [y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << block+1 << "(y, x, params, steady_state, jacobian_eval, y_kmin, periods)\n"; - } - else if (simulation_type == SOLVE_FORWARD_COMPLETE || simulation_type == SOLVE_BACKWARD_COMPLETE) - output << "function [residual, y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << block+1 << "(y, x, params, steady_state, it_, jacobian_eval)\n"; - else if (simulation_type == SOLVE_BACKWARD_SIMPLE || simulation_type == SOLVE_FORWARD_SIMPLE) - output << "function [residual, y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << block+1 << "(y, x, params, steady_state, it_, jacobian_eval)\n"; - else - output << "function [residual, y, g1, g2, g3, b, varargout] = " << dynamic_basename << "_" << block+1 << "(y, x, params, steady_state, periods, jacobian_eval, y_kmin, y_size, Periods)\n"; - BlockType block_type; - if (simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE) - block_type = SIMULTAN; - else if (simulation_type == SOLVE_FORWARD_COMPLETE || simulation_type == SOLVE_BACKWARD_COMPLETE) - block_type = SIMULTANS; - else if ((simulation_type == SOLVE_FORWARD_SIMPLE || simulation_type == SOLVE_BACKWARD_SIMPLE - || simulation_type == EVALUATE_BACKWARD || simulation_type == EVALUATE_FORWARD) - && getBlockFirstEquation(block) < prologue) - block_type = PROLOGUE; - else if ((simulation_type == SOLVE_FORWARD_SIMPLE || simulation_type == SOLVE_BACKWARD_SIMPLE - || simulation_type == EVALUATE_BACKWARD || simulation_type == EVALUATE_FORWARD) - && getBlockFirstEquation(block) >= equations.size() - epilogue) - block_type = EPILOGUE; - else - block_type = SIMULTANS; - output << " % ////////////////////////////////////////////////////////////////////////" << endl - << " % //" << string(" Block ").substr(int (log10(block + 1))) << block + 1 << " " << BlockType0(block_type) - << " //" << endl - << " % // Simulation type " - << BlockSim(simulation_type) << " //" << endl - << " % ////////////////////////////////////////////////////////////////////////" << endl; - //The Temporary terms - if (simulation_type == EVALUATE_BACKWARD || simulation_type == EVALUATE_FORWARD) - { - output << " if(jacobian_eval)\n"; - output << " g1 = spalloc(" << block_mfs << ", " << count_col_endo << ", " << nze << ");\n"; - output << " g1_x=spalloc(" << block_size << ", " << count_col_exo << ", " << nze_exo << ");\n"; - output << " g1_xd=spalloc(" << block_size << ", " << count_col_exo_det << ", " << nze_exo_det << ");\n"; - output << " g1_o=spalloc(" << block_size << ", " << count_col_other_endo << ", " << nze_other_endo << ");\n"; - output << " end;\n"; - } - else - { - output << " if(jacobian_eval)\n"; - output << " g1 = spalloc(" << block_size << ", " << count_col_endo << ", " << nze << ");\n"; - output << " g1_x=spalloc(" << block_size << ", " << count_col_exo << ", " << nze_exo << ");\n"; - output << " g1_xd=spalloc(" << block_size << ", " << count_col_exo_det << ", " << nze_exo_det << ");\n"; - output << " g1_o=spalloc(" << block_size << ", " << count_col_other_endo << ", " << nze_other_endo << ");\n"; - output << " else\n"; - if (simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE) - { - output << " g1 = spalloc(" << block_mfs << "*Periods, " - << block_mfs << "*(Periods+" << max_leadlag_block[block].first+max_leadlag_block[block].second+1 << ")" - << ", " << nze << "*Periods);\n"; - } - else - { - output << " g1 = spalloc(" << block_mfs - << ", " << block_mfs << ", " << nze << ");\n"; - } - output << " end;\n"; - } - - output << " g2=0;g3=0;\n"; - if (v_temporary_terms_inuse[block].size()) - { - tmp_output.str(""); - for (temporary_terms_inuse_t::const_iterator it = v_temporary_terms_inuse[block].begin(); - it != v_temporary_terms_inuse[block].end(); it++) - tmp_output << " T" << *it; - output << " global" << tmp_output.str() << ";\n"; - } - if (simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE) - { - temporary_terms_t tt2; - tt2.clear(); - for (int i = 0; i < (int) block_size; i++) - { - if (v_temporary_terms[block][i].size() && global_temporary_terms) - { - output << " " << "% //Temporary variables initialization" << endl - << " " << "T_zeros = zeros(y_kmin+periods, 1);" << endl; - for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin(); - it != v_temporary_terms[block][i].end(); it++) - { - output << " "; - (*it)->writeOutput(output, oMatlabDynamicModel, local_temporary_terms); - output << " = T_zeros;" << endl; - } - } - } - } - if (simulation_type == SOLVE_BACKWARD_SIMPLE || simulation_type == SOLVE_FORWARD_SIMPLE || simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_FORWARD_COMPLETE) - output << " residual=zeros(" << block_mfs << ",1);\n"; - else if (simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE) - output << " residual=zeros(" << block_mfs << ",y_kmin+periods);\n"; - if (simulation_type == EVALUATE_BACKWARD) - output << " for it_ = (y_kmin+periods):y_kmin+1\n"; - if (simulation_type == EVALUATE_FORWARD) - output << " for it_ = y_kmin+1:(y_kmin+periods)\n"; - - if (simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE) - { - output << " b = zeros(periods*y_size,1);" << endl - << " for it_ = y_kmin+1:(periods+y_kmin)" << endl - << " Per_y_=it_*y_size;" << endl - << " Per_J_=(it_-y_kmin-1)*y_size;" << endl - << " Per_K_=(it_-1)*y_size;" << endl; - sps = " "; - } - else - if (simulation_type == EVALUATE_BACKWARD || simulation_type == EVALUATE_FORWARD) - sps = " "; - else - sps = ""; - // The equations - for (unsigned int i = 0; i < block_size; i++) - { - temporary_terms_t tt2; - tt2.clear(); - if (v_temporary_terms[block].size()) - { - output << " " << "% //Temporary variables" << endl; - for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin(); - it != v_temporary_terms[block][i].end(); it++) - { - if (dynamic_cast(*it) != NULL) - (*it)->writeExternalFunctionOutput(output, local_output_type, tt2, tef_terms); - - output << " " << sps; - (*it)->writeOutput(output, local_output_type, local_temporary_terms, tef_terms); - output << " = "; - (*it)->writeOutput(output, local_output_type, tt2, tef_terms); - // Insert current node into tt2 - tt2.insert(*it); - output << ";" << endl; - } - } - - int variable_ID = getBlockVariableID(block, i); - int equation_ID = getBlockEquationID(block, i); - EquationType equ_type = getBlockEquationType(block, i); - string sModel = symbol_table.getName(symbol_table.getID(eEndogenous, variable_ID)); - eq_node = (BinaryOpNode *) getBlockEquationExpr(block, i); - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - tmp_output.str(""); - lhs->writeOutput(tmp_output, local_output_type, local_temporary_terms); - switch (simulation_type) - { - case EVALUATE_BACKWARD: - case EVALUATE_FORWARD: - evaluation: if (simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE) - output << " % equation " << getBlockEquationID(block, i)+1 << " variable : " << sModel - << " (" << variable_ID+1 << ") " << c_Equation_Type(equ_type) << endl; - output << " "; - if (equ_type == E_EVALUATE) - { - output << tmp_output.str(); - output << " = "; - rhs->writeOutput(output, local_output_type, local_temporary_terms); - } - else if (equ_type == E_EVALUATE_S) - { - output << "%" << tmp_output.str(); - output << " = "; - if (isBlockEquationRenormalized(block, i)) - { - rhs->writeOutput(output, local_output_type, local_temporary_terms); - output << "\n "; - tmp_output.str(""); - eq_node = (BinaryOpNode *) getBlockEquationRenormalizedExpr(block, i); - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - lhs->writeOutput(output, local_output_type, local_temporary_terms); - output << " = "; - rhs->writeOutput(output, local_output_type, local_temporary_terms); - } - } - else - { - cerr << "Type mismatch for equation " << equation_ID+1 << "\n"; - exit(EXIT_FAILURE); - } - output << ";\n"; - break; - case SOLVE_BACKWARD_SIMPLE: - case SOLVE_FORWARD_SIMPLE: - case SOLVE_BACKWARD_COMPLETE: - case SOLVE_FORWARD_COMPLETE: - if (i < block_recursive) - goto evaluation; - feedback_variables.push_back(variable_ID); - output << " % equation " << equation_ID+1 << " variable : " << sModel - << " (" << variable_ID+1 << ") " << c_Equation_Type(equ_type) << " symb_id=" << symbol_table.getID(eEndogenous, variable_ID) << endl; - output << " " << "residual(" << i+1-block_recursive << ") = ("; - goto end; - case SOLVE_TWO_BOUNDARIES_COMPLETE: - case SOLVE_TWO_BOUNDARIES_SIMPLE: - if (i < block_recursive) - goto evaluation; - feedback_variables.push_back(variable_ID); - output << " % equation " << equation_ID+1 << " variable : " << sModel - << " (" << variable_ID+1 << ") " << c_Equation_Type(equ_type) << " symb_id=" << symbol_table.getID(eEndogenous, variable_ID) << endl; - Ufoss << " b(" << i+1-block_recursive << "+Per_J_) = -residual(" << i+1-block_recursive << ", it_)"; - Uf[equation_ID] += Ufoss.str(); - Ufoss.str(""); - output << " residual(" << i+1-block_recursive << ", it_) = ("; - goto end; - default: - end: - output << tmp_output.str(); - output << ") - ("; - rhs->writeOutput(output, local_output_type, local_temporary_terms); - output << ");\n"; -#ifdef CONDITION - if (simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE) - output << " condition(" << i+1 << ")=0;\n"; -#endif - } - } - // The Jacobian if we have to solve the block - if (simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE || simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE) - output << " " << sps << "% Jacobian " << endl << " if jacobian_eval" << endl; - else - if (simulation_type == SOLVE_BACKWARD_SIMPLE || simulation_type == SOLVE_FORWARD_SIMPLE - || simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_FORWARD_COMPLETE) - output << " % Jacobian " << endl << " if jacobian_eval" << endl; - else - output << " % Jacobian " << endl << " if jacobian_eval" << endl; - prev_var = 999999999; - prev_lag = -9999999; - count_col = 0; - for (map >, expr_t>::const_iterator it = tmp_block_endo_derivative.begin(); it != tmp_block_endo_derivative.end(); it++) - { - int lag = it->first.first; - unsigned int var = it->first.second.first; - unsigned int eq = it->first.second.second; - int eqr = getBlockEquationID(block, eq); - int varr = getBlockVariableID(block, var); - if (var != prev_var || lag != prev_lag) - { - prev_var = var; - prev_lag = lag; - count_col++; - } - - expr_t id = it->second; - - output << " g1(" << eq+1 << ", " << count_col << ") = "; - id->writeOutput(output, local_output_type, local_temporary_terms); - output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr)) - << "(" << lag - << ") " << varr+1 << ", " << var+1 - << ", equation=" << eqr+1 << ", " << eq+1 << endl; - } - prev_var = 999999999; - prev_lag = -9999999; - count_col = 0; - for (map >, expr_t>::const_iterator it = tmp_block_exo_derivative.begin(); it != tmp_block_exo_derivative.end(); it++) - { - int lag = it->first.first; - unsigned int var = it->first.second.first; - unsigned int eq = it->first.second.second; - int eqr = getBlockInitialEquationID(block, eq); - if (var != prev_var || lag != prev_lag) - { - prev_var = var; - prev_lag = lag; - count_col++; - } - expr_t id = it->second; - output << " g1_x(" << eqr+1 << ", " << count_col << ") = "; - id->writeOutput(output, local_output_type, local_temporary_terms); - output << "; % variable=" << symbol_table.getName(symbol_table.getID(eExogenous, var)) - << "(" << lag - << ") " << var+1 - << ", equation=" << eq+1 << endl; - } - prev_var = 999999999; - prev_lag = -9999999; - count_col = 0; - for (map >, expr_t>::const_iterator it = tmp_block_exo_det_derivative.begin(); it != tmp_block_exo_det_derivative.end(); it++) - { - int lag = it->first.first; - unsigned int var = it->first.second.first; - unsigned int eq = it->first.second.second; - int eqr = getBlockInitialEquationID(block, eq); - if (var != prev_var || lag != prev_lag) - { - prev_var = var; - prev_lag = lag; - count_col++; - } - expr_t id = it->second; - output << " g1_xd(" << eqr+1 << ", " << count_col << ") = "; - id->writeOutput(output, local_output_type, local_temporary_terms); - output << "; % variable=" << symbol_table.getName(symbol_table.getID(eExogenous, var)) - << "(" << lag - << ") " << var+1 - << ", equation=" << eq+1 << endl; - } - prev_var = 999999999; - prev_lag = -9999999; - count_col = 0; - for (map >, expr_t>::const_iterator it = tmp_block_other_endo_derivative.begin(); it != tmp_block_other_endo_derivative.end(); it++) - { - int lag = it->first.first; - unsigned int var = it->first.second.first; - unsigned int eq = it->first.second.second; - int eqr = getBlockInitialEquationID(block, eq); - if (var != prev_var || lag != prev_lag) - { - prev_var = var; - prev_lag = lag; - count_col++; - } - expr_t id = it->second; - - output << " g1_o(" << eqr+1 << ", " << /*var+1+(lag+block_max_lag)*block_size*/ count_col << ") = "; - id->writeOutput(output, local_output_type, local_temporary_terms); - output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var)) - << "(" << lag - << ") " << var+1 - << ", equation=" << eq+1 << endl; - } - output << " varargout{1}=g1_x;\n"; - output << " varargout{2}=g1_xd;\n"; - output << " varargout{3}=g1_o;\n"; - - switch (simulation_type) - { - case EVALUATE_FORWARD: - case EVALUATE_BACKWARD: - output << " end;" << endl; - output << " end;" << endl; - break; - case SOLVE_BACKWARD_SIMPLE: - case SOLVE_FORWARD_SIMPLE: - case SOLVE_BACKWARD_COMPLETE: - case SOLVE_FORWARD_COMPLETE: - output << " else" << endl; - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - { - unsigned int eq = it->first.first; - unsigned int var = it->first.second; - unsigned int eqr = getBlockEquationID(block, eq); - unsigned int varr = getBlockVariableID(block, var); - expr_t id = it->second.second; - int lag = it->second.first; - if (lag == 0) - { - output << " g1(" << eq+1 << ", " << var+1-block_recursive << ") = "; - id->writeOutput(output, local_output_type, local_temporary_terms); - output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr)) - << "(" << lag - << ") " << varr+1 - << ", equation=" << eqr+1 << endl; - } - - } - output << " end;\n"; - break; - case SOLVE_TWO_BOUNDARIES_SIMPLE: - case SOLVE_TWO_BOUNDARIES_COMPLETE: - output << " else" << endl; - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - { - unsigned int eq = it->first.first; - unsigned int var = it->first.second; - unsigned int eqr = getBlockEquationID(block, eq); - unsigned int varr = getBlockVariableID(block, var); - ostringstream tmp_output; - expr_t id = it->second.second; - int lag = it->second.first; - if (eq >= block_recursive && var >= block_recursive) - { - if (lag == 0) - Ufoss << "+g1(" << eq+1-block_recursive - << "+Per_J_, " << var+1-block_recursive - << "+Per_K_)*y(it_, " << varr+1 << ")"; - else if (lag == 1) - Ufoss << "+g1(" << eq+1-block_recursive - << "+Per_J_, " << var+1-block_recursive - << "+Per_y_)*y(it_+1, " << varr+1 << ")"; - else if (lag > 0) - Ufoss << "+g1(" << eq+1-block_recursive - << "+Per_J_, " << var+1-block_recursive - << "+y_size*(it_+" << lag-1 << "))*y(it_+" << lag << ", " << varr+1 << ")"; - else - Ufoss << "+g1(" << eq+1-block_recursive - << "+Per_J_, " << var+1-block_recursive - << "+y_size*(it_" << lag-1 << "))*y(it_" << lag << ", " << varr+1 << ")"; - Uf[eqr] += Ufoss.str(); - Ufoss.str(""); - - if (lag == 0) - tmp_output << " g1(" << eq+1-block_recursive << "+Per_J_, " - << var+1-block_recursive << "+Per_K_) = "; - else if (lag == 1) - tmp_output << " g1(" << eq+1-block_recursive << "+Per_J_, " - << var+1-block_recursive << "+Per_y_) = "; - else if (lag > 0) - tmp_output << " g1(" << eq+1-block_recursive << "+Per_J_, " - << var+1-block_recursive << "+y_size*(it_+" << lag-1 << ")) = "; - else if (lag < 0) - tmp_output << " g1(" << eq+1-block_recursive << "+Per_J_, " - << var+1-block_recursive << "+y_size*(it_" << lag-1 << ")) = "; - output << " " << tmp_output.str(); - id->writeOutput(output, local_output_type, local_temporary_terms); - output << ";"; - output << " %2 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr)) - << "(" << lag << ") " << varr+1 - << ", equation=" << eqr+1 << " (" << eq+1 << ")" << endl; - } - -#ifdef CONDITION - output << " if (fabs(condition[" << eqr << "])= block_recursive) - output << " " << Uf[getBlockEquationID(block, i)] << ";\n"; -#ifdef CONDITION - output << " if (fabs(condition(" << i+1 << "))Block_List[block].Max_Lead+ModelBlock->Block_List[block].Max_Lag; m++) - { - k = m-ModelBlock->Block_List[block].Max_Lag; - for (i = 0; i < ModelBlock->Block_List[block].IM_lead_lag[m].size; i++) - { - unsigned int eq = ModelBlock->Block_List[block].IM_lead_lag[m].Equ_Index[i]; - unsigned int var = ModelBlock->Block_List[block].IM_lead_lag[m].Var_Index[i]; - unsigned int u = ModelBlock->Block_List[block].IM_lead_lag[m].u[i]; - unsigned int eqr = ModelBlock->Block_List[block].IM_lead_lag[m].Equ[i]; - output << " u(" << u+1 << "+Per_u_) = u(" << u+1 << "+Per_u_) / condition(" << eqr+1 << ");\n"; - } - } - for (i = 0; i < ModelBlock->Block_List[block].Size; i++) - output << " u(" << i+1 << "+Per_u_) = u(" << i+1 << "+Per_u_) / condition(" << i+1 << ");\n"; -#endif - output << " end;" << endl; - output << " end;" << endl; - break; - default: - break; - } - output << "end" << endl; - output.close(); - } -} - -void -DynamicModel::writeModelEquationsCode(string &file_name, const string &bin_basename, const map_idx_t &map_idx) const -{ - - ostringstream tmp_output; - ofstream code_file; - unsigned int instruction_number = 0; - bool file_open = false; - string main_name = file_name; - - main_name += ".cod"; - code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate); - if (!code_file.is_open()) - { - cerr << "Error : Can't open file \"" << main_name << "\" for writing" << endl; - exit(EXIT_FAILURE); - } - - int count_u; - int u_count_int = 0; - BlockSimulationType simulation_type; - if ((max_endo_lag > 0) && (max_endo_lead > 0)) - simulation_type = SOLVE_TWO_BOUNDARIES_COMPLETE; - else if ((max_endo_lag >= 0) && (max_endo_lead == 0)) - simulation_type = SOLVE_FORWARD_COMPLETE; - else - simulation_type = SOLVE_BACKWARD_COMPLETE; - - Write_Inf_To_Bin_File(file_name, u_count_int, file_open, simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE, symbol_table.endo_nbr()); - file_open = true; - - //Temporary variables declaration - FDIMT_ fdimt(temporary_terms.size()); - fdimt.write(code_file, instruction_number); - - vector exo, exo_det, other_endo; - - for (int i = 0; i < symbol_table.exo_det_nbr(); i++) - exo_det.push_back(i); - for (int i = 0; i < symbol_table.exo_nbr(); i++) - exo.push_back(i); - - map >, expr_t> first_derivatives_reordered_endo; - map, pair >, expr_t> first_derivatives_reordered_exo; - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - int deriv_id = it->first.second; - unsigned int eq = it->first.first; - int symb = getSymbIDByDerivID(deriv_id); - unsigned int var = symbol_table.getTypeSpecificID(symb); - int lag = getLagByDerivID(deriv_id); - if (getTypeByDerivID(deriv_id) == eEndogenous) - first_derivatives_reordered_endo[make_pair(lag, make_pair(var, eq))] = it->second; - else if (getTypeByDerivID(deriv_id) == eExogenous || getTypeByDerivID(deriv_id) == eExogenousDet) - first_derivatives_reordered_exo[make_pair(make_pair(lag, getTypeByDerivID(deriv_id)), make_pair(var, eq))] = it->second; - } - int prev_var = -1; - int prev_lag = -999999999; - int count_col_endo = 0; - for (map >, expr_t>::const_iterator it = first_derivatives_reordered_endo.begin(); - it != first_derivatives_reordered_endo.end(); it++) - { - int var = it->first.second.first; - int lag = it->first.first; - if (prev_var != var || prev_lag != lag) - { - prev_var = var; - prev_lag = lag; - count_col_endo++; - } - } - prev_var = -1; - prev_lag = -999999999; - int prev_type = -1; - int count_col_exo = 0; - int count_col_det_exo = 0; - - for (map, pair >, expr_t>::const_iterator it = first_derivatives_reordered_exo.begin(); - it != first_derivatives_reordered_exo.end(); it++) - { - int var = it->first.second.first; - int lag = it->first.first.first; - int type = it->first.first.second; - if (prev_var != var || prev_lag != lag || prev_type != type) - { - prev_var = var; - prev_lag = lag; - prev_type = type; - if (type == eExogenous) - count_col_exo++; - else if (type == eExogenousDet) - count_col_det_exo++; - } - } - - FBEGINBLOCK_ fbeginblock(symbol_table.endo_nbr(), - simulation_type, - 0, - symbol_table.endo_nbr(), - variable_reordered, - equation_reordered, - false, - symbol_table.endo_nbr(), - max_endo_lag, - max_endo_lead, - u_count_int, - count_col_endo, - symbol_table.exo_det_nbr(), - count_col_det_exo, - symbol_table.exo_nbr(), - count_col_exo, - 0, - 0, - exo_det, - exo, - other_endo - ); - fbeginblock.write(code_file, instruction_number); - - compileTemporaryTerms(code_file, instruction_number, temporary_terms, map_idx, true, false); - - compileModelEquations(code_file, instruction_number, temporary_terms, map_idx, true, false); - - FENDEQU_ fendequ; - fendequ.write(code_file, instruction_number); - - // Get the current code_file position and jump if eval = true - streampos pos1 = code_file.tellp(); - FJMPIFEVAL_ fjmp_if_eval(0); - fjmp_if_eval.write(code_file, instruction_number); - int prev_instruction_number = instruction_number; - - vector, int > > > derivatives; - derivatives.resize(symbol_table.endo_nbr()); - count_u = symbol_table.endo_nbr(); - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - int deriv_id = it->first.second; - if (getTypeByDerivID(deriv_id) == eEndogenous) - { - expr_t d1 = it->second; - unsigned int eq = it->first.first; - int symb = getSymbIDByDerivID(deriv_id); - unsigned int var = symbol_table.getTypeSpecificID(symb); - int lag = getLagByDerivID(deriv_id); - FNUMEXPR_ fnumexpr(FirstEndoDerivative, eq, var, lag); - fnumexpr.write(code_file, instruction_number); - if (!derivatives[eq].size()) - derivatives[eq].clear(); - derivatives[eq].push_back(make_pair(make_pair(var, lag), count_u)); - d1->compile(code_file, instruction_number, false, temporary_terms, map_idx, true, false); - - FSTPU_ fstpu(count_u); - fstpu.write(code_file, instruction_number); - count_u++; - } - } - for (int i = 0; i < symbol_table.endo_nbr(); i++) - { - FLDR_ fldr(i); - fldr.write(code_file, instruction_number); - if (derivatives[i].size()) - { - for (vector, int> >::const_iterator it = derivatives[i].begin(); - it != derivatives[i].end(); it++) - { - FLDU_ fldu(it->second); - fldu.write(code_file, instruction_number); - FLDV_ fldv(eEndogenous, it->first.first, it->first.second); - fldv.write(code_file, instruction_number); - FBINARY_ fbinary(oTimes); - fbinary.write(code_file, instruction_number); - if (it != derivatives[i].begin()) - { - FBINARY_ fbinary(oPlus); - fbinary.write(code_file, instruction_number); - } - } - FBINARY_ fbinary(oMinus); - fbinary.write(code_file, instruction_number); - } - FSTPU_ fstpu(i); - fstpu.write(code_file, instruction_number); - } - - // Get the current code_file position and jump = true - streampos pos2 = code_file.tellp(); - FJMP_ fjmp(0); - fjmp.write(code_file, instruction_number); - // Set code_file position to previous JMPIFEVAL_ and set the number of instructions to jump - streampos pos3 = code_file.tellp(); - code_file.seekp(pos1); - FJMPIFEVAL_ fjmp_if_eval1(instruction_number - prev_instruction_number); - fjmp_if_eval1.write(code_file, instruction_number); - code_file.seekp(pos3); - prev_instruction_number = instruction_number; - - // The Jacobian - prev_var = -1; - prev_lag = -999999999; - count_col_endo = 0; - for (map >, expr_t>::const_iterator it = first_derivatives_reordered_endo.begin(); - it != first_derivatives_reordered_endo.end(); it++) - { - unsigned int eq = it->first.second.second; - int var = it->first.second.first; - int lag = it->first.first; - expr_t d1 = it->second; - FNUMEXPR_ fnumexpr(FirstEndoDerivative, eq, var, lag); - fnumexpr.write(code_file, instruction_number); - if (prev_var != var || prev_lag != lag) - { - prev_var = var; - prev_lag = lag; - count_col_endo++; - } - d1->compile(code_file, instruction_number, false, temporary_terms, map_idx, true, false); - FSTPG3_ fstpg3(eq, var, lag, count_col_endo-1); - fstpg3.write(code_file, instruction_number); - } - prev_var = -1; - prev_lag = -999999999; - count_col_exo = 0; - for (map, pair >, expr_t>::const_iterator it = first_derivatives_reordered_exo.begin(); - it != first_derivatives_reordered_exo.end(); it++) - { - unsigned int eq = it->first.second.second; - int var = it->first.second.first; - int lag = it->first.first.first; - expr_t d1 = it->second; - FNUMEXPR_ fnumexpr(FirstExoDerivative, eq, var, lag); - fnumexpr.write(code_file, instruction_number); - if (prev_var != var || prev_lag != lag) - { - prev_var = var; - prev_lag = lag; - count_col_exo++; - } - d1->compile(code_file, instruction_number, false, temporary_terms, map_idx, true, false); - FSTPG3_ fstpg3(eq, var, lag, count_col_exo-1); - fstpg3.write(code_file, instruction_number); - } - // Set codefile position to previous JMP_ and set the number of instructions to jump - pos1 = code_file.tellp(); - code_file.seekp(pos2); - FJMP_ fjmp1(instruction_number - prev_instruction_number); - fjmp1.write(code_file, instruction_number); - code_file.seekp(pos1); - - FENDBLOCK_ fendblock; - fendblock.write(code_file, instruction_number); - FEND_ fend; - fend.write(code_file, instruction_number); - code_file.close(); -} - -void -DynamicModel::writeModelEquationsCode_Block(string &file_name, const string &bin_basename, const map_idx_t &map_idx) const -{ - struct Uff_l - { - int u, var, lag; - Uff_l *pNext; - }; - - struct Uff - { - Uff_l *Ufl, *Ufl_First; - }; - - int i, v; - string tmp_s; - ostringstream tmp_output; - ofstream code_file; - unsigned int instruction_number = 0; - expr_t lhs = NULL, rhs = NULL; - BinaryOpNode *eq_node; - Uff Uf[symbol_table.endo_nbr()]; - map reference_count; - deriv_node_temp_terms_t tef_terms; - vector feedback_variables; - bool file_open = false; - - string main_name = file_name; - main_name += ".cod"; - code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate); - if (!code_file.is_open()) - { - cerr << "Error : Can't open file \"" << main_name << "\" for writing" << endl; - exit(EXIT_FAILURE); - } - //Temporary variables declaration - - FDIMT_ fdimt(temporary_terms.size()); - fdimt.write(code_file, instruction_number); - - for (unsigned int block = 0; block < getNbBlocks(); block++) - { - feedback_variables.clear(); - if (block > 0) - { - FENDBLOCK_ fendblock; - fendblock.write(code_file, instruction_number); - } - int count_u; - int u_count_int = 0; - BlockSimulationType simulation_type = getBlockSimulationType(block); - unsigned int block_size = getBlockSize(block); - unsigned int block_mfs = getBlockMfs(block); - unsigned int block_recursive = block_size - block_mfs; - int block_max_lag = max_leadlag_block[block].first; - int block_max_lead = max_leadlag_block[block].second; - - if (simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE || simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE - || simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_FORWARD_COMPLETE) - { - Write_Inf_To_Bin_File_Block(file_name, bin_basename, block, u_count_int, file_open, - simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE); - file_open = true; - } - map >, expr_t> tmp_block_endo_derivative; - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - tmp_block_endo_derivative[make_pair(it->second.first, make_pair(it->first.second, it->first.first))] = it->second.second; - map >, expr_t> tmp_exo_derivative; - for (derivative_t::const_iterator it = derivative_exo[block].begin(); it != (derivative_exo[block]).end(); it++) - tmp_exo_derivative[make_pair(it->first.first, make_pair(it->first.second.second, it->first.second.first))] = it->second; - map >, expr_t> tmp_exo_det_derivative; - for (derivative_t::const_iterator it = derivative_exo_det[block].begin(); it != (derivative_exo_det[block]).end(); it++) - tmp_exo_det_derivative[make_pair(it->first.first, make_pair(it->first.second.second, it->first.second.first))] = it->second; - map >, expr_t> tmp_other_endo_derivative; - for (derivative_t::const_iterator it = derivative_other_endo[block].begin(); it != (derivative_other_endo[block]).end(); it++) - tmp_other_endo_derivative[make_pair(it->first.first, make_pair(it->first.second.second, it->first.second.first))] = it->second; - int prev_var = -1; - int prev_lag = -999999999; - int count_col_endo = 0; - for (map >, expr_t>::const_iterator it = tmp_block_endo_derivative.begin(); it != tmp_block_endo_derivative.end(); it++) - { - int lag = it->first.first; - int var = it->first.second.first; - if (prev_var != var || prev_lag != lag) - { - prev_var = var; - prev_lag = lag; - count_col_endo++; - } - } - unsigned int count_col_det_exo = 0; - vector exo_det; - for (lag_var_t::const_iterator it = exo_det_block[block].begin(); it != exo_det_block[block].end(); it++) - for (var_t::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) - { - count_col_det_exo++; - if (find(exo_det.begin(), exo_det.end(), *it1) == exo_det.end()) - exo_det.push_back(*it1); - } - - unsigned int count_col_exo = 0; - vector exo; - for (lag_var_t::const_iterator it = exo_block[block].begin(); it != exo_block[block].end(); it++) - for (var_t::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) - { - count_col_exo++; - if (find(exo.begin(), exo.end(), *it1) == exo.end()) - exo.push_back(*it1); - } - - vector other_endo; - unsigned int count_col_other_endo = 0; - for (lag_var_t::const_iterator it = other_endo_block[block].begin(); it != other_endo_block[block].end(); it++) - for (var_t::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) - { - count_col_other_endo++; - if (find(other_endo.begin(), other_endo.end(), *it1) == other_endo.end()) - other_endo.push_back(*it1); - } - - FBEGINBLOCK_ fbeginblock(block_mfs, - simulation_type, - getBlockFirstEquation(block), - block_size, - variable_reordered, - equation_reordered, - blocks_linear[block], - symbol_table.endo_nbr(), - block_max_lag, - block_max_lead, - u_count_int, - count_col_endo, - exo_det.size(), - count_col_det_exo, - exo.size(), - getBlockExoColSize(block), - other_endo.size(), - count_col_other_endo, - exo_det, - exo, - other_endo - ); - fbeginblock.write(code_file, instruction_number); - - // The equations - for (i = 0; i < (int) block_size; i++) - { - //The Temporary terms - temporary_terms_t tt2; - tt2.clear(); - if (v_temporary_terms[block][i].size()) - { - for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin(); - it != v_temporary_terms[block][i].end(); it++) - { - if (dynamic_cast(*it) != NULL) - (*it)->compileExternalFunctionOutput(code_file, instruction_number, false, tt2, map_idx, true, false, tef_terms); - - FNUMEXPR_ fnumexpr(TemporaryTerm, (int)(map_idx.find((*it)->idx)->second)); - fnumexpr.write(code_file, instruction_number); - (*it)->compile(code_file, instruction_number, false, tt2, map_idx, true, false, tef_terms); - FSTPT_ fstpt((int)(map_idx.find((*it)->idx)->second)); - fstpt.write(code_file, instruction_number); - // Insert current node into tt2 - tt2.insert(*it); -#ifdef DEBUGC - cout << "FSTPT " << v << "\n"; - instruction_number++; - code_file.write(&FOK, sizeof(FOK)); - code_file.write(reinterpret_cast(&k), sizeof(k)); - ki++; -#endif - - } - } -#ifdef DEBUGC - for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin(); - it != v_temporary_terms[block][i].end(); it++) - { - map_idx_t::const_iterator ii = map_idx.find((*it)->idx); - cout << "map_idx[" << (*it)->idx <<"]=" << ii->second << "\n"; - } -#endif - - int variable_ID, equation_ID; - EquationType equ_type; - - switch (simulation_type) - { - evaluation: - case EVALUATE_BACKWARD: - case EVALUATE_FORWARD: - equ_type = getBlockEquationType(block, i); - { - FNUMEXPR_ fnumexpr(ModelEquation, getBlockEquationID(block, i)); - fnumexpr.write(code_file, instruction_number); - } - if (equ_type == E_EVALUATE) - { - eq_node = (BinaryOpNode *) getBlockEquationExpr(block, i); - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - rhs->compile(code_file, instruction_number, false, temporary_terms, map_idx, true, false); - lhs->compile(code_file, instruction_number, true, temporary_terms, map_idx, true, false); - } - else if (equ_type == E_EVALUATE_S) - { - eq_node = (BinaryOpNode *) getBlockEquationRenormalizedExpr(block, i); - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - rhs->compile(code_file, instruction_number, false, temporary_terms, map_idx, true, false); - lhs->compile(code_file, instruction_number, true, temporary_terms, map_idx, true, false); - } - break; - case SOLVE_BACKWARD_COMPLETE: - case SOLVE_FORWARD_COMPLETE: - case SOLVE_TWO_BOUNDARIES_COMPLETE: - case SOLVE_TWO_BOUNDARIES_SIMPLE: - if (i < (int) block_recursive) - goto evaluation; - variable_ID = getBlockVariableID(block, i); - equation_ID = getBlockEquationID(block, i); - feedback_variables.push_back(variable_ID); - Uf[equation_ID].Ufl = NULL; - goto end; - default: - end: - FNUMEXPR_ fnumexpr(ModelEquation, getBlockEquationID(block, i)); - fnumexpr.write(code_file, instruction_number); - eq_node = (BinaryOpNode *) getBlockEquationExpr(block, i); - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - lhs->compile(code_file, instruction_number, false, temporary_terms, map_idx, true, false); - rhs->compile(code_file, instruction_number, false, temporary_terms, map_idx, true, false); - - FBINARY_ fbinary(oMinus); - fbinary.write(code_file, instruction_number); - FSTPR_ fstpr(i - block_recursive); - fstpr.write(code_file, instruction_number); - } - } - FENDEQU_ fendequ; - fendequ.write(code_file, instruction_number); - - // Get the current code_file position and jump if eval = true - streampos pos1 = code_file.tellp(); - FJMPIFEVAL_ fjmp_if_eval(0); - fjmp_if_eval.write(code_file, instruction_number); - int prev_instruction_number = instruction_number; - // The Jacobian if we have to solve the block determinsitic block - if (simulation_type != EVALUATE_BACKWARD - && simulation_type != EVALUATE_FORWARD) - { - switch (simulation_type) - { - case SOLVE_BACKWARD_SIMPLE: - case SOLVE_FORWARD_SIMPLE: - { - FNUMEXPR_ fnumexpr(FirstEndoDerivative, getBlockEquationID(block, 0), getBlockVariableID(block, 0), 0); - fnumexpr.write(code_file, instruction_number); - } - compileDerivative(code_file, instruction_number, getBlockEquationID(block, 0), getBlockVariableID(block, 0), 0, map_idx); - { - FSTPG_ fstpg(0); - fstpg.write(code_file, instruction_number); - } - break; - - case SOLVE_BACKWARD_COMPLETE: - case SOLVE_FORWARD_COMPLETE: - case SOLVE_TWO_BOUNDARIES_COMPLETE: - case SOLVE_TWO_BOUNDARIES_SIMPLE: - count_u = feedback_variables.size(); - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - { - int lag = it->second.first; - unsigned int eq = it->first.first; - unsigned int var = it->first.second; - unsigned int eqr = getBlockEquationID(block, eq); - unsigned int varr = getBlockVariableID(block, var); - if (eq >= block_recursive and var >= block_recursive) - { - if (lag != 0 && (simulation_type == SOLVE_FORWARD_COMPLETE || simulation_type == SOLVE_BACKWARD_COMPLETE)) - continue; - if (!Uf[eqr].Ufl) - { - Uf[eqr].Ufl = (Uff_l *) malloc(sizeof(Uff_l)); - Uf[eqr].Ufl_First = Uf[eqr].Ufl; - } - else - { - Uf[eqr].Ufl->pNext = (Uff_l *) malloc(sizeof(Uff_l)); - Uf[eqr].Ufl = Uf[eqr].Ufl->pNext; - } - Uf[eqr].Ufl->pNext = NULL; - Uf[eqr].Ufl->u = count_u; - Uf[eqr].Ufl->var = varr; - Uf[eqr].Ufl->lag = lag; - FNUMEXPR_ fnumexpr(FirstEndoDerivative, eqr, varr, lag); - fnumexpr.write(code_file, instruction_number); - compileChainRuleDerivative(code_file, instruction_number, eqr, varr, lag, map_idx); - FSTPU_ fstpu(count_u); - fstpu.write(code_file, instruction_number); - count_u++; - } - } - for (i = 0; i < (int) block_size; i++) - { - if (i >= (int) block_recursive) - { - FLDR_ fldr(i-block_recursive); - fldr.write(code_file, instruction_number); - - FLDZ_ fldz; - fldz.write(code_file, instruction_number); - - v = getBlockEquationID(block, i); - for (Uf[v].Ufl = Uf[v].Ufl_First; Uf[v].Ufl; Uf[v].Ufl = Uf[v].Ufl->pNext) - { - FLDU_ fldu(Uf[v].Ufl->u); - fldu.write(code_file, instruction_number); - FLDV_ fldv(eEndogenous, Uf[v].Ufl->var, Uf[v].Ufl->lag); - fldv.write(code_file, instruction_number); - - FBINARY_ fbinary(oTimes); - fbinary.write(code_file, instruction_number); - - FCUML_ fcuml; - fcuml.write(code_file, instruction_number); - } - Uf[v].Ufl = Uf[v].Ufl_First; - while (Uf[v].Ufl) - { - Uf[v].Ufl_First = Uf[v].Ufl->pNext; - free(Uf[v].Ufl); - Uf[v].Ufl = Uf[v].Ufl_First; - } - FBINARY_ fbinary(oMinus); - fbinary.write(code_file, instruction_number); - - FSTPU_ fstpu(i - block_recursive); - fstpu.write(code_file, instruction_number); - } - } - break; - default: - break; - } - } - // Get the current code_file position and jump = true - streampos pos2 = code_file.tellp(); - FJMP_ fjmp(0); - fjmp.write(code_file, instruction_number); - // Set code_file position to previous JMPIFEVAL_ and set the number of instructions to jump - streampos pos3 = code_file.tellp(); - code_file.seekp(pos1); - FJMPIFEVAL_ fjmp_if_eval1(instruction_number - prev_instruction_number); - fjmp_if_eval1.write(code_file, instruction_number); - code_file.seekp(pos3); - prev_instruction_number = instruction_number; - // The Jacobian if we have to solve the block determinsitic block - - prev_var = -1; - prev_lag = -999999999; - count_col_endo = 0; - for (map >, expr_t>::const_iterator it = tmp_block_endo_derivative.begin(); it != tmp_block_endo_derivative.end(); it++) - { - int lag = it->first.first; - unsigned int eq = it->first.second.second; - int var = it->first.second.first; - unsigned int eqr = getBlockEquationID(block, eq); - unsigned int varr = getBlockVariableID(block, var); - if (prev_var != var || prev_lag != lag) - { - prev_var = var; - prev_lag = lag; - count_col_endo++; - } - FNUMEXPR_ fnumexpr(FirstEndoDerivative, eqr, varr, lag); - fnumexpr.write(code_file, instruction_number); - compileDerivative(code_file, instruction_number, eqr, varr, lag, map_idx); - FSTPG3_ fstpg3(eq, var, lag, count_col_endo-1); - fstpg3.write(code_file, instruction_number); - } - prev_var = -1; - prev_lag = -999999999; - count_col_exo = 0; - for (map >, expr_t>::const_iterator it = tmp_exo_derivative.begin(); it != tmp_exo_derivative.end(); it++) - { - int lag = it->first.first; - int eq = it->first.second.second; - int var = it->first.second.first; - int eqr = getBlockInitialEquationID(block, eq); - int varr = getBlockInitialExogenousID(block, var); - if (prev_var != var || prev_lag != lag) - { - prev_var = var; - prev_lag = lag; - count_col_exo++; - } - expr_t id = it->second; - - FNUMEXPR_ fnumexpr(FirstExoDerivative, eqr, varr, lag); - fnumexpr.write(code_file, instruction_number); - id->compile(code_file, instruction_number, false, temporary_terms, map_idx, true, false); - FSTPG3_ fstpg3(eq, var, lag, /*var*/ count_col_exo-1); - fstpg3.write(code_file, instruction_number); - } - prev_var = -1; - prev_lag = -999999999; - int count_col_exo_det = 0; - for (map >, expr_t>::const_iterator it = tmp_exo_det_derivative.begin(); it != tmp_exo_det_derivative.end(); it++) - { - int lag = it->first.first; - int eq = it->first.second.second; - int var = it->first.second.first; - int eqr = getBlockInitialEquationID(block, eq); - int varr = getBlockInitialDetExogenousID(block, var); - if (prev_var != var || prev_lag != lag) - { - prev_var = var; - prev_lag = lag; - count_col_exo_det++; - } - expr_t id = it->second; - - FNUMEXPR_ fnumexpr(FirstExodetDerivative, eqr, varr, lag); - fnumexpr.write(code_file, instruction_number); - id->compile(code_file, instruction_number, false, temporary_terms, map_idx, true, false); - FSTPG3_ fstpg3(eq, var, lag, count_col_exo_det-1); - fstpg3.write(code_file, instruction_number); - } - prev_var = -1; - prev_lag = -999999999; - count_col_other_endo = 0; - for (map >, expr_t>::const_iterator it = tmp_other_endo_derivative.begin(); it != tmp_other_endo_derivative.end(); it++) - { - int lag = it->first.first; - int eq = it->first.second.second; - int var = it->first.second.first; - int eqr = getBlockInitialEquationID(block, eq); - int varr = getBlockInitialOtherEndogenousID(block, var);; - if (prev_var != var || prev_lag != lag) - { - prev_var = var; - prev_lag = lag; - count_col_other_endo++; - } - expr_t id = it->second; - - FNUMEXPR_ fnumexpr(FirstOtherEndoDerivative, eqr, varr, lag); - fnumexpr.write(code_file, instruction_number); - id->compile(code_file, instruction_number, false, temporary_terms, map_idx, true, false); - FSTPG3_ fstpg3(eq, var, lag, count_col_other_endo-1); - fstpg3.write(code_file, instruction_number); - } - - // Set codefile position to previous JMP_ and set the number of instructions to jump - pos1 = code_file.tellp(); - code_file.seekp(pos2); - FJMP_ fjmp1(instruction_number - prev_instruction_number); - fjmp1.write(code_file, instruction_number); - code_file.seekp(pos1); - } - FENDBLOCK_ fendblock; - fendblock.write(code_file, instruction_number); - FEND_ fend; - fend.write(code_file, instruction_number); - code_file.close(); -} - -void -DynamicModel::writeDynamicMFile(const string &dynamic_basename) const -{ - string filename = dynamic_basename + ".m"; - - ofstream mDynamicModelFile; - mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); - if (!mDynamicModelFile.is_open()) - { - cerr << "Error: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - mDynamicModelFile << "function [residual, g1, g2, g3] = " << dynamic_basename << "(y, x, params, steady_state, it_)" << endl - << "%" << endl - << "% Status : Computes dynamic model for Dynare" << endl - << "%" << 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 - << "% steady_state [M_.endo_nbr by 1] double vector of steady state values" << endl - << "% params [M_.param_nbr by 1] double vector of parameter values in declaration order" << endl - << "% it_ scalar double time period for exogenous variables for which to evaluate the model" << endl - << "%" << endl - << "% Outputs:" << endl - << "% residual [M_.endo_nbr by 1] double vector of residuals of the dynamic model equations in order of " << endl - << "% declaration of the equations." << endl - << "% Dynare may prepend auxiliary equations, see M_.aux_vars" << endl - << "% g1 [M_.endo_nbr by #dynamic variables] double Jacobian matrix of the dynamic model equations;" << endl - << "% rows: equations in order of declaration" << endl - << "% columns: variables in order stored in M_.lead_lag_incidence followed by the ones in M_.exo_names" << endl - << "% g2 [M_.endo_nbr by (#dynamic variables)^2] double Hessian matrix of the dynamic model equations;" << endl - << "% rows: equations in order of declaration" << endl - << "% columns: variables in order stored in M_.lead_lag_incidence followed by the ones in M_.exo_names" << endl - << "% g3 [M_.endo_nbr by (#dynamic variables)^3] double Third order derivative matrix of the dynamic model equations;" << endl - << "% rows: equations in order of declaration" << endl - << "% columns: variables in order stored in M_.lead_lag_incidence followed by the ones in M_.exo_names" << endl - << "%" << endl - << "%" << endl - << "% Warning : this file is generated automatically by Dynare" << endl - << "% from model file (.mod)" << endl << endl; - - writeDynamicModel(mDynamicModelFile, false, false); - mDynamicModelFile << "end" << endl; // Close *_dynamic function - mDynamicModelFile.close(); -} - -void -DynamicModel::writeDynamicJuliaFile(const string &basename) const -{ - string filename = basename + "Dynamic.jl"; - - ofstream output; - output.open(filename.c_str(), ios::out | ios::binary); - if (!output.is_open()) - { - cerr << "Error: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - output << "module " << basename << "Dynamic" << endl - << "#" << endl - << "# NB: this file was automatically generated by Dynare" << endl - << "# from " << basename << ".mod" << endl - << "#" << endl - << "using Utils" << endl << endl - << "export dynamic!" << endl << endl; - writeDynamicModel(output, false, true); - output << "end" << endl; - output.close(); -} - -void -DynamicModel::writeDynamicCFile(const string &dynamic_basename, const int order) const -{ - string filename = dynamic_basename + ".c"; - string filename_mex = dynamic_basename + "_mex.c"; - ofstream mDynamicModelFile, mDynamicMexFile; - - mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); - if (!mDynamicModelFile.is_open()) - { - cerr << "Error: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - mDynamicModelFile << "/*" << endl - << " * " << filename << " : Computes dynamic model for Dynare" << endl - << " *" << endl - << " * Warning : this file is generated automatically by Dynare" << endl - << " * from model file (.mod)" << endl - << " */" << endl -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - << "#ifdef _MSC_VER" << endl - << "#define _USE_MATH_DEFINES" << endl - << "#endif" << endl -#endif - << "#include " << endl; - - if (external_functions_table.get_total_number_of_unique_model_block_external_functions()) - // External Matlab function, implies Dynamic function will call mex - mDynamicModelFile << "#include \"mex.h\"" << endl; - else - mDynamicModelFile << "#include " << endl; - - mDynamicModelFile << "#define max(a, b) (((a) > (b)) ? (a) : (b))" << endl - << "#define min(a, b) (((a) > (b)) ? (b) : (a))" << endl; - - // Write function definition if oPowerDeriv is used - writePowerDerivCHeader(mDynamicModelFile); - writeNormcdfCHeader(mDynamicModelFile); - - // Writing the function body - writeDynamicModel(mDynamicModelFile, true, false); - - writePowerDeriv(mDynamicModelFile); - writeNormcdf(mDynamicModelFile); - mDynamicModelFile.close(); - - mDynamicMexFile.open(filename_mex.c_str(), ios::out | ios::binary); - if (!mDynamicMexFile.is_open()) - { - cerr << "Error: Can't open file " << filename_mex << " for writing" << endl; - exit(EXIT_FAILURE); - } - - // Writing the gateway routine - mDynamicMexFile << "/*" << endl - << " * " << filename_mex << " : The gateway routine used to call the Dynamic function " - << "located in " << filename << endl - << " *" << endl - << " * Warning : this file is generated automatically by Dynare" << endl - << " * from model file (.mod)" << endl - << endl - << " */" << endl << endl - << "#include \"mex.h\"" << endl << endl - << "void Dynamic(double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, double *g1, double *v2, double *v3);" << endl - << "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl - << "{" << endl - << " double *y, *x, *params, *steady_state;" << endl - << " double *residual, *g1, *v2, *v3;" << endl - << " int nb_row_x, it_;" << endl - << endl - << " /* Check that no derivatives of higher order than computed are being requested */" << endl - << " if (nlhs > " << order + 1 << ")" << endl - << " mexErrMsgTxt(\"Derivatives of higher order than computed have been requested\");" << endl - << " /* Create a pointer to the input matrix y. */" << endl - << " y = mxGetPr(prhs[0]);" << endl - << endl - << " /* Create a pointer to the input matrix x. */" << endl - << " x = mxGetPr(prhs[1]);" << endl - << endl - << " /* Create a pointer to the input matrix params. */" << endl - << " params = mxGetPr(prhs[2]);" << endl - << endl - << " /* Create a pointer to the input matrix steady_state. */" << endl - << " steady_state = mxGetPr(prhs[3]);" << endl - << endl - << " /* Fetch time index */" << endl - << " it_ = (int) mxGetScalar(prhs[4]) - 1;" << endl - << endl - << " /* Gets number of rows of matrix x. */" << endl - << " nb_row_x = mxGetM(prhs[1]);" << endl - << endl - << " residual = NULL;" << endl - << " if (nlhs >= 1)" << endl - << " {" << endl - << " /* Set the output pointer to the output matrix residual. */" << endl - << " plhs[0] = mxCreateDoubleMatrix(" << equations.size() << ",1, mxREAL);" << endl - << " /* Create a C pointer to a copy of the output matrix residual. */" << endl - << " residual = mxGetPr(plhs[0]);" << endl - << " }" << endl - << endl - << " g1 = NULL;" << endl - << " if (nlhs >= 2)" << endl - << " {" << endl - << " /* Set the output pointer to the output matrix g1. */" << endl - << " plhs[1] = mxCreateDoubleMatrix(" << equations.size() << ", " << dynJacobianColsNbr << ", mxREAL);" << endl - << " /* Create a C pointer to a copy of the output matrix g1. */" << endl - << " g1 = mxGetPr(plhs[1]);" << endl - << " }" << endl - << endl - << " v2 = NULL;" << endl - << " if (nlhs >= 3)" << endl - << " {" << endl - << " /* Set the output pointer to the output matrix v2. */" << endl - << " plhs[2] = mxCreateDoubleMatrix(" << NNZDerivatives[1] << ", " << 3 - << ", mxREAL);" << endl - << " v2 = mxGetPr(plhs[2]);" << endl - << " }" << endl - << endl - << " v3 = NULL;" << endl - << " if (nlhs >= 4)" << endl - << " {" << endl - << " /* Set the output pointer to the output matrix v3. */" << endl - << " plhs[3] = mxCreateDoubleMatrix(" << NNZDerivatives[2] << ", " << 3 << ", mxREAL);" << endl - << " v3 = mxGetPr(plhs[3]);" << endl - << " }" << endl - << endl - << " /* Call the C subroutines. */" << endl - << " Dynamic(y, x, nb_row_x, params, steady_state, it_, residual, g1, v2, v3);" << endl - << "}" << endl; - mDynamicMexFile.close(); -} - -string -DynamicModel::reform(const string name1) const -{ - string name = name1; - int pos = name.find("\\", 0); - while (pos >= 0) - { - if (name.substr(pos + 1, 1) != "\\") - { - name = name.insert(pos, "\\"); - pos++; - } - pos++; - pos = name.find("\\", pos); - } - return (name); -} - -void -DynamicModel::printNonZeroHessianEquations(ostream &output) const -{ - if (nonzero_hessian_eqs.size() != 1) - output << "["; - for (map::const_iterator it = nonzero_hessian_eqs.begin(); - it != nonzero_hessian_eqs.end(); it++) - { - if (it != nonzero_hessian_eqs.begin()) - output << " "; - output << it->first; - } - if (nonzero_hessian_eqs.size() != 1) - output << "]"; -} - -void -DynamicModel::setNonZeroHessianEquations(map &eqs) -{ - for (second_derivatives_t::const_iterator it = second_derivatives.begin(); - it != second_derivatives.end(); it++) - if (nonzero_hessian_eqs.find(it->first.first) == nonzero_hessian_eqs.end()) - { - nonzero_hessian_eqs[it->first.first] = ""; - for (size_t i = 0; i < equation_tags.size(); i++) - if (equation_tags[i].first == it->first.first) - if (equation_tags[i].second.first == "name") - { - nonzero_hessian_eqs[it->first.first] = equation_tags[i].second.second; - break; - } - } - eqs = nonzero_hessian_eqs; -} - -void -DynamicModel::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 -{ - int j; - std::ofstream SaveCode; - if (file_open) - SaveCode.open((bin_basename + "_dynamic.bin").c_str(), ios::out | ios::in | ios::binary | ios::ate); - else - SaveCode.open((bin_basename + "_dynamic.bin").c_str(), ios::out | ios::binary); - if (!SaveCode.is_open()) - { - cerr << "Error : Can't open file \"" << bin_basename << "_dynamic.bin\" for writing" << endl; - exit(EXIT_FAILURE); - } - u_count_int = 0; - unsigned int block_size = getBlockSize(num); - unsigned int block_mfs = getBlockMfs(num); - unsigned int block_recursive = block_size - block_mfs; - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[num].begin(); it != (blocks_derivatives[num]).end(); it++) - { - unsigned int eq = it->first.first; - unsigned int var = it->first.second; - int lag = it->second.first; - if (lag != 0 && !is_two_boundaries) - continue; - if (eq >= block_recursive && var >= block_recursive) - { - int v = eq - block_recursive; - SaveCode.write(reinterpret_cast(&v), sizeof(v)); - int varr = var - block_recursive + lag * block_mfs; - SaveCode.write(reinterpret_cast(&varr), sizeof(varr)); - SaveCode.write(reinterpret_cast(&lag), sizeof(lag)); - int u = u_count_int + block_mfs; - SaveCode.write(reinterpret_cast(&u), sizeof(u)); - u_count_int++; - } - } - - if (is_two_boundaries) - u_count_int += block_mfs; - for (j = block_recursive; j < (int) block_size; j++) - { - unsigned int varr = getBlockVariableID(num, j); - SaveCode.write(reinterpret_cast(&varr), sizeof(varr)); - } - for (j = block_recursive; j < (int) block_size; j++) - { - unsigned int eqr = getBlockEquationID(num, j); - SaveCode.write(reinterpret_cast(&eqr), sizeof(eqr)); - } - SaveCode.close(); -} - -void -DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const string &basename) const -{ - string sp; - ofstream mDynamicModelFile; - ostringstream tmp, tmp1, tmp_eq; - bool OK; - chdir(basename.c_str()); - string filename = dynamic_basename + ".m"; - mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); - if (!mDynamicModelFile.is_open()) - { - cerr << "Error: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - mDynamicModelFile << "%\n"; - mDynamicModelFile << "% " << filename << " : Computes dynamic model for Dynare\n"; - mDynamicModelFile << "%\n"; - mDynamicModelFile << "% Warning : this file is generated automatically by Dynare\n"; - mDynamicModelFile << "% from model file (.mod)\n\n"; - mDynamicModelFile << "%/\n"; - - int Nb_SGE = 0; - bool open_par = false; - - mDynamicModelFile << "function [varargout] = " << dynamic_basename << "(options_, M_, oo_, varargin)\n"; - mDynamicModelFile << " g2=[];g3=[];\n"; - //Temporary variables declaration - OK = true; - ostringstream tmp_output; - for (temporary_terms_t::const_iterator it = temporary_terms.begin(); - it != temporary_terms.end(); it++) - { - if (OK) - OK = false; - else - tmp_output << " "; - (*it)->writeOutput(tmp_output, oMatlabStaticModelSparse, temporary_terms); - } - if (tmp_output.str().length() > 0) - mDynamicModelFile << " global " << tmp_output.str() << ";\n"; - - mDynamicModelFile << " T_init=zeros(1,options_.periods+M_.maximum_lag+M_.maximum_lead);\n"; - tmp_output.str(""); - for (temporary_terms_t::const_iterator it = temporary_terms.begin(); - it != temporary_terms.end(); it++) - { - tmp_output << " "; - (*it)->writeOutput(tmp_output, oMatlabDynamicModel, temporary_terms); - tmp_output << "=T_init;\n"; - } - if (tmp_output.str().length() > 0) - mDynamicModelFile << tmp_output.str(); - - mDynamicModelFile << " y_kmin=M_.maximum_lag;" << endl - << " y_kmax=M_.maximum_lead;" << endl - << " y_size=M_.endo_nbr;" << endl - << " if(length(varargin)>0)" << endl - << " %it is a simple evaluation of the dynamic model for time _it" << endl - << " y=varargin{1};" << endl - << " x=varargin{2};" << endl - << " params=varargin{3};" << endl - << " steady_state=varargin{4};" << endl - << " it_=varargin{5};" << endl - << " dr=varargin{6};" << endl - << " Per_u_=0;" << endl - << " Per_y_=it_*y_size;" << endl - << " ys=y(it_,:);" << endl; - tmp.str(""); - tmp_eq.str(""); - unsigned int nb_blocks = getNbBlocks(); - unsigned int block = 0; - for (int count_call = 1; block < nb_blocks; block++, count_call++) - { - unsigned int block_size = getBlockSize(block); - unsigned int block_mfs = getBlockMfs(block); - unsigned int block_recursive = block_size - block_mfs; - BlockSimulationType simulation_type = getBlockSimulationType(block); - - if (simulation_type == EVALUATE_FORWARD || simulation_type == EVALUATE_BACKWARD) - { - for (unsigned int ik = 0; ik < block_size; ik++) - { - tmp << " " << getBlockVariableID(block, ik)+1; - tmp_eq << " " << getBlockEquationID(block, ik)+1; - } - } - else - { - for (unsigned int ik = block_recursive; ik < block_size; ik++) - { - tmp << " " << getBlockVariableID(block, ik)+1; - tmp_eq << " " << getBlockEquationID(block, ik)+1; - } - } - mDynamicModelFile << " y_index_eq=[" << tmp_eq.str() << "];\n"; - mDynamicModelFile << " y_index=[" << tmp.str() << "];\n"; - - switch (simulation_type) - { - case EVALUATE_FORWARD: - case EVALUATE_BACKWARD: - mDynamicModelFile << " [y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_xd, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << block + 1 << "(y, x, params, steady_state, 1, it_-1, 1);\n"; - mDynamicModelFile << " residual(y_index_eq)=ys(y_index)-y(it_, y_index);\n"; - break; - case SOLVE_FORWARD_SIMPLE: - case SOLVE_BACKWARD_SIMPLE: - mDynamicModelFile << " [r, y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_xd, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << block + 1 << "(y, x, params, steady_state, it_, 1);\n"; - mDynamicModelFile << " residual(y_index_eq)=r;\n"; - break; - case SOLVE_FORWARD_COMPLETE: - case SOLVE_BACKWARD_COMPLETE: - mDynamicModelFile << " [r, y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_xd, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << block + 1 << "(y, x, params, steady_state, it_, 1);\n"; - mDynamicModelFile << " residual(y_index_eq)=r;\n"; - break; - case SOLVE_TWO_BOUNDARIES_COMPLETE: - case SOLVE_TWO_BOUNDARIES_SIMPLE: - mDynamicModelFile << " [r, y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, b, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_xd, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << block + 1 << "(y, x, params, steady_state, it_-" << max_lag << ", 1, " << max_lag << ", " << block_recursive << "," << "options_.periods" << ");\n"; - mDynamicModelFile << " residual(y_index_eq)=r(:,M_.maximum_lag+1);\n"; - break; - default: - break; - } - tmp_eq.str(""); - tmp.str(""); - } - if (tmp1.str().length()) - { - mDynamicModelFile << tmp1.str(); - tmp1.str(""); - } - mDynamicModelFile << " varargout{1}=residual;" << endl - << " varargout{2}=dr;" << endl - << " return;" << endl - << " end;" << endl - << " %it is the deterministic simulation of the block decomposed dynamic model" << endl - << " if(options_.stack_solve_algo==0)" << endl - << " mthd='Sparse LU';" << endl - << " elseif(options_.stack_solve_algo==1)" << endl - << " mthd='Relaxation';" << endl - << " elseif(options_.stack_solve_algo==2)" << endl - << " mthd='GMRES';" << endl - << " elseif(options_.stack_solve_algo==3)" << endl - << " mthd='BICGSTAB';" << endl - << " elseif(options_.stack_solve_algo==4)" << endl - << " mthd='OPTIMPATH';" << endl - << " else" << endl - << " mthd='UNKNOWN';" << endl - << " end;" << endl - << " if options_.verbosity" << endl - << " printline(41)" << endl - << " disp(sprintf('MODEL SIMULATION (method=%s):',mthd))" << endl - << " skipline()" << endl - << " end" << endl - << " periods=options_.periods;" << endl - << " maxit_=options_.simul.maxit;" << endl - << " solve_tolf=options_.solve_tolf;" << endl - << " y=oo_.endo_simul';" << endl - << " x=oo_.exo_simul;" << endl; - - mDynamicModelFile << " params=M_.params;\n"; - mDynamicModelFile << " steady_state=oo_.steady_state;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.status = 0;\n"; - for (block = 0; block < nb_blocks; block++) - { - unsigned int block_size = getBlockSize(block); - unsigned int block_mfs = getBlockMfs(block); - unsigned int block_recursive = block_size - block_mfs; - BlockSimulationType simulation_type = getBlockSimulationType(block); - - if ((simulation_type == EVALUATE_FORWARD) && (block_size)) - { - if (open_par) - { - mDynamicModelFile << " end\n"; - } - mDynamicModelFile << " oo_.deterministic_simulation.status = 1;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.error = 0;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.iterations = 0;\n"; - mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; - mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; - mDynamicModelFile << " else\n"; - mDynamicModelFile << " blck_num = 1;\n"; - mDynamicModelFile << " end;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).status = 1;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).error = 0;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).iterations = 0;\n"; - mDynamicModelFile << " g1=[];g2=[];g3=[];\n"; - mDynamicModelFile << " y=" << dynamic_basename << "_" << block + 1 << "(y, x, params, steady_state, 0, y_kmin, periods);\n"; - mDynamicModelFile << " tmp = y(:,M_.block_structure.block(" << block + 1 << ").variable);\n"; - mDynamicModelFile << " if any(isnan(tmp) | isinf(tmp))\n"; - mDynamicModelFile << " disp(['Inf or Nan value during the evaluation of block " << block <<"']);\n"; - mDynamicModelFile << " oo_.deterministic_simulation.status = 0;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.error = 100;\n"; - mDynamicModelFile << " varargout{1} = oo_;\n"; - mDynamicModelFile << " return;\n"; - mDynamicModelFile << " end;\n"; - } - else if ((simulation_type == EVALUATE_BACKWARD) && (block_size)) - { - if (open_par) - { - mDynamicModelFile << " end\n"; - } - mDynamicModelFile << " oo_.deterministic_simulation.status = 1;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.error = 0;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.iterations = 0;\n"; - mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; - mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; - mDynamicModelFile << " else\n"; - mDynamicModelFile << " blck_num = 1;\n"; - mDynamicModelFile << " end;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).status = 1;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).error = 0;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.block(blck_num).iterations = 0;\n"; - mDynamicModelFile << " g1=[];g2=[];g3=[];\n"; - mDynamicModelFile << " " << dynamic_basename << "_" << block + 1 << "(y, x, params, steady_state, 0, y_kmin, periods);\n"; - mDynamicModelFile << " tmp = y(:,M_.block_structure.block(" << block + 1 << ").variable);\n"; - mDynamicModelFile << " if any(isnan(tmp) | isinf(tmp))\n"; - mDynamicModelFile << " disp(['Inf or Nan value during the evaluation of block " << block <<"']);\n"; - mDynamicModelFile << " oo_.deterministic_simulation.status = 0;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.error = 100;\n"; - mDynamicModelFile << " varargout{1} = oo_;\n"; - mDynamicModelFile << " return;\n"; - mDynamicModelFile << " end;\n"; - } - else if ((simulation_type == SOLVE_FORWARD_COMPLETE || simulation_type == SOLVE_FORWARD_SIMPLE) && (block_size)) - { - if (open_par) - mDynamicModelFile << " end\n"; - open_par = false; - mDynamicModelFile << " g1=0;\n"; - mDynamicModelFile << " r=0;\n"; - tmp.str(""); - for (unsigned int ik = block_recursive; ik < block_size; ik++) - { - tmp << " " << getBlockVariableID(block, ik)+1; - } - mDynamicModelFile << " y_index = [" << tmp.str() << "];\n"; - int nze = blocks_derivatives[block].size(); - mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; - mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; - mDynamicModelFile << " else\n"; - mDynamicModelFile << " blck_num = 1;\n"; - mDynamicModelFile << " end;\n"; - mDynamicModelFile << " y = solve_one_boundary('" << dynamic_basename << "_" << block + 1 << "'" - <<", y, x, params, steady_state, y_index, " << nze - <<", options_.periods, " << blocks_linear[block] - <<", blck_num, y_kmin, options_.simul.maxit, options_.solve_tolf, options_.slowc, " << cutoff << ", options_.stack_solve_algo, 1, 1, 0);\n"; - mDynamicModelFile << " tmp = y(:,M_.block_structure.block(" << block + 1 << ").variable);\n"; - mDynamicModelFile << " if any(isnan(tmp) | isinf(tmp))\n"; - mDynamicModelFile << " disp(['Inf or Nan value during the resolution of block " << block <<"']);\n"; - mDynamicModelFile << " oo_.deterministic_simulation.status = 0;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.error = 100;\n"; - mDynamicModelFile << " varargout{1} = oo_;\n"; - mDynamicModelFile << " return;\n"; - mDynamicModelFile << " end;\n"; - } - else if ((simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_BACKWARD_SIMPLE) && (block_size)) - { - if (open_par) - mDynamicModelFile << " end\n"; - open_par = false; - mDynamicModelFile << " g1=0;\n"; - mDynamicModelFile << " r=0;\n"; - tmp.str(""); - for (unsigned int ik = block_recursive; ik < block_size; ik++) - { - tmp << " " << getBlockVariableID(block, ik)+1; - } - mDynamicModelFile << " y_index = [" << tmp.str() << "];\n"; - int nze = blocks_derivatives[block].size(); - - mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; - mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; - mDynamicModelFile << " else\n"; - mDynamicModelFile << " blck_num = 1;\n"; - mDynamicModelFile << " end;\n"; - mDynamicModelFile << " y = solve_one_boundary('" << dynamic_basename << "_" << block + 1 << "'" - <<", y, x, params, steady_state, y_index, " << nze - <<", options_.periods, " << blocks_linear[block] - <<", blck_num, y_kmin, options_.simul.maxit, options_.solve_tolf, options_.slowc, " << cutoff << ", options_.stack_solve_algo, 1, 1, 0);\n"; - mDynamicModelFile << " tmp = y(:,M_.block_structure.block(" << block + 1 << ").variable);\n"; - mDynamicModelFile << " if any(isnan(tmp) | isinf(tmp))\n"; - mDynamicModelFile << " disp(['Inf or Nan value during the resolution of block " << block <<"']);\n"; - mDynamicModelFile << " oo_.deterministic_simulation.status = 0;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.error = 100;\n"; - mDynamicModelFile << " varargout{1} = oo_;\n"; - mDynamicModelFile << " return;\n"; - mDynamicModelFile << " end;\n"; - } - else if ((simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE) && (block_size)) - { - if (open_par) - mDynamicModelFile << " end\n"; - open_par = false; - Nb_SGE++; - int nze = blocks_derivatives[block].size(); - mDynamicModelFile << " y_index=["; - for (unsigned int ik = block_recursive; ik < block_size; ik++) - { - mDynamicModelFile << " " << getBlockVariableID(block, ik)+1; - } - mDynamicModelFile << " ];\n"; - mDynamicModelFile << " if(isfield(oo_.deterministic_simulation,'block'))\n"; - mDynamicModelFile << " blck_num = length(oo_.deterministic_simulation.block)+1;\n"; - mDynamicModelFile << " else\n"; - mDynamicModelFile << " blck_num = 1;\n"; - mDynamicModelFile << " end;\n"; - mDynamicModelFile << " [y oo_] = solve_two_boundaries('" << dynamic_basename << "_" << block + 1 << "'" - <<", y, x, params, steady_state, y_index, " << nze - <<", options_.periods, " << max_leadlag_block[block].first - <<", " << max_leadlag_block[block].second - <<", " << blocks_linear[block] - <<", blck_num, y_kmin, options_.simul.maxit, options_.solve_tolf, options_.slowc, " << cutoff << ", options_.stack_solve_algo, options_, M_, oo_);\n"; - mDynamicModelFile << " tmp = y(:,M_.block_structure.block(" << block + 1 << ").variable);\n"; - mDynamicModelFile << " if any(isnan(tmp) | isinf(tmp))\n"; - mDynamicModelFile << " disp(['Inf or Nan value during the resolution of block " << block <<"']);\n"; - mDynamicModelFile << " oo_.deterministic_simulation.status = 0;\n"; - mDynamicModelFile << " oo_.deterministic_simulation.error = 100;\n"; - mDynamicModelFile << " varargout{1} = oo_;\n"; - mDynamicModelFile << " return;\n"; - mDynamicModelFile << " end;\n"; - } - } - if (open_par) - mDynamicModelFile << " end;\n"; - open_par = false; - mDynamicModelFile << " oo_.endo_simul = y';\n"; - mDynamicModelFile << " varargout{1} = oo_;\n"; - mDynamicModelFile << "return;\n"; - mDynamicModelFile << "end" << endl; - - mDynamicModelFile.close(); - - writeModelEquationsOrdered_M(dynamic_basename); - - chdir(".."); -} - -void -DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll, bool julia) const -{ - ostringstream model_local_vars_output; // Used for storing model local vars - ostringstream model_output; // Used for storing model temp vars and equations - ostringstream jacobian_output; // Used for storing jacobian equations - ostringstream hessian_output; // Used for storing Hessian equations - ostringstream third_derivatives_output; // Used for storing third order derivatives equations - - ExprNodeOutputType output_type = (use_dll ? oCDynamicModel : - julia ? oJuliaDynamicModel : oMatlabDynamicModel); - - deriv_node_temp_terms_t tef_terms; - temporary_terms_t temp_term_empty; - temporary_terms_t temp_term_union = temporary_terms_res; - temporary_terms_t temp_term_union_m_1; - - writeModelLocalVariables(model_local_vars_output, output_type, tef_terms); - - writeTemporaryTerms(temporary_terms_res, temp_term_union_m_1, model_output, output_type, tef_terms); - - writeModelEquations(model_output, output_type); - - int nrows = equations.size(); - int hessianColsNbr = dynJacobianColsNbr * dynJacobianColsNbr; - - // Writing Jacobian - temp_term_union_m_1 = temp_term_union; - temp_term_union.insert(temporary_terms_g1.begin(), temporary_terms_g1.end()); - if (!first_derivatives.empty()) - if (julia) - writeTemporaryTerms(temp_term_union, temp_term_empty, jacobian_output, output_type, tef_terms); - else - writeTemporaryTerms(temp_term_union, temp_term_union_m_1, jacobian_output, output_type, tef_terms); - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - int eq = it->first.first; - int var = it->first.second; - expr_t d1 = it->second; - - jacobianHelper(jacobian_output, eq, getDynJacobianCol(var), output_type); - jacobian_output << "="; - d1->writeOutput(jacobian_output, output_type, temp_term_union, tef_terms); - jacobian_output << ";" << endl; - } - - // Writing Hessian - temp_term_union_m_1 = temp_term_union; - temp_term_union.insert(temporary_terms_g2.begin(), temporary_terms_g2.end()); - if (!second_derivatives.empty()) - if (julia) - writeTemporaryTerms(temp_term_union, temp_term_empty, hessian_output, output_type, tef_terms); - else - writeTemporaryTerms(temp_term_union, temp_term_union_m_1, hessian_output, output_type, tef_terms); - int k = 0; // Keep the line of a 2nd derivative in v2 - for (second_derivatives_t::const_iterator it = second_derivatives.begin(); - it != second_derivatives.end(); it++) - { - int eq = it->first.first; - int var1 = it->first.second.first; - int var2 = it->first.second.second; - expr_t d2 = it->second; - - int id1 = getDynJacobianCol(var1); - int id2 = getDynJacobianCol(var2); - - int col_nb = id1 * dynJacobianColsNbr + id2; - int col_nb_sym = id2 * dynJacobianColsNbr + id1; - - ostringstream for_sym; - if (output_type == oJuliaDynamicModel) - { - for_sym << "g2[" << eq + 1 << "," << col_nb + 1 << "]"; - hessian_output << " @inbounds " << for_sym.str() << " = "; - d2->writeOutput(hessian_output, output_type, temp_term_union, tef_terms); - hessian_output << endl; - } - else - { - sparseHelper(2, hessian_output, k, 0, output_type); - hessian_output << "=" << eq + 1 << ";" << endl; - - sparseHelper(2, hessian_output, k, 1, output_type); - hessian_output << "=" << col_nb + 1 << ";" << endl; - - sparseHelper(2, hessian_output, k, 2, output_type); - hessian_output << "="; - d2->writeOutput(hessian_output, output_type, temp_term_union, tef_terms); - hessian_output << ";" << endl; - - k++; - } - - // Treating symetric elements - if (id1 != id2) - if (output_type == oJuliaDynamicModel) - hessian_output << " @inbounds g2[" << eq + 1 << "," << col_nb_sym + 1 << "] = " - << for_sym.str() << endl; - else - { - sparseHelper(2, hessian_output, k, 0, output_type); - hessian_output << "=" << eq + 1 << ";" << endl; - - sparseHelper(2, hessian_output, k, 1, output_type); - hessian_output << "=" << col_nb_sym + 1 << ";" << endl; - - sparseHelper(2, hessian_output, k, 2, output_type); - hessian_output << "="; - sparseHelper(2, hessian_output, k-1, 2, output_type); - hessian_output << ";" << endl; - - k++; - } - } - - // Writing third derivatives - temp_term_union_m_1 = temp_term_union; - temp_term_union.insert(temporary_terms_g3.begin(), temporary_terms_g3.end()); - if (!third_derivatives.empty()) - if (julia) - writeTemporaryTerms(temp_term_union, temp_term_empty, third_derivatives_output, output_type, tef_terms); - else - writeTemporaryTerms(temp_term_union, temp_term_union_m_1, third_derivatives_output, output_type, tef_terms); - k = 0; // Keep the line of a 3rd derivative in v3 - for (third_derivatives_t::const_iterator it = third_derivatives.begin(); - it != third_derivatives.end(); it++) - { - int eq = it->first.first; - int var1 = it->first.second.first; - int var2 = it->first.second.second.first; - int var3 = it->first.second.second.second; - expr_t d3 = it->second; - - int id1 = getDynJacobianCol(var1); - int id2 = getDynJacobianCol(var2); - int id3 = getDynJacobianCol(var3); - - // Reference column number for the g3 matrix - int ref_col = id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3; - - ostringstream for_sym; - if (output_type == oJuliaDynamicModel) - { - for_sym << "g3[" << eq + 1 << "," << ref_col + 1 << "]"; - third_derivatives_output << " @inbounds " << for_sym.str() << " = "; - d3->writeOutput(third_derivatives_output, output_type, temp_term_union, tef_terms); - third_derivatives_output << endl; - } - else - { - sparseHelper(3, third_derivatives_output, k, 0, output_type); - third_derivatives_output << "=" << eq + 1 << ";" << endl; - - sparseHelper(3, third_derivatives_output, k, 1, output_type); - third_derivatives_output << "=" << ref_col + 1 << ";" << endl; - - sparseHelper(3, third_derivatives_output, k, 2, output_type); - third_derivatives_output << "="; - d3->writeOutput(third_derivatives_output, output_type, temp_term_union, tef_terms); - third_derivatives_output << ";" << endl; - } - - // Compute the column numbers for the 5 other permutations of (id1,id2,id3) - // and store them in a set (to avoid duplicates if two indexes are equal) - set cols; - cols.insert(id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2); - cols.insert(id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3); - cols.insert(id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1); - cols.insert(id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2); - cols.insert(id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1); - - int k2 = 1; // Keeps the offset of the permutation relative to k - for (set::iterator it2 = cols.begin(); it2 != cols.end(); it2++) - if (*it2 != ref_col) - if (output_type == oJuliaDynamicModel) - third_derivatives_output << " @inbounds g3[" << eq + 1 << "," << *it2 + 1 << "] = " - << for_sym.str() << endl; - else - { - sparseHelper(3, third_derivatives_output, k+k2, 0, output_type); - third_derivatives_output << "=" << eq + 1 << ";" << endl; - - sparseHelper(3, third_derivatives_output, k+k2, 1, output_type); - third_derivatives_output << "=" << *it2 + 1 << ";" << endl; - - sparseHelper(3, third_derivatives_output, k+k2, 2, output_type); - third_derivatives_output << "="; - sparseHelper(3, third_derivatives_output, k, 2, output_type); - third_derivatives_output << ";" << endl; - - k2++; - } - k += k2; - } - - if (output_type == oMatlabDynamicModel) - { - // Check that we don't have more than 32 nested parenthesis because Matlab does not suppor this. See Issue #1201 - map tmp_paren_vars; - bool message_printed = false; - fixNestedParenthesis(model_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(model_local_vars_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(jacobian_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(hessian_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(third_derivatives_output, tmp_paren_vars, message_printed); - - DynamicOutput << "%" << endl - << "% Model equations" << endl - << "%" << endl - << endl - << "residual = zeros(" << nrows << ", 1);" << endl - << model_local_vars_output.str() - << model_output.str() - // Writing initialization instruction for matrix g1 - << "if nargout >= 2," << endl - << " g1 = zeros(" << nrows << ", " << dynJacobianColsNbr << ");" << endl - << endl - << " %" << endl - << " % Jacobian matrix" << endl - << " %" << endl - << endl - << jacobian_output.str() - << endl - - // Initialize g2 matrix - << "if nargout >= 3," << endl - << " %" << endl - << " % Hessian matrix" << endl - << " %" << endl - << endl; - if (second_derivatives.size()) - DynamicOutput << " v2 = zeros(" << NNZDerivatives[1] << ",3);" << endl - << hessian_output.str() - << " g2 = sparse(v2(:,1),v2(:,2),v2(:,3)," << nrows << "," << hessianColsNbr << ");" << endl; - else // Either hessian is all zero, or we didn't compute it - DynamicOutput << " g2 = sparse([],[],[]," << nrows << "," << hessianColsNbr << ");" << endl; - - // Initialize g3 matrix - DynamicOutput << "if nargout >= 4," << endl - << " %" << endl - << " % Third order derivatives" << endl - << " %" << endl - << endl; - int ncols = hessianColsNbr * dynJacobianColsNbr; - if (third_derivatives.size()) - DynamicOutput << " v3 = zeros(" << NNZDerivatives[2] << ",3);" << endl - << third_derivatives_output.str() - << " g3 = sparse(v3(:,1),v3(:,2),v3(:,3)," << nrows << "," << ncols << ");" << endl; - else // Either 3rd derivatives is all zero, or we didn't compute it - DynamicOutput << " g3 = sparse([],[],[]," << nrows << "," << ncols << ");" << endl; - - DynamicOutput << "end" << endl - << "end" << endl - << "end" << endl; - } - else if (output_type == oCDynamicModel) - { - DynamicOutput << "void Dynamic(double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, double *g1, double *v2, double *v3)" << endl - << "{" << endl - << " double lhs, rhs;" << endl - << endl - << " /* Residual equations */" << endl - << model_local_vars_output.str() - << model_output.str() - << " /* Jacobian */" << endl - << " if (g1 == NULL)" << endl - << " return;" << endl - << endl - << jacobian_output.str() - << endl; - - if (second_derivatives.size()) - DynamicOutput << " /* Hessian for endogenous and exogenous variables */" << endl - << " if (v2 == NULL)" << endl - << " return;" << endl - << endl - << hessian_output.str() - << endl; - - if (third_derivatives.size()) - DynamicOutput << " /* Third derivatives for endogenous and exogenous variables */" << endl - << " if (v3 == NULL)" << endl - << " return;" << endl - << endl - << third_derivatives_output.str() - << endl; - - DynamicOutput << "}" << endl << endl; - } - else - { - ostringstream comments; - comments << "## Function Arguments" << endl - << endl - << "## Input" << endl - << " 1 y: Array{Float64, num_dynamic_vars, 1} Vector of endogenous variables in the order stored" << endl - << " in model_.lead_lag_incidence; see the manual" << endl - << " 2 x: Array{Float64, nperiods, length(model_.exo)} Matrix of exogenous variables (in declaration order)" << endl - << " for all simulation periods" << endl - << " 3 params: Array{Float64, length(model_.param), 1} Vector of parameter values in declaration order" << endl - << " 4 steady_state:" << endl - << " 5 it_: Int Time period for exogenous variables for which to evaluate the model" << endl - << endl - << "## Output" << endl - << " 6 residual: Array(Float64, model_.eq_nbr, 1) Vector of residuals of the dynamic model equations in" << endl - << " order of declaration of the equations." << endl; - - DynamicOutput << "function dynamic!(y::Vector{Float64}, x::Matrix{Float64}, " - << "params::Vector{Float64}," << endl - << " steady_state::Vector{Float64}, it_::Int, " - << "residual::Vector{Float64})" << endl - << "#=" << endl << comments.str() << "=#" << endl - << " @assert length(y)+size(x, 2) == " << dynJacobianColsNbr << endl - << " @assert length(params) == " << symbol_table.param_nbr() << endl - << " @assert length(residual) == " << nrows << endl - << " #" << endl - << " # Model equations" << endl - << " #" << endl - << model_local_vars_output.str() - << model_output.str() - << "end" << endl << endl - << "function dynamic!(y::Vector{Float64}, x::Matrix{Float64}, " - << "params::Vector{Float64}," << endl - << " steady_state::Vector{Float64}, it_::Int, " - << "residual::Vector{Float64}," << endl - << " g1::Matrix{Float64})" << endl; - - comments << " 7 g1: Array(Float64, model_.eq_nbr, num_dynamic_vars) Jacobian matrix of the dynamic model equations;" << endl - << " rows: equations in order of declaration" << endl - << " columns: variables in order stored in model_.lead_lag_incidence" << endl; - - DynamicOutput << "#=" << endl << comments.str() << "=#" << endl - << " @assert size(g1) == (" << nrows << ", " << dynJacobianColsNbr << ")" << endl - << " fill!(g1, 0.0)" << endl - << " dynamic!(y, x, params, steady_state, it_, residual)" << endl - << model_local_vars_output.str() - << " #" << endl - << " # Jacobian matrix" << endl - << " #" << endl - << jacobian_output.str() - << "end" << endl << endl - << "function dynamic!(y::Vector{Float64}, x::Matrix{Float64}, " - << "params::Vector{Float64}," << endl - << " steady_state::Vector{Float64}, it_::Int, " - << "residual::Vector{Float64}," << endl - << " g1::Matrix{Float64}, g2::Matrix{Float64})" << endl; - - comments << " 8 g2: spzeros(model_.eq_nbr, (num_dynamic_vars)^2) Hessian matrix of the dynamic model equations;" << endl - << " rows: equations in order of declaration" << endl - << " columns: variables in order stored in model_.lead_lag_incidence" << endl; - - DynamicOutput << "#=" << endl << comments.str() << "=#" << endl - << " @assert size(g2) == (" << nrows << ", " << hessianColsNbr << ")" << endl - << " fill!(g2, 0.0)" << endl - << " dynamic!(y, x, params, steady_state, it_, residual, g1)" << endl; - if (second_derivatives.size()) - DynamicOutput << model_local_vars_output.str() - << " #" << endl - << " # Hessian matrix" << endl - << " #" << endl - << hessian_output.str(); - - // Initialize g3 matrix - int ncols = hessianColsNbr * dynJacobianColsNbr; - DynamicOutput << "end" << endl << endl - << "function dynamic!(y::Vector{Float64}, x::Matrix{Float64}, " - << "params::Vector{Float64}," << endl - << " steady_state::Vector{Float64}, it_::Int, " - << "residual::Vector{Float64}," << endl - << " g1::Matrix{Float64}, g2::Matrix{Float64}, g3::Matrix{Float64})" << endl; - - comments << " 9 g3: spzeros(model_.eq_nbr, (num_dynamic_vars)^3) Third order derivative matrix of the dynamic model equations;" << endl - << " rows: equations in order of declaration" << endl - << " columns: variables in order stored in model_.lead_lag_incidence" << endl; - - DynamicOutput << "#=" << endl << comments.str() << "=#" << endl - << " @assert size(g3) == (" << nrows << ", " << ncols << ")" << endl - << " fill!(g3, 0.0)" << endl - << " dynamic!(y, x, params, steady_state, it_, residual, g1, g2)" << endl; - if (third_derivatives.size()) - DynamicOutput << model_local_vars_output.str() - << " #" << endl - << " # Third order derivatives" << endl - << " #" << endl - << third_derivatives_output.str(); - DynamicOutput << "end" << endl; - } -} - -void -DynamicModel::writeOutput(ostream &output, const string &basename, bool block_decomposition, bool byte_code, bool use_dll, int order, bool estimation_present, bool compute_xrefs, bool julia) const -{ - /* Writing initialisation for M_.lead_lag_incidence matrix - M_.lead_lag_incidence is a matrix with as many columns as there are - endogenous variables and as many rows as there are periods in the - models (nbr of rows = M_.max_lag+M_.max_lead+1) - - The matrix elements are equal to zero if a variable isn't present in the - model at a given period. - */ - - string modstruct; - string outstruct; - if (julia) - { - modstruct = "model_."; - outstruct = "oo_."; - } - else - { - modstruct = "M_."; - outstruct = "oo_."; - } - - output << modstruct << "max_endo_lag_orig = " << max_endo_lag_orig << ";" << endl - << modstruct << "max_endo_lead_orig = " << max_endo_lead_orig << ";" << endl - << modstruct << "max_exo_lag_orig = " << max_exo_lag_orig << ";" << endl - << modstruct << "max_exo_lead_orig = " << max_exo_lead_orig << ";" << endl - << modstruct << "max_exo_det_lag_orig = " << max_exo_det_lag_orig << ";" << endl - << modstruct << "max_exo_det_lead_orig = " << max_exo_det_lead_orig << ";" << endl - << modstruct << "max_lag_orig = " << max_lag_orig << ";" << endl - << modstruct << "max_lead_orig = " << max_lead_orig << ";" << endl - << modstruct << "lead_lag_incidence = ["; - // Loop on endogenous variables - int nstatic = 0, - nfwrd = 0, - npred = 0, - nboth = 0; - for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++) - { - output << endl; - int sstatic = 1, - sfwrd = 0, - spred = 0, - sboth = 0; - // Loop on periods - for (int lag = -max_endo_lag; lag <= max_endo_lead; lag++) - { - // Print variableID if exists with current period, otherwise print 0 - try - { - int varID = getDerivID(symbol_table.getID(eEndogenous, endoID), lag); - output << " " << getDynJacobianCol(varID) + 1; - if (lag == -1) - { - sstatic = 0; - spred = 1; - } - else if (lag == 1) - { - if (spred == 1) - { - sboth = 1; - spred = 0; - } - else - { - sstatic = 0; - sfwrd = 1; - } - } - } - catch (UnknownDerivIDException &e) - { - output << " 0"; - } - } - nstatic += sstatic; - nfwrd += sfwrd; - npred += spred; - nboth += sboth; - output << ";"; - } - output << "]';" << endl; - output << modstruct << "nstatic = " << nstatic << ";" << endl - << modstruct << "nfwrd = " << nfwrd << ";" << endl - << modstruct << "npred = " << npred << ";" << endl - << modstruct << "nboth = " << nboth << ";" << endl - << modstruct << "nsfwrd = " << nfwrd+nboth << ";" << endl - << modstruct << "nspred = " << npred+nboth << ";" << endl - << modstruct << "ndynamic = " << npred+nboth+nfwrd << ";" << endl; - - // Write equation tags - if (julia) - { - output << modstruct << "equation_tags = [" << endl; - for (size_t i = 0; i < equation_tags.size(); i++) - output << " EquationTag(" - << equation_tags[i].first + 1 << " , \"" - << equation_tags[i].second.first << "\" , \"" - << equation_tags[i].second.second << "\")" << endl; - output << " ]" << endl; - } - else - { - output << modstruct << "equations_tags = {" << endl; - for (size_t i = 0; i < equation_tags.size(); i++) - output << " " << equation_tags[i].first + 1 << " , '" - << equation_tags[i].second.first << "' , '" - << equation_tags[i].second.second << "' ;" << endl; - output << "};" << endl; - } - - /* Say if static and dynamic models differ (because of [static] and [dynamic] - equation tags) */ - output << modstruct << "static_and_dynamic_models_differ = " - << (static_only_equations.size() > 0 ? - (julia ? "true" : "1") : - (julia ? "false" : "0")) - << ";" << endl; - - vector state_var; - for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++) - // Loop on periods - for (int lag = -max_endo_lag; lag < 0; lag++) - try - { - getDerivID(symbol_table.getID(eEndogenous, variable_reordered[endoID]), lag); - if (lag < 0 && find(state_var.begin(), state_var.end(), variable_reordered[endoID]+1) == state_var.end()) - state_var.push_back(variable_reordered[endoID]+1); - } - catch (UnknownDerivIDException &e) - { - } - - //In case of sparse model, writes the block_decomposition structure of the model - if (block_decomposition) - { - vector state_equ; - int count_lead_lag_incidence = 0; - int max_lead, max_lag, max_lag_endo, max_lead_endo, max_lag_exo, max_lead_exo, max_lag_exo_det, max_lead_exo_det; - unsigned int nb_blocks = getNbBlocks(); - for (unsigned int block = 0; block < nb_blocks; block++) - { - //For a block composed of a single equation determines wether we have to evaluate or to solve the equation - count_lead_lag_incidence = 0; - BlockSimulationType simulation_type = getBlockSimulationType(block); - int block_size = getBlockSize(block); - max_lag = max_leadlag_block[block].first; - max_lead = max_leadlag_block[block].second; - max_lag_endo = endo_max_leadlag_block[block].first; - max_lead_endo = endo_max_leadlag_block[block].second; - max_lag_exo = exo_max_leadlag_block[block].first; - max_lead_exo = exo_max_leadlag_block[block].second; - max_lag_exo_det = exo_det_max_leadlag_block[block].first; - max_lead_exo_det = exo_det_max_leadlag_block[block].second; - ostringstream tmp_s, tmp_s_eq; - tmp_s.str(""); - tmp_s_eq.str(""); - for (int i = 0; i < block_size; i++) - { - tmp_s << " " << getBlockVariableID(block, i)+1; - tmp_s_eq << " " << getBlockEquationID(block, i)+1; - } - set exogenous; - exogenous.clear(); - for (lag_var_t::const_iterator it = exo_block[block].begin(); it != exo_block[block].end(); it++) - for (var_t::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) - exogenous.insert(*it1); - set exogenous_det; - exogenous_det.clear(); - for (lag_var_t::const_iterator it = exo_det_block[block].begin(); it != exo_det_block[block].end(); it++) - for (var_t::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) - exogenous_det.insert(*it1); - set other_endogenous; - other_endogenous.clear(); - for (lag_var_t::const_iterator it = other_endo_block[block].begin(); it != other_endo_block[block].end(); it++) - for (var_t::const_iterator it1 = it->second.begin(); it1 != it->second.end(); it1++) - other_endogenous.insert(*it1); - output << "block_structure.block(" << block+1 << ").Simulation_Type = " << simulation_type << ";\n"; - output << "block_structure.block(" << block+1 << ").maximum_lag = " << max_lag << ";\n"; - output << "block_structure.block(" << block+1 << ").maximum_lead = " << max_lead << ";\n"; - output << "block_structure.block(" << block+1 << ").maximum_endo_lag = " << max_lag_endo << ";\n"; - output << "block_structure.block(" << block+1 << ").maximum_endo_lead = " << max_lead_endo << ";\n"; - output << "block_structure.block(" << block+1 << ").maximum_exo_lag = " << max_lag_exo << ";\n"; - output << "block_structure.block(" << block+1 << ").maximum_exo_lead = " << max_lead_exo << ";\n"; - output << "block_structure.block(" << block+1 << ").maximum_exo_det_lag = " << max_lag_exo_det << ";\n"; - output << "block_structure.block(" << block+1 << ").maximum_exo_det_lead = " << max_lead_exo_det << ";\n"; - output << "block_structure.block(" << block+1 << ").endo_nbr = " << block_size << ";\n"; - output << "block_structure.block(" << block+1 << ").mfs = " << getBlockMfs(block) << ";\n"; - output << "block_structure.block(" << block+1 << ").equation = [" << tmp_s_eq.str() << "];\n"; - output << "block_structure.block(" << block+1 << ").variable = [" << tmp_s.str() << "];\n"; - output << "block_structure.block(" << block+1 << ").exo_nbr = " << getBlockExoSize(block) << ";\n"; - output << "block_structure.block(" << block+1 << ").exogenous = ["; - int i = 0; - for (set::iterator it_exogenous = exogenous.begin(); it_exogenous != exogenous.end(); it_exogenous++) - if (*it_exogenous >= 0) - { - output << " " << *it_exogenous+1; - i++; - } - output << "];\n"; - - output << "block_structure.block(" << block+1 << ").exogenous_det = ["; - i = 0; - for (set::iterator it_exogenous_det = exogenous_det.begin(); it_exogenous_det != exogenous_det.end(); it_exogenous_det++) - if (*it_exogenous_det >= 0) - { - output << " " << *it_exogenous_det+1; - i++; - } - output << "];\n"; - output << "block_structure.block(" << block+1 << ").exo_det_nbr = " << i << ";\n"; - - output << "block_structure.block(" << block+1 << ").other_endogenous = ["; - i = 0; - for (set::iterator it_other_endogenous = other_endogenous.begin(); it_other_endogenous != other_endogenous.end(); it_other_endogenous++) - if (*it_other_endogenous >= 0) - { - output << " " << *it_other_endogenous+1; - i++; - } - output << "];\n"; - output << "block_structure.block(" << block+1 << ").other_endogenous_block = ["; - i = 0; - for (set::iterator it_other_endogenous = other_endogenous.begin(); it_other_endogenous != other_endogenous.end(); it_other_endogenous++) - if (*it_other_endogenous >= 0) - { - bool OK = true; - unsigned int j; - for (j = 0; j < block && OK; j++) - for (unsigned int k = 0; k < getBlockSize(j) && OK; k++) - { - //printf("*it_other_endogenous=%d, getBlockVariableID(%d, %d)=%d\n",*it_other_endogenous, j, k, getBlockVariableID(j, k)); - OK = *it_other_endogenous != getBlockVariableID(j, k); - } - if (!OK) - output << " " << j; - i++; - } - output << "];\n"; - - //vector inter_state_var; - output << "block_structure.block(" << block+1 << ").tm1 = zeros(" << i << ", " << state_var.size() << ");\n"; - int count_other_endogenous = 1; - for (set::const_iterator it_other_endogenous = other_endogenous.begin(); it_other_endogenous != other_endogenous.end(); it_other_endogenous++) - { - for (vector::const_iterator it = state_var.begin(); it != state_var.end(); it++) - { - //cout << "block = " << block+1 << " state_var = " << *it << " it_other_endogenous=" << *it_other_endogenous + 1 << "\n"; - if (*it == *it_other_endogenous + 1) - { - output << "block_structure.block(" << block+1 << ").tm1(" - << count_other_endogenous << ", " - << it - state_var.begin()+1 << ") = 1;\n"; - /*output << "block_structure.block(" << block+1 << ").tm1(" - << it - state_var.begin()+1 << ", " - << count_other_endogenous << ") = 1;\n";*/ - //cout << "=>\n"; - } - } - count_other_endogenous++; - } - - output << "block_structure.block(" << block+1 << ").other_endo_nbr = " << i << ";\n"; - - tmp_s.str(""); - count_lead_lag_incidence = 0; - dynamic_jacob_map_t reordered_dynamic_jacobian; - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != blocks_derivatives[block].end(); it++) - reordered_dynamic_jacobian[make_pair(it->second.first, make_pair(it->first.second, it->first.first))] = it->second.second; - output << "block_structure.block(" << block+1 << ").lead_lag_incidence = [];\n"; - int last_var = -1; - vector local_state_var; - vector local_stat_var; - int n_static = 0, n_backward = 0, n_forward = 0, n_mixed = 0; - for (int lag = -1; lag < 1+1; lag++) - { - last_var = -1; - for (dynamic_jacob_map_t::const_iterator it = reordered_dynamic_jacobian.begin(); it != reordered_dynamic_jacobian.end(); it++) - { - if (lag == it->first.first && last_var != it->first.second.first) - { - if (lag == -1) - { - local_state_var.push_back(getBlockVariableID(block, it->first.second.first)+1); - n_backward++; - } - else if (lag == 0) - { - if (find(local_state_var.begin(), local_state_var.end(), getBlockVariableID(block, it->first.second.first)+1) == local_state_var.end()) - { - local_stat_var.push_back(getBlockVariableID(block, it->first.second.first)+1); - n_static++; - } - } - else - { - if (find(local_state_var.begin(), local_state_var.end(), getBlockVariableID(block, it->first.second.first)+1) != local_state_var.end()) - { - n_backward--; - n_mixed++; - } - else - { - if (find(local_stat_var.begin(), local_stat_var.end(), getBlockVariableID(block, it->first.second.first)+1) != local_stat_var.end()) - n_static--; - n_forward++; - } - } - count_lead_lag_incidence++; - for (int i = last_var; i < it->first.second.first-1; i++) - tmp_s << " 0"; - if (tmp_s.str().length()) - tmp_s << " "; - tmp_s << count_lead_lag_incidence; - last_var = it->first.second.first; - } - } - for (int i = last_var + 1; i < block_size; i++) - tmp_s << " 0"; - output << "block_structure.block(" << block+1 << ").lead_lag_incidence = [ block_structure.block(" << block+1 << ").lead_lag_incidence; " << tmp_s.str() << "]; %lag = " << lag << "\n"; - tmp_s.str(""); - } - vector inter_state_var; - for (vector::const_iterator it_l = local_state_var.begin(); it_l != local_state_var.end(); it_l++) - for (vector::const_iterator it = state_var.begin(); it != state_var.end(); it++) - if (*it == *it_l) - inter_state_var.push_back(it - state_var.begin()+1); - output << "block_structure.block(" << block+1 << ").sorted_col_dr_ghx = ["; - for (vector::const_iterator it = inter_state_var.begin(); it != inter_state_var.end(); it++) - output << *it << " "; - output << "];\n"; - count_lead_lag_incidence = 0; - output << "block_structure.block(" << block+1 << ").lead_lag_incidence_other = [];\n"; - for (int lag = -1; lag <= 1; lag++) - { - tmp_s.str(""); - for (set::iterator it_other_endogenous = other_endogenous.begin(); it_other_endogenous != other_endogenous.end(); it_other_endogenous++) - { - bool done = false; - for (int i = 0; i < block_size; i++) - { - unsigned int eq = getBlockEquationID(block, i); - derivative_t::const_iterator it = derivative_other_endo[block].find(make_pair(lag, make_pair(eq, *it_other_endogenous))); - if (it != derivative_other_endo[block].end()) - { - count_lead_lag_incidence++; - tmp_s << " " << count_lead_lag_incidence; - done = true; - break; - } - } - if (!done) - tmp_s << " 0"; - } - output << "block_structure.block(" << block+1 << ").lead_lag_incidence_other = [ block_structure.block(" << block+1 << ").lead_lag_incidence_other; " << tmp_s.str() << "]; %lag = " << lag << "\n"; - } - output << "block_structure.block(" << block+1 << ").n_static = " << n_static << ";\n"; - output << "block_structure.block(" << block+1 << ").n_forward = " << n_forward << ";\n"; - output << "block_structure.block(" << block+1 << ").n_backward = " << n_backward << ";\n"; - output << "block_structure.block(" << block+1 << ").n_mixed = " << n_mixed << ";\n"; - } - output << modstruct << "block_structure.block = block_structure.block;\n"; - string cst_s; - int nb_endo = symbol_table.endo_nbr(); - output << modstruct << "block_structure.variable_reordered = ["; - for (int i = 0; i < nb_endo; i++) - output << " " << variable_reordered[i]+1; - output << "];\n"; - output << modstruct << "block_structure.equation_reordered = ["; - for (int i = 0; i < nb_endo; i++) - output << " " << equation_reordered[i]+1; - output << "];\n"; - vector variable_inv_reordered(nb_endo); - - for (int i = 0; i < nb_endo; i++) - variable_inv_reordered[variable_reordered[i]] = i; - - for (vector::const_iterator it = state_var.begin(); it != state_var.end(); it++) - state_equ.push_back(equation_reordered[variable_inv_reordered[*it - 1]]+1); - - map >, int> lag_row_incidence; - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - int deriv_id = it->first.second; - if (getTypeByDerivID(deriv_id) == eEndogenous) - { - int eq = it->first.first; - int symb = getSymbIDByDerivID(deriv_id); - int var = symbol_table.getTypeSpecificID(symb); - int lag = getLagByDerivID(deriv_id); - lag_row_incidence[make_pair(lag, make_pair(eq, var))] = 1; - } - } - int prev_lag = -1000000; - for (map >, int>::const_iterator it = lag_row_incidence.begin(); it != lag_row_incidence.end(); it++) - { - if (prev_lag != it->first.first) - { - if (prev_lag != -1000000) - output << "];\n"; - prev_lag = it->first.first; - output << modstruct << "block_structure.incidence(" << max_endo_lag+it->first.first+1 << ").lead_lag = " << prev_lag << ";\n"; - output << modstruct << "block_structure.incidence(" << max_endo_lag+it->first.first+1 << ").sparse_IM = ["; - } - output << it->first.second.first+1 << " " << it->first.second.second+1 << ";\n"; - } - output << "];\n"; - if (estimation_present) - { - ofstream KF_index_file; - string main_name = basename; - main_name += ".kfi"; - KF_index_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate); - int n_obs = symbol_table.observedVariablesNbr(); - int n_state = state_var.size(); - for (vector::const_iterator it = state_var.begin(); it != state_var.end(); it++) - if (symbol_table.isObservedVariable(symbol_table.getID(eEndogenous, *it-1))) - n_obs--; - - int n = n_obs + n_state; - output << modstruct << "nobs_non_statevar = " << n_obs << ";" << endl; - int nb_diag = 0; - //map, int>::const_iterator row_state_var_incidence_it = row_state_var_incidence.begin(); - - vector i_nz_state_var(n); - for (int i = 0; i < n_obs; i++) - i_nz_state_var[i] = n; - unsigned int lp = n_obs; - - for (unsigned int block = 0; block < nb_blocks; block++) - { - int block_size = getBlockSize(block); - int nze = 0; - - for (int i = 0; i < block_size; i++) - { - int var = getBlockVariableID(block, i); - vector::const_iterator it_state_var = find(state_var.begin(), state_var.end(), var+1); - if (it_state_var != state_var.end()) - nze++; - } - if (block == 0) - { - set > row_state_var_incidence; - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - { - vector::const_iterator it_state_var = find(state_var.begin(), state_var.end(), getBlockVariableID(block, it->first.second)+1); - if (it_state_var != state_var.end()) - { - vector::const_iterator it_state_equ = find(state_equ.begin(), state_equ.end(), getBlockEquationID(block, it->first.first)+1); - if (it_state_equ != state_equ.end()) - row_state_var_incidence.insert(make_pair(it_state_equ - state_equ.begin(), it_state_var - state_var.begin())); - } - - } - /*tmp_block_endo_derivative[make_pair(it->second.first, make_pair(it->first.second, it->first.first))] = it->second.second; - if (block == 0) - { - - vector::const_iterator it_state_equ = find(state_equ.begin(), state_equ.end(), getBlockEquationID(block, i)+1); - if (it_state_equ != state_equ.end()) - { - cout << "row_state_var_incidence[make_pair([" << *it_state_equ << "] " << it_state_equ - state_equ.begin() << ", [" << *it_state_var << "] " << it_state_var - state_var.begin() << ")] = 1;\n"; - row_state_var_incidence.insert(make_pair(it_state_equ - state_equ.begin(), it_state_var - state_var.begin())); - } - }*/ - set >::const_iterator row_state_var_incidence_it = row_state_var_incidence.begin(); - bool diag = true; - int nb_diag_r = 0; - while (row_state_var_incidence_it != row_state_var_incidence.end() && diag) - { - diag = (row_state_var_incidence_it->first == row_state_var_incidence_it->second); - if (diag) - { - int equ = row_state_var_incidence_it->first; - row_state_var_incidence_it++; - if (equ != row_state_var_incidence_it->first) - nb_diag_r++; - } - - } - set > col_state_var_incidence; - for (set >::const_iterator row_state_var_incidence_it = row_state_var_incidence.begin(); row_state_var_incidence_it != row_state_var_incidence.end(); row_state_var_incidence_it++) - col_state_var_incidence.insert(make_pair(row_state_var_incidence_it->second, row_state_var_incidence_it->first)); - set >::const_iterator col_state_var_incidence_it = col_state_var_incidence.begin(); - diag = true; - int nb_diag_c = 0; - while (col_state_var_incidence_it != col_state_var_incidence.end() && diag) - { - diag = (col_state_var_incidence_it->first == col_state_var_incidence_it->second); - if (diag) - { - int var = col_state_var_incidence_it->first; - col_state_var_incidence_it++; - if (var != col_state_var_incidence_it->first) - nb_diag_c++; - } - } - nb_diag = min(nb_diag_r, nb_diag_c); - row_state_var_incidence.clear(); - col_state_var_incidence.clear(); - } - for (int i = 0; i < nze; i++) - i_nz_state_var[lp + i] = lp + nze; - lp += nze; - } - output << modstruct << "nz_state_var = ["; - for (unsigned int i = 0; i < lp; i++) - output << i_nz_state_var[i] << " "; - output << "];" << endl; - output << modstruct << "n_diag = " << nb_diag << ";" << endl; - KF_index_file.write(reinterpret_cast(&nb_diag), sizeof(nb_diag)); - - typedef pair > index_KF; - vector v_index_KF; - for (int i = 0; i < n; i++) - //int i = 0; - for (int j = n_obs; j < n; j++) - { - int j1 = j - n_obs; - int j1_n_state = j1 * n_state - n_obs; - if ((i < n_obs) || (i >= nb_diag + n_obs) || (j1 >= nb_diag)) - for (int k = n_obs; k < i_nz_state_var[i]; k++) - { - v_index_KF.push_back(make_pair(i + j1 * n, make_pair(i + k * n, k + j1_n_state))); - } - } - int size_v_index_KF = v_index_KF.size(); - - KF_index_file.write(reinterpret_cast(&size_v_index_KF), sizeof(size_v_index_KF)); - for (vector::iterator it = v_index_KF.begin(); it != v_index_KF.end(); it++) - KF_index_file.write(reinterpret_cast(&(*it)), sizeof(index_KF)); - - vector v_index_KF_2; - int n_n_obs = n * n_obs; - for (int i = 0; i < n; i++) - //i = 0; - for (int j = i; j < n; j++) - { - if ((i < n_obs) || (i >= nb_diag + n_obs) || (j < n_obs) || (j >= nb_diag + n_obs)) - for (int k = n_obs; k < i_nz_state_var[j]; k++) - { - int k_n = k * n; - v_index_KF_2.push_back(make_pair(i * n + j, make_pair(i + k_n - n_n_obs, j + k_n))); - } - } - int size_v_index_KF_2 = v_index_KF_2.size(); - - KF_index_file.write(reinterpret_cast(&size_v_index_KF_2), sizeof(size_v_index_KF_2)); - for (vector::iterator it = v_index_KF_2.begin(); it != v_index_KF_2.end(); it++) - KF_index_file.write(reinterpret_cast(&(*it)), sizeof(index_KF)); - KF_index_file.close(); - } - } - - output << modstruct << "state_var = ["; - for (vector::const_iterator it=state_var.begin(); it != state_var.end(); it++) - output << *it << " "; - output << "];" << endl; - - // Writing initialization for some other variables - if (!julia) - output << modstruct << "exo_names_orig_ord = [1:" << symbol_table.exo_nbr() << "];" << endl; - else - output << modstruct << "exo_names_orig_ord = collect(1:" << symbol_table.exo_nbr() << ");" << endl; - - output << modstruct << "maximum_lag = " << max_lag << ";" << endl - << modstruct << "maximum_lead = " << max_lead << ";" << endl; - - output << modstruct << "maximum_endo_lag = " << max_endo_lag << ";" << endl - << modstruct << "maximum_endo_lead = " << max_endo_lead << ";" << endl - << outstruct << "steady_state = zeros(" << symbol_table.endo_nbr() << (julia ? ")" : ", 1);") << endl; - - output << modstruct << "maximum_exo_lag = " << max_exo_lag << ";" << endl - << modstruct << "maximum_exo_lead = " << max_exo_lead << ";" << endl - << outstruct << "exo_steady_state = zeros(" << symbol_table.exo_nbr() << (julia ? ")" : ", 1);") << endl; - - if (symbol_table.exo_det_nbr()) - { - output << modstruct << "maximum_exo_det_lag = " << max_exo_det_lag << ";" << endl - << modstruct << "maximum_exo_det_lead = " << max_exo_det_lead << ";" << endl - << outstruct << "exo_det_steady_state = zeros(" << symbol_table.exo_det_nbr() << (julia ? ")" : ", 1);") << endl; - } - - output << modstruct << "params = " << (julia ? "fill(NaN, " : "NaN(") - << symbol_table.param_nbr() << (julia ? ")" : ", 1);") << endl; - - if (compute_xrefs) - writeXrefs(output); - - // Write number of non-zero derivatives - // Use -1 if the derivatives have not been computed - output << modstruct << (julia ? "nnzderivatives" : "NNZDerivatives") - << " = [" << NNZDerivatives[0] << "; "; - if (order > 1) - output << NNZDerivatives[1] << "; "; - else - output << "-1; "; - - if (order > 2) - output << NNZDerivatives[2]; - else - output << "-1"; - output << "];" << endl; -} - -map >, expr_t> -DynamicModel::collect_first_order_derivatives_endogenous() -{ - map >, expr_t> endo_derivatives; - for (first_derivatives_t::iterator it2 = first_derivatives.begin(); - it2 != first_derivatives.end(); it2++) - { - if (getTypeByDerivID(it2->first.second) == eEndogenous) - { - int eq = it2->first.first; - int var = symbol_table.getTypeSpecificID(getSymbIDByDerivID(it2->first.second)); - int lag = getLagByDerivID(it2->first.second); - endo_derivatives[make_pair(eq, make_pair(var, lag))] = it2->second; - } - } - return endo_derivatives; -} - -void -DynamicModel::runTrendTest(const eval_context_t &eval_context) -{ - computeDerivIDs(); - testTrendDerivativesEqualToZero(eval_context); -} - -void -DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, int paramsDerivsOrder, - const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, - bool bytecode, const bool nopreprocessoroutput) -{ - assert(jacobianExo || !(hessian || thirdDerivatives || paramsDerivsOrder)); - - initializeVariablesAndEquations(); - - // Prepare for derivation - computeDerivIDs(); - - // Computes dynamic jacobian columns, must be done after computeDerivIDs() - computeDynJacobianCols(jacobianExo); - - // Compute derivatives w.r. to all endogenous, and possibly exogenous and exogenous deterministic - set vars; - for (deriv_id_table_t::const_iterator it = deriv_id_table.begin(); - it != deriv_id_table.end(); it++) - { - SymbolType type = symbol_table.getType(it->first.first); - if (type == eEndogenous || (jacobianExo && (type == eExogenous || type == eExogenousDet))) - vars.insert(it->second); - } - - // Launch computations - if (!nopreprocessoroutput) - cout << "Computing dynamic model derivatives:" << endl - << " - order 1" << endl; - computeJacobian(vars); - - if (hessian) - { - if (!nopreprocessoroutput) - cout << " - order 2" << endl; - computeHessian(vars); - } - - if (paramsDerivsOrder > 0) - { - if (!nopreprocessoroutput) - cout << " - derivatives of Jacobian/Hessian w.r. to parameters" << endl; - computeParamsDerivatives(paramsDerivsOrder); - - if (!no_tmp_terms) - computeParamsDerivativesTemporaryTerms(); - } - - if (thirdDerivatives) - { - if (!nopreprocessoroutput) - cout << " - order 3" << endl; - computeThirdDerivatives(vars); - } - - if (block) - { - vector n_static, n_forward, n_backward, n_mixed; - jacob_map_t contemporaneous_jacobian, static_jacobian; - - // for each block contains pair - vector > blocks; - - evaluateAndReduceJacobian(eval_context, contemporaneous_jacobian, static_jacobian, dynamic_jacobian, cutoff, false); - - computeNonSingularNormalization(contemporaneous_jacobian, cutoff, static_jacobian, dynamic_jacobian); - - computePrologueAndEpilogue(static_jacobian, equation_reordered, variable_reordered); - - map >, expr_t> first_order_endo_derivatives = collect_first_order_derivatives_endogenous(); - - equation_type_and_normalized_equation = equationTypeDetermination(first_order_endo_derivatives, variable_reordered, equation_reordered, mfs); - - if (!nopreprocessoroutput) - cout << "Finding the optimal block decomposition of the model ...\n"; - - lag_lead_vector_t equation_lag_lead, variable_lag_lead; - - computeBlockDecompositionAndFeedbackVariablesForEachBlock(static_jacobian, dynamic_jacobian, equation_reordered, variable_reordered, blocks, equation_type_and_normalized_equation, false, true, mfs, inv_equation_reordered, inv_variable_reordered, equation_lag_lead, variable_lag_lead, n_static, n_forward, n_backward, n_mixed); - - block_type_firstequation_size_mfs = reduceBlocksAndTypeDetermination(dynamic_jacobian, blocks, equation_type_and_normalized_equation, variable_reordered, equation_reordered, n_static, n_forward, n_backward, n_mixed, block_col_type); - - printBlockDecomposition(blocks); - - computeChainRuleJacobian(blocks_derivatives); - - blocks_linear = BlockLinear(blocks_derivatives, variable_reordered); - - collect_block_first_order_derivatives(); - - collectBlockVariables(); - - global_temporary_terms = true; - if (!no_tmp_terms) - computeTemporaryTermsOrdered(); - int k = 0; - equation_block = vector(equations.size()); - variable_block_lead_lag = vector< pair< int, pair< int, int> > >(equations.size()); - for (unsigned int i = 0; i < getNbBlocks(); i++) - { - for (unsigned int j = 0; j < getBlockSize(i); j++) - { - equation_block[equation_reordered[k]] = i; - int l = variable_reordered[k]; - variable_block_lead_lag[l] = make_pair(i, make_pair(variable_lag_lead[l].first, variable_lag_lead[l].second)); - k++; - } - } - } - else - if (!no_tmp_terms) - { - computeTemporaryTerms(!use_dll); - if (bytecode) - computeTemporaryTermsMapping(); - } -} - -void -DynamicModel::computeXrefs() -{ - int i = 0; - for (vector::iterator it = equations.begin(); - it != equations.end(); it++) - { - ExprNode::EquationInfo ei; - (*it)->computeXrefs(ei); - xrefs[i++] = ei; - } - - i = 0; - for (map::const_iterator it = xrefs.begin(); - it != xrefs.end(); it++, i++) - { - computeRevXref(xref_param, it->second.param, i); - computeRevXref(xref_endo, it->second.endo, i); - computeRevXref(xref_exo, it->second.exo, i); - computeRevXref(xref_exo_det, it->second.exo_det, i); - } -} - -void -DynamicModel::computeRevXref(map, set > &xrefset, const set > &eiref, int eqn) -{ - for (set >::const_iterator it = eiref.begin(); - it != eiref.end(); it++) - { - set eq; - if (xrefset.find(*it) != xrefset.end()) - eq = xrefset[*it]; - eq.insert(eqn); - xrefset[*it] = eq; - } -} - -void -DynamicModel::writeXrefs(ostream &output) const -{ - output << "M_.xref1.param = cell(1, M_.eq_nbr);" << endl - << "M_.xref1.endo = cell(1, M_.eq_nbr);" << endl - << "M_.xref1.exo = cell(1, M_.eq_nbr);" << endl - << "M_.xref1.exo_det = cell(1, M_.eq_nbr);" << endl; - int i = 1; - for (map::const_iterator it = xrefs.begin(); - it != xrefs.end(); it++, i++) - { - output << "M_.xref1.param{" << i << "} = [ "; - for (set >::const_iterator it1 = it->second.param.begin(); - it1 != it->second.param.end(); it1++) - output << symbol_table.getTypeSpecificID(it1->first) + 1 << " "; - output << "];" << endl; - - output << "M_.xref1.endo{" << i << "} = [ "; - for (set >::const_iterator it1 = it->second.endo.begin(); - it1 != it->second.endo.end(); it1++) - output << "struct('id', " << symbol_table.getTypeSpecificID(it1->first) + 1 << ", 'shift', " << it1->second << ");"; - output << "];" << endl; - - output << "M_.xref1.exo{" << i << "} = [ "; - for (set >::const_iterator it1 = it->second.exo.begin(); - it1 != it->second.exo.end(); it1++) - output << "struct('id', " << symbol_table.getTypeSpecificID(it1->first) + 1 << ", 'shift', " << it1->second << ");"; - output << "];" << endl; - - output << "M_.xref1.exo_det{" << i << "} = [ "; - for (set >::const_iterator it1 = it->second.exo_det.begin(); - it1 != it->second.exo_det.end(); it1++) - output << "struct('id', " << symbol_table.getTypeSpecificID(it1->first) + 1 << ", 'shift', " << it1->second << ");"; - output << "];" << endl; - } - - output << "M_.xref2.param = cell(1, M_.param_nbr);" << endl - << "M_.xref2.endo = cell(1, M_.endo_nbr);" << endl - << "M_.xref2.exo = cell(1, M_.exo_nbr);" << endl - << "M_.xref2.exo_det = cell(1, M_.exo_det_nbr);" << endl; - writeRevXrefs(output, xref_param, "param"); - writeRevXrefs(output, xref_endo, "endo"); - writeRevXrefs(output, xref_exo, "exo"); - writeRevXrefs(output, xref_exo_det, "exo_det"); -} - -void -DynamicModel::writeRevXrefs(ostream &output, const map, set > &xrefmap, const string &type) const -{ - int last_tsid = -1; - for (map, set >::const_iterator it = xrefmap.begin(); - it != xrefmap.end(); it++) - { - int tsid = symbol_table.getTypeSpecificID(it->first.first) + 1; - output << "M_.xref2." << type << "{" << tsid << "} = [ "; - if (last_tsid == tsid) - output << "M_.xref2." << type << "{" << tsid << "}; "; - else - last_tsid = tsid; - - for (set::const_iterator it1 = it->second.begin(); - it1 != it->second.end(); it1++) - if (type == "param") - output << *it1 + 1 << " "; - else - output << "struct('shift', " << it->first.second << ", 'eq', " << *it1+1 << ");"; - output << "];" << endl; - } -} - -map >, pair >, int> -DynamicModel::get_Derivatives(int block) -{ - int max_lag, max_lead; - map >, pair >, int> Derivatives; - Derivatives.clear(); - BlockSimulationType simulation_type = getBlockSimulationType(block); - if (simulation_type == EVALUATE_BACKWARD || simulation_type == EVALUATE_FORWARD) - { - max_lag = 1; - max_lead = 1; - setBlockLeadLag(block, max_lag, max_lead); - } - else - { - max_lag = getBlockMaxLag(block); - max_lead = getBlockMaxLead(block); - } - int block_size = getBlockSize(block); - int block_nb_recursive = block_size - getBlockMfs(block); - for (int lag = -max_lag; lag <= max_lead; lag++) - { - for (int eq = 0; eq < block_size; eq++) - { - int eqr = getBlockEquationID(block, eq); - for (int var = 0; var < block_size; var++) - { - int varr = getBlockVariableID(block, var); - if (dynamic_jacobian.find(make_pair(lag, make_pair(eqr, varr))) != dynamic_jacobian.end()) - { - bool OK = true; - map >, pair >, int>::const_iterator its = Derivatives.find(make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))); - if (its != Derivatives.end()) - { - if (its->second == 2) - OK = false; - } - - if (OK) - { - if (getBlockEquationType(block, eq) == E_EVALUATE_S && eq < block_nb_recursive) - //It's a normalized equation, we have to recompute the derivative using chain rule derivative function - Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 1; - else - //It's a feedback equation we can use the derivatives - Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 0; - } - if (var < block_nb_recursive) - { - int eqs = getBlockEquationID(block, var); - for (int vars = block_nb_recursive; vars < block_size; vars++) - { - int varrs = getBlockVariableID(block, vars); - //A new derivative needs to be computed using the chain rule derivative function (a feedback variable appears in a recursive equation) - if (Derivatives.find(make_pair(make_pair(lag, make_pair(var, vars)), make_pair(eqs, varrs))) != Derivatives.end()) - Derivatives[make_pair(make_pair(lag, make_pair(eq, vars)), make_pair(eqr, varrs))] = 2; - } - } - } - } - } - } - return (Derivatives); -} - -void -DynamicModel::computeChainRuleJacobian(blocks_derivatives_t &blocks_endo_derivatives) -{ - map recursive_variables; - unsigned int nb_blocks = getNbBlocks(); - blocks_endo_derivatives = blocks_derivatives_t(nb_blocks); - for (unsigned int block = 0; block < nb_blocks; block++) - { - block_derivatives_equation_variable_laglead_nodeid_t tmp_derivatives; - recursive_variables.clear(); - int block_size = getBlockSize(block); - int block_nb_mfs = getBlockMfs(block); - int block_nb_recursives = block_size - block_nb_mfs; - blocks_endo_derivatives.push_back(block_derivatives_equation_variable_laglead_nodeid_t(0)); - for (int i = 0; i < block_nb_recursives; i++) - { - if (getBlockEquationType(block, i) == E_EVALUATE_S) - recursive_variables[getDerivID(symbol_table.getID(eEndogenous, getBlockVariableID(block, i)), 0)] = getBlockEquationRenormalizedExpr(block, i); - else - recursive_variables[getDerivID(symbol_table.getID(eEndogenous, getBlockVariableID(block, i)), 0)] = getBlockEquationExpr(block, i); - } - map >, pair >, int> Derivatives = get_Derivatives(block); - map >, pair >, int>::const_iterator it = Derivatives.begin(); - for (int i = 0; i < (int) Derivatives.size(); i++) - { - int Deriv_type = it->second; - pair >, pair > it_l(it->first); - it++; - int lag = it_l.first.first; - int eq = it_l.first.second.first; - int var = it_l.first.second.second; - int eqr = it_l.second.first; - int varr = it_l.second.second; - if (Deriv_type == 0) - first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = first_derivatives[make_pair(eqr, getDerivID(symbol_table.getID(eEndogenous, varr), lag))]; - else if (Deriv_type == 1) - first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = (equation_type_and_normalized_equation[eqr].second)->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables); - else if (Deriv_type == 2) - { - if (getBlockEquationType(block, eq) == E_EVALUATE_S && eq < block_nb_recursives) - first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = (equation_type_and_normalized_equation[eqr].second)->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables); - else - first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables); - } - tmp_derivatives.push_back(make_pair(make_pair(eq, var), make_pair(lag, first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))]))); - } - blocks_endo_derivatives[block] = tmp_derivatives; - } -} - -void -DynamicModel::collect_block_first_order_derivatives() -{ - //! vector for an equation or a variable indicates the block number - vector equation_2_block, variable_2_block; - unsigned int nb_blocks = getNbBlocks(); - equation_2_block = vector(equation_reordered.size()); - variable_2_block = vector(variable_reordered.size()); - for (unsigned int block = 0; block < nb_blocks; block++) - { - unsigned int block_size = getBlockSize(block); - for (unsigned int i = 0; i < block_size; i++) - { - equation_2_block[getBlockEquationID(block, i)] = block; - variable_2_block[getBlockVariableID(block, i)] = block; - } - } - other_endo_block = vector(nb_blocks); - exo_block = vector(nb_blocks); - exo_det_block = vector(nb_blocks); - derivative_endo = vector(nb_blocks); - derivative_other_endo = vector(nb_blocks); - derivative_exo = vector(nb_blocks); - derivative_exo_det = vector(nb_blocks); - endo_max_leadlag_block = vector >(nb_blocks, make_pair(0, 0)); - other_endo_max_leadlag_block = vector >(nb_blocks, make_pair(0, 0)); - exo_max_leadlag_block = vector >(nb_blocks, make_pair(0, 0)); - exo_det_max_leadlag_block = vector >(nb_blocks, make_pair(0, 0)); - max_leadlag_block = vector >(nb_blocks, make_pair(0, 0)); - for (first_derivatives_t::iterator it2 = first_derivatives.begin(); - it2 != first_derivatives.end(); it2++) - { - int eq = it2->first.first; - int var = symbol_table.getTypeSpecificID(getSymbIDByDerivID(it2->first.second)); - int lag = getLagByDerivID(it2->first.second); - int block_eq = equation_2_block[eq]; - int block_var = 0; - derivative_t tmp_derivative; - lag_var_t lag_var; - switch (getTypeByDerivID(it2->first.second)) - { - case eEndogenous: - block_var = variable_2_block[var]; - if (block_eq == block_var) - { - if (lag < 0 && lag < -endo_max_leadlag_block[block_eq].first) - endo_max_leadlag_block[block_eq] = make_pair(-lag, endo_max_leadlag_block[block_eq].second); - if (lag > 0 && lag > endo_max_leadlag_block[block_eq].second) - endo_max_leadlag_block[block_eq] = make_pair(endo_max_leadlag_block[block_eq].first, lag); - tmp_derivative = derivative_endo[block_eq]; - tmp_derivative[make_pair(lag, make_pair(eq, var))] = first_derivatives[make_pair(eq, getDerivID(symbol_table.getID(eEndogenous, var), lag))]; - derivative_endo[block_eq] = tmp_derivative; - } - else - { - if (lag < 0 && lag < -other_endo_max_leadlag_block[block_eq].first) - other_endo_max_leadlag_block[block_eq] = make_pair(-lag, other_endo_max_leadlag_block[block_eq].second); - if (lag > 0 && lag > other_endo_max_leadlag_block[block_eq].second) - other_endo_max_leadlag_block[block_eq] = make_pair(other_endo_max_leadlag_block[block_eq].first, lag); - tmp_derivative = derivative_other_endo[block_eq]; - { - map< int, map >::const_iterator it = block_other_endo_index.find(block_eq); - if (it == block_other_endo_index.end()) - block_other_endo_index[block_eq][var] = 0; - else - { - map::const_iterator it1 = it->second.find(var); - if (it1 == it->second.end()) - { - int size = block_other_endo_index[block_eq].size(); - block_other_endo_index[block_eq][var] = size; - } - } - } - tmp_derivative[make_pair(lag, make_pair(eq, var))] = first_derivatives[make_pair(eq, getDerivID(symbol_table.getID(eEndogenous, var), lag))]; - derivative_other_endo[block_eq] = tmp_derivative; - lag_var = other_endo_block[block_eq]; - if (lag_var.find(lag) == lag_var.end()) - lag_var[lag].clear(); - lag_var[lag].insert(var); - other_endo_block[block_eq] = lag_var; - } - break; - case eExogenous: - if (lag < 0 && lag < -exo_max_leadlag_block[block_eq].first) - exo_max_leadlag_block[block_eq] = make_pair(-lag, exo_max_leadlag_block[block_eq].second); - if (lag > 0 && lag > exo_max_leadlag_block[block_eq].second) - exo_max_leadlag_block[block_eq] = make_pair(exo_max_leadlag_block[block_eq].first, lag); - tmp_derivative = derivative_exo[block_eq]; - { - map< int, map >::const_iterator it = block_exo_index.find(block_eq); - if (it == block_exo_index.end()) - block_exo_index[block_eq][var] = 0; - else - { - map::const_iterator it1 = it->second.find(var); - if (it1 == it->second.end()) - { - int size = block_exo_index[block_eq].size(); - block_exo_index[block_eq][var] = size; - } - } - } - tmp_derivative[make_pair(lag, make_pair(eq, var))] = first_derivatives[make_pair(eq, getDerivID(symbol_table.getID(eExogenous, var), lag))]; - derivative_exo[block_eq] = tmp_derivative; - lag_var = exo_block[block_eq]; - if (lag_var.find(lag) == lag_var.end()) - lag_var[lag].clear(); - lag_var[lag].insert(var); - exo_block[block_eq] = lag_var; - break; - case eExogenousDet: - if (lag < 0 && lag < -exo_det_max_leadlag_block[block_eq].first) - exo_det_max_leadlag_block[block_eq] = make_pair(-lag, exo_det_max_leadlag_block[block_eq].second); - if (lag > 0 && lag > exo_det_max_leadlag_block[block_eq].second) - exo_det_max_leadlag_block[block_eq] = make_pair(exo_det_max_leadlag_block[block_eq].first, lag); - tmp_derivative = derivative_exo_det[block_eq]; - { - map< int, map >::const_iterator it = block_det_exo_index.find(block_eq); - if (it == block_det_exo_index.end()) - block_det_exo_index[block_eq][var] = 0; - else - { - map::const_iterator it1 = it->second.find(var); - if (it1 == it->second.end()) - { - int size = block_det_exo_index[block_eq].size(); - block_det_exo_index[block_eq][var] = size; - } - } - } - tmp_derivative[make_pair(lag, make_pair(eq, var))] = first_derivatives[make_pair(eq, getDerivID(symbol_table.getID(eExogenous, var), lag))]; - derivative_exo_det[block_eq] = tmp_derivative; - lag_var = exo_det_block[block_eq]; - if (lag_var.find(lag) == lag_var.end()) - lag_var[lag].clear(); - lag_var[lag].insert(var); - exo_det_block[block_eq] = lag_var; - break; - default: - break; - } - if (lag < 0 && lag < -max_leadlag_block[block_eq].first) - max_leadlag_block[block_eq] = make_pair(-lag, max_leadlag_block[block_eq].second); - if (lag > 0 && lag > max_leadlag_block[block_eq].second) - max_leadlag_block[block_eq] = make_pair(max_leadlag_block[block_eq].first, lag); - } - -} - -void -DynamicModel::collectBlockVariables() -{ - for (unsigned int block = 0; block < getNbBlocks(); block++) - { - int prev_var = -1; - int prev_lag = -999999999; - int count_col_exo = 0; - var_t tmp_var_exo; - for (lag_var_t::const_iterator it = exo_block[block].begin(); it != exo_block[block].end(); it++) - { - int lag = it->first; - for (var_t::const_iterator it2 = it->second.begin(); it2 != it->second.end(); it2++) - { - int var = *it2; - tmp_var_exo.insert(var); - if (prev_var != var || prev_lag != lag) - { - prev_var = var; - prev_lag = lag; - count_col_exo++; - } - } - } - block_var_exo.push_back(make_pair(tmp_var_exo, count_col_exo)); - } -} - -void -DynamicModel::writeDynamicFile(const string &basename, bool block, bool bytecode, bool use_dll, int order, bool julia) const -{ - int r; - string t_basename = basename + "_dynamic"; - if (block && bytecode) - writeModelEquationsCode_Block(t_basename, basename, map_idx); - else if (!block && bytecode) - writeModelEquationsCode(t_basename, basename, map_idx); - else if (block && !bytecode) - { -#ifdef _WIN32 - r = mkdir(basename.c_str()); -#else - r = mkdir(basename.c_str(), 0777); -#endif - if (r < 0 && errno != EEXIST) - { - perror("ERROR"); - exit(EXIT_FAILURE); - } - writeSparseDynamicMFile(t_basename, basename); - } - else if (use_dll) - writeDynamicCFile(t_basename, order); - else if (julia) - writeDynamicJuliaFile(basename); - else - writeDynamicMFile(t_basename); -} - -void -DynamicModel::cloneDynamic(DynamicModel &dynamic_model) const -{ - /* Ensure that we are using the same symbol table, because at many places we manipulate - symbol IDs rather than strings */ - assert(&symbol_table == &dynamic_model.symbol_table); - - // Convert model local variables (need to be done first) - for (vector::const_iterator it = local_variables_vector.begin(); - it != local_variables_vector.end(); it++) - dynamic_model.AddLocalVariable(*it, local_variables_table.find(*it)->second->cloneDynamic(dynamic_model)); - - // Convert equations - for (size_t i = 0; i < equations.size(); i++) - { - vector > eq_tags; - for (vector > >::const_iterator it = equation_tags.begin(); - it != equation_tags.end(); ++it) - if (it->first == (int)i) - eq_tags.push_back(it->second); - dynamic_model.addEquation(equations[i]->cloneDynamic(dynamic_model), equations_lineno[i], eq_tags); - } - - // Convert auxiliary equations - for (deque::const_iterator it = aux_equations.begin(); - it != aux_equations.end(); it++) - dynamic_model.addAuxEquation((*it)->cloneDynamic(dynamic_model)); - - // Convert static_only equations - for (size_t i = 0; i < static_only_equations.size(); i++) - dynamic_model.addStaticOnlyEquation(static_only_equations[i]->cloneDynamic(dynamic_model), - static_only_equations_lineno[i], - static_only_equations_equation_tags[i]); - - dynamic_model.setLeadsLagsOrig(); -} - -void -DynamicModel::replaceMyEquations(DynamicModel &dynamic_model) const -{ - dynamic_model.equations.clear(); - for (size_t i = 0; i < equations.size(); i++) - dynamic_model.addEquation(equations[i]->cloneDynamic(dynamic_model), - equations_lineno[i]); -} - -void -DynamicModel::computeRamseyPolicyFOCs(const StaticModel &static_model, const bool nopreprocessoroutput) -{ - // Add aux LM to constraints in equations - // equation[i]->lhs = rhs becomes equation[i]->MULT_(i+1)*(lhs-rhs) = 0 - int i; - for (i = 0; i < (int) equations.size(); i++) - { - BinaryOpNode *substeq = dynamic_cast(equations[i]->addMultipliersToConstraints(i)); - assert(substeq != NULL); - equations[i] = substeq; - } - if (!nopreprocessoroutput) - cout << "Ramsey Problem: added " << i << " Multipliers." << endl; - - // Add Planner Objective to equations to include in computeDerivIDs - assert(static_model.equations.size() == 1); - addEquation(static_model.equations[0]->cloneDynamic(*this), static_model.equations_lineno[0]); - - // Get max endo lead and max endo lag - set > dynvars; - int max_eq_lead = 0; - int max_eq_lag = 0; - for (int i = 0; i < (int) equations.size(); i++) - equations[i]->collectDynamicVariables(eEndogenous, dynvars); - - for (set >::const_iterator it = dynvars.begin(); - it != dynvars.end(); it++) - { - int lag = it->second; - if (max_eq_lead < lag) - max_eq_lead = lag; - else if (-max_eq_lag > lag) - max_eq_lag = -lag; - } - - // Get Discount Factor - assert(symbol_table.exists("optimal_policy_discount_factor")); - int symb_id = symbol_table.getID("optimal_policy_discount_factor"); - assert(symbol_table.getType(symb_id) == eParameter); - expr_t discount_factor_node = AddVariable(symb_id, 0); - - // Create (modified) Lagrangian (so that we can take the derivative once at time t) - expr_t lagrangian = Zero; - for (i = 0; i < (int) equations.size(); i++) - for (int lag = -max_eq_lag; lag <= max_eq_lead; lag++) - { - expr_t dfpower = NULL; - std::stringstream lagstream; - lagstream << abs(lag); - if (lag < 0) - dfpower = AddNonNegativeConstant(lagstream.str()); - else if (lag == 0) - dfpower = Zero; - else - dfpower = AddMinus(Zero, AddNonNegativeConstant(lagstream.str())); - - lagrangian = AddPlus(AddTimes(AddPower(discount_factor_node, dfpower), - equations[i]->getNonZeroPartofEquation()->decreaseLeadsLags(lag)), lagrangian); - } - - equations.clear(); - addEquation(AddEqual(lagrangian, Zero), -1); - computeDerivIDs(); - - //Compute derivatives and overwrite equations - vector neweqs; - for (deriv_id_table_t::const_iterator it = deriv_id_table.begin(); - it != deriv_id_table.end(); it++) - // For all endogenous variables with zero lag - if (symbol_table.getType(it->first.first) == eEndogenous && it->first.second == 0) - neweqs.push_back(AddEqual(equations[0]->getNonZeroPartofEquation()->getDerivative(it->second), Zero)); - - // Add new equations - equations.clear(); - for (int i = 0; i < (int) neweqs.size(); i++) - addEquation(neweqs[i], -1); -} - -void -DynamicModel::toStatic(StaticModel &static_model) const -{ - /* Ensure that we are using the same symbol table, because at many places we manipulate - symbol IDs rather than strings */ - assert(&symbol_table == &static_model.symbol_table); - - // Convert model local variables (need to be done first) - for (vector::const_iterator it = local_variables_vector.begin(); - it != local_variables_vector.end(); it++) - static_model.AddLocalVariable(*it, local_variables_table.find(*it)->second->toStatic(static_model)); - - // Convert equations - int static_only_index = 0; - for (int i = 0; i < (int) equations.size(); i++) - { - // Detect if equation is marked [dynamic] - bool is_dynamic_only = false; - vector > eq_tags; - for (vector > >::const_iterator it = equation_tags.begin(); - it != equation_tags.end(); ++it) - if (it->first == i) - { - eq_tags.push_back(it->second); - if (it->second.first == "dynamic") - is_dynamic_only = true; - } - - try - { - // If yes, replace it by an equation marked [static] - if (is_dynamic_only) - { - static_model.addEquation(static_only_equations[static_only_index]->toStatic(static_model), static_only_equations_lineno[static_only_index], static_only_equations_equation_tags[static_only_index]); - static_only_index++; - } - else - static_model.addEquation(equations[i]->toStatic(static_model), equations_lineno[i], eq_tags); - } - catch (DataTree::DivisionByZeroException) - { - cerr << "...division by zero error encountred when converting equation " << i << " to static" << endl; - exit(EXIT_FAILURE); - } - } - - // Convert auxiliary equations - for (deque::const_iterator it = aux_equations.begin(); - it != aux_equations.end(); it++) - static_model.addAuxEquation((*it)->toStatic(static_model)); -} - -bool -DynamicModel::ParamUsedWithLeadLag() const -{ - return ParamUsedWithLeadLagInternal(); -} - -set -DynamicModel::findUnusedEndogenous() -{ - set usedEndo, unusedEndo; - for (int i = 0; i < (int) equations.size(); i++) - equations[i]->collectVariables(eEndogenous, usedEndo); - set allEndo = symbol_table.getEndogenous(); - set_difference(allEndo.begin(), allEndo.end(), - usedEndo.begin(), usedEndo.end(), - inserter(unusedEndo, unusedEndo.begin())); - return unusedEndo; -} - -set -DynamicModel::findUnusedExogenous() -{ - set usedExo, unusedExo; - for (int i = 0; i < (int) equations.size(); i++) - equations[i]->collectVariables(eExogenous, usedExo); - set allExo = symbol_table.getExogenous(); - set_difference(allExo.begin(), allExo.end(), - usedExo.begin(), usedExo.end(), - inserter(unusedExo, unusedExo.begin())); - return unusedExo; -} - -void -DynamicModel::setLeadsLagsOrig() -{ - set > dynvars; - - for (int i = 0; i < (int) equations.size(); i++) - { - equations[i]->collectDynamicVariables(eEndogenous, dynvars); - equations[i]->collectDynamicVariables(eExogenous, dynvars); - equations[i]->collectDynamicVariables(eExogenousDet, dynvars); - } - - for (set >::const_iterator it = dynvars.begin(); - it != dynvars.end(); it++) - { - int lag = it->second; - SymbolType type = symbol_table.getType(it->first); - - if (max_lead_orig < lag) - max_lead_orig= lag; - else if (-max_lag_orig > lag) - max_lag_orig = -lag; - - switch (type) - { - case eEndogenous: - if (max_endo_lead_orig < lag) - max_endo_lead_orig = lag; - else if (-max_endo_lag_orig > lag) - max_endo_lag_orig = -lag; - break; - case eExogenous: - if (max_exo_lead_orig < lag) - max_exo_lead_orig = lag; - else if (-max_exo_lag_orig > lag) - max_exo_lag_orig = -lag; - break; - case eExogenousDet: - if (max_exo_det_lead_orig < lag) - max_exo_det_lead_orig = lag; - else if (-max_exo_det_lag_orig > lag) - max_exo_det_lag_orig = -lag; - break; - default: - break; - } - } -} - -void -DynamicModel::computeDerivIDs() -{ - set > dynvars; - - for (int i = 0; i < (int) equations.size(); i++) - equations[i]->collectDynamicVariables(eEndogenous, dynvars); - - dynJacobianColsNbr = dynvars.size(); - - for (int i = 0; i < (int) equations.size(); i++) - { - equations[i]->collectDynamicVariables(eExogenous, dynvars); - equations[i]->collectDynamicVariables(eExogenousDet, dynvars); - equations[i]->collectDynamicVariables(eParameter, dynvars); - equations[i]->collectDynamicVariables(eTrend, dynvars); - equations[i]->collectDynamicVariables(eLogTrend, dynvars); - } - - for (set >::const_iterator it = dynvars.begin(); - it != dynvars.end(); it++) - { - int lag = it->second; - SymbolType type = symbol_table.getType(it->first); - - /* Setting maximum and minimum lags. - - We don't want these to be affected by lead/lags on parameters: they - are accepted for facilitating variable flipping, but are simply - ignored. */ - if (max_lead < lag && type != eParameter) - max_lead = lag; - else if (-max_lag > lag && type != eParameter) - max_lag = -lag; - - switch (type) - { - case eEndogenous: - if (max_endo_lead < lag) - max_endo_lead = lag; - else if (-max_endo_lag > lag) - max_endo_lag = -lag; - break; - case eExogenous: - if (max_exo_lead < lag) - max_exo_lead = lag; - else if (-max_exo_lag > lag) - max_exo_lag = -lag; - break; - case eExogenousDet: - if (max_exo_det_lead < lag) - max_exo_det_lead = lag; - else if (-max_exo_det_lag > lag) - max_exo_det_lag = -lag; - break; - default: - break; - } - - // Create a new deriv_id - int deriv_id = deriv_id_table.size(); - - deriv_id_table[*it] = deriv_id; - inv_deriv_id_table.push_back(*it); - } -} - -SymbolType -DynamicModel::getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException) -{ - return symbol_table.getType(getSymbIDByDerivID(deriv_id)); -} - -int -DynamicModel::getLagByDerivID(int deriv_id) const throw (UnknownDerivIDException) -{ - if (deriv_id < 0 || deriv_id >= (int) inv_deriv_id_table.size()) - throw UnknownDerivIDException(); - - return inv_deriv_id_table[deriv_id].second; -} - -int -DynamicModel::getSymbIDByDerivID(int deriv_id) const throw (UnknownDerivIDException) -{ - if (deriv_id < 0 || deriv_id >= (int) inv_deriv_id_table.size()) - throw UnknownDerivIDException(); - - return inv_deriv_id_table[deriv_id].first; -} - -int -DynamicModel::getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException) -{ - deriv_id_table_t::const_iterator it = deriv_id_table.find(make_pair(symb_id, lag)); - if (it == deriv_id_table.end()) - throw UnknownDerivIDException(); - else - return it->second; -} - -void -DynamicModel::addAllParamDerivId(set &deriv_id_set) -{ - for (size_t i = 0; i < inv_deriv_id_table.size(); i++) - if (symbol_table.getType(inv_deriv_id_table[i].first) == eParameter) - deriv_id_set.insert(i); -} - -void -DynamicModel::computeDynJacobianCols(bool jacobianExo) -{ - /* Sort the dynamic endogenous variables by lexicographic order over (lag, type_specific_symbol_id) - and fill the dynamic columns for exogenous and exogenous deterministic */ - map, int> ordered_dyn_endo; - - for (deriv_id_table_t::const_iterator it = deriv_id_table.begin(); - it != deriv_id_table.end(); it++) - { - const int &symb_id = it->first.first; - const int &lag = it->first.second; - const int &deriv_id = it->second; - SymbolType type = symbol_table.getType(symb_id); - int tsid = symbol_table.getTypeSpecificID(symb_id); - - switch (type) - { - case eEndogenous: - ordered_dyn_endo[make_pair(lag, tsid)] = deriv_id; - break; - case eExogenous: - // At this point, dynJacobianColsNbr contains the number of dynamic endogenous - if (jacobianExo) - dyn_jacobian_cols_table[deriv_id] = dynJacobianColsNbr + tsid; - break; - case eExogenousDet: - // At this point, dynJacobianColsNbr contains the number of dynamic endogenous - if (jacobianExo) - dyn_jacobian_cols_table[deriv_id] = dynJacobianColsNbr + symbol_table.exo_nbr() + tsid; - break; - case eParameter: - case eTrend: - case eLogTrend: - // We don't assign a dynamic jacobian column to parameters or trend variables - break; - default: - // Shut up GCC - cerr << "DynamicModel::computeDynJacobianCols: impossible case" << endl; - exit(EXIT_FAILURE); - } - } - - // Fill in dynamic jacobian columns for endogenous - int sorted_id = 0; - for (map, int>::const_iterator it = ordered_dyn_endo.begin(); - it != ordered_dyn_endo.end(); it++) - dyn_jacobian_cols_table[it->second] = sorted_id++; - - // Set final value for dynJacobianColsNbr - if (jacobianExo) - dynJacobianColsNbr += symbol_table.exo_nbr() + symbol_table.exo_det_nbr(); -} - -int -DynamicModel::getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDException) -{ - map::const_iterator it = dyn_jacobian_cols_table.find(deriv_id); - if (it == dyn_jacobian_cols_table.end()) - throw UnknownDerivIDException(); - else - return it->second; -} - -void -DynamicModel::testTrendDerivativesEqualToZero(const eval_context_t &eval_context) -{ - for (deriv_id_table_t::const_iterator it = deriv_id_table.begin(); - it != deriv_id_table.end(); it++) - if (symbol_table.getType(it->first.first) == eTrend - || symbol_table.getType(it->first.first) == eLogTrend) - for (int eq = 0; eq < (int) equations.size(); eq++) - { - expr_t homogeneq = AddMinus(equations[eq]->get_arg1(), - equations[eq]->get_arg2()); - - // Do not run the test if the term inside the log is zero - if (fabs(homogeneq->eval(eval_context)) > ZERO_BAND) - { - expr_t testeq = AddLog(homogeneq); // F = log(lhs-rhs) - testeq = testeq->getDerivative(it->second); // d F / d Trend - for (deriv_id_table_t::const_iterator endogit = deriv_id_table.begin(); - endogit != deriv_id_table.end(); endogit++) - if (symbol_table.getType(endogit->first.first) == eEndogenous) - { - double nearZero = testeq->getDerivative(endogit->second)->eval(eval_context); // eval d F / d Trend d Endog - if (fabs(nearZero) > ZERO_BAND) - { - cerr << "WARNING: trends not compatible with balanced growth path; the second-order cross partial of equation " << eq + 1 << " (line " - << equations_lineno[eq] << ") w.r.t. trend variable " - << symbol_table.getName(it->first.first) << " and endogenous variable " - << symbol_table.getName(endogit->first.first) << " is not null. " << endl; - // Changed to warning. See discussion in #1389 - } - } - } - } -} - -void -DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) const -{ - if (!residuals_params_derivatives.size() - && !residuals_params_second_derivatives.size() - && !jacobian_params_derivatives.size() - && !jacobian_params_second_derivatives.size() - && !hessian_params_derivatives.size()) - return; - - ExprNodeOutputType output_type = (julia ? oJuliaDynamicModel : oMatlabDynamicModel); - ostringstream model_local_vars_output; // Used for storing model local vars - ostringstream model_output; // Used for storing model temp vars and equations - ostringstream jacobian_output; // Used for storing jacobian equations - ostringstream hessian_output; // Used for storing Hessian equations - ostringstream hessian1_output; // Used for storing Hessian equations - ostringstream third_derivs_output; // Used for storing third order derivatives equations - ostringstream third_derivs1_output; // Used for storing third order derivatives equations - - deriv_node_temp_terms_t tef_terms; - writeModelLocalVariables(model_local_vars_output, output_type, tef_terms); - - temporary_terms_t temp_terms_empty; - writeTemporaryTerms(params_derivs_temporary_terms, temp_terms_empty, model_output, output_type, tef_terms); - - for (first_derivatives_t::const_iterator it = residuals_params_derivatives.begin(); - it != residuals_params_derivatives.end(); it++) - { - int eq = it->first.first; - int param = it->first.second; - expr_t d1 = it->second; - - int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; - - jacobian_output << "rp" << LEFT_ARRAY_SUBSCRIPT(output_type) << eq+1 << ", " << param_col - << RIGHT_ARRAY_SUBSCRIPT(output_type) << " = "; - d1->writeOutput(jacobian_output, output_type, params_derivs_temporary_terms, tef_terms); - jacobian_output << ";" << endl; - } - - for (second_derivatives_t::const_iterator it = jacobian_params_derivatives.begin(); - it != jacobian_params_derivatives.end(); it++) - { - int eq = it->first.first; - int var = it->first.second.first; - int param = it->first.second.second; - expr_t d2 = it->second; - - int var_col = getDynJacobianCol(var) + 1; - int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; - - hessian_output << "gp" << LEFT_ARRAY_SUBSCRIPT(output_type) << eq+1 << ", " << var_col - << ", " << param_col << RIGHT_ARRAY_SUBSCRIPT(output_type) << " = "; - d2->writeOutput(hessian_output, output_type, params_derivs_temporary_terms, tef_terms); - hessian_output << ";" << endl; - } - - int i = 1; - for (second_derivatives_t::const_iterator it = residuals_params_second_derivatives.begin(); - it != residuals_params_second_derivatives.end(); ++it, i++) - { - int eq = it->first.first; - int param1 = it->first.second.first; - int param2 = it->first.second.second; - expr_t d2 = it->second; - - int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; - int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; - - hessian1_output << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl - << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl - << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl - << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; - d2->writeOutput(hessian1_output, output_type, params_derivs_temporary_terms, tef_terms); - hessian1_output << ";" << endl; - } - - i = 1; - for (third_derivatives_t::const_iterator it = jacobian_params_second_derivatives.begin(); - it != jacobian_params_second_derivatives.end(); ++it, i++) - { - int eq = it->first.first; - int var = it->first.second.first; - int param1 = it->first.second.second.first; - int param2 = it->first.second.second.second; - expr_t d2 = it->second; - - int var_col = getDynJacobianCol(var) + 1; - int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; - int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; - - third_derivs_output << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl - << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var_col << ";" << endl - << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl - << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl - << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; - d2->writeOutput(third_derivs_output, output_type, params_derivs_temporary_terms, tef_terms); - third_derivs_output << ";" << endl; - } - - i = 1; - for (third_derivatives_t::const_iterator it = hessian_params_derivatives.begin(); - it != hessian_params_derivatives.end(); ++it, i++) - { - int eq = it->first.first; - int var1 = it->first.second.first; - int var2 = it->first.second.second.first; - int param = it->first.second.second.second; - expr_t d2 = it->second; - - int var1_col = getDynJacobianCol(var1) + 1; - int var2_col = getDynJacobianCol(var2) + 1; - int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; - - third_derivs1_output << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl - << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var1_col << ";" << endl - << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var2_col << ";" << endl - << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param_col << ";" << endl - << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; - d2->writeOutput(third_derivs1_output, output_type, params_derivs_temporary_terms, tef_terms); - third_derivs1_output << ";" << endl; - } - - string filename = julia ? basename + "DynamicParamsDerivs.jl" : basename + "_params_derivs.m"; - ofstream paramsDerivsFile; - paramsDerivsFile.open(filename.c_str(), ios::out | ios::binary); - if (!paramsDerivsFile.is_open()) - { - cerr << "ERROR: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - if (!julia) - { - // Check that we don't have more than 32 nested parenthesis because Matlab does not suppor this. See Issue #1201 - map tmp_paren_vars; - bool message_printed = false; - fixNestedParenthesis(model_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(model_local_vars_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(jacobian_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(hessian_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(hessian1_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(third_derivs_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(third_derivs1_output, tmp_paren_vars, message_printed); - paramsDerivsFile << "function [rp, gp, rpp, gpp, hp] = " << basename << "_params_derivs(y, x, params, steady_state, it_, ss_param_deriv, ss_param_2nd_deriv)" << endl - << "%" << endl - << "% Compute the derivatives of the dynamic model with respect to the parameters" << endl - << "% Inputs :" << endl - << "% y [#dynamic variables by 1] double vector of endogenous variables in the order stored" << endl - << "% in M_.lead_lag_incidence; see the Manual" << endl - << "% x [nperiods by M_.exo_nbr] double matrix of exogenous variables (in declaration order)" << endl - << "% for all simulation periods" << endl - << "% params [M_.param_nbr by 1] double vector of parameter values in declaration order" << endl - << "% steady_state [M_.endo_nbr by 1] double vector of steady state values" << endl - << "% it_ scalar double time period for exogenous variables for which to evaluate the model" << endl - << "% ss_param_deriv [M_.eq_nbr by #params] Jacobian matrix of the steady states values with respect to the parameters" << endl - << "% ss_param_2nd_deriv [M_.eq_nbr by #params by #params] Hessian matrix of the steady states values with respect to the parameters" << endl - << "%" << endl - << "% Outputs:" << endl - << "% rp [M_.eq_nbr by #params] double Jacobian matrix of dynamic model equations with respect to parameters " << endl - << "% Dynare may prepend or append auxiliary equations, see M_.aux_vars" << endl - << "% gp [M_.endo_nbr by #dynamic variables by #params] double Derivative of the Jacobian matrix of the dynamic model equations with respect to the parameters" << endl - << "% rows: equations in order of declaration" << endl - << "% columns: variables in order stored in M_.lead_lag_incidence" << endl - << "% rpp [#second_order_residual_terms by 4] double Hessian matrix of second derivatives of residuals with respect to parameters;" << endl - << "% rows: respective derivative term" << endl - << "% 1st column: equation number of the term appearing" << endl - << "% 2nd column: number of the first parameter in derivative" << endl - << "% 3rd column: number of the second parameter in derivative" << endl - << "% 4th column: value of the Hessian term" << endl - << "% gpp [#second_order_Jacobian_terms by 5] double Hessian matrix of second derivatives of the Jacobian with respect to the parameters;" << endl - << "% rows: respective derivative term" << endl - << "% 1st column: equation number of the term appearing" << endl - << "% 2nd column: column number of variable in Jacobian of the dynamic model" << endl - << "% 3rd column: number of the first parameter in derivative" << endl - << "% 4th column: number of the second parameter in derivative" << endl - << "% 5th column: value of the Hessian term" << endl - << "% hp [#first_order_Hessian_terms by 5] double Jacobian matrix of derivatives of the dynamic Hessian with respect to the parameters;" << endl - << "% rows: respective derivative term" << endl - << "% 1st column: equation number of the term appearing" << endl - << "% 2nd column: column number of first variable in Hessian of the dynamic model" << endl - << "% 3rd column: column number of second variable in Hessian of the dynamic model" << endl - << "% 4th column: number of the parameter in derivative" << endl - << "% 5th column: value of the Hessian term" << endl - << "%" << endl - << "%" << endl - << "% Warning : this file is generated automatically by Dynare" << endl - << "% from model file (.mod)" << endl << endl - << model_local_vars_output.str() - << model_output.str() - << "rp = zeros(" << equations.size() << ", " - << symbol_table.param_nbr() << ");" << endl - << jacobian_output.str() - << "gp = zeros(" << equations.size() << ", " << dynJacobianColsNbr << ", " << symbol_table.param_nbr() << ");" << endl - << hessian_output.str() - << "if nargout >= 3" << endl - << "rpp = zeros(" << residuals_params_second_derivatives.size() << ",4);" << endl - << hessian1_output.str() - << "gpp = zeros(" << jacobian_params_second_derivatives.size() << ",5);" << endl - << third_derivs_output.str() - << "end" << endl - << "if nargout >= 5" << endl - << "hp = zeros(" << hessian_params_derivatives.size() << ",5);" << endl - << third_derivs1_output.str() - << "end" << endl - << "end" << endl; - } - else - paramsDerivsFile << "module " << basename << "DynamicParamsDerivs" << endl - << "#" << endl - << "# NB: this file was automatically generated by Dynare" << endl - << "# from " << basename << ".mod" << endl - << "#" << endl - << "export params_derivs" << endl << endl - << "function params_derivs(y, x, paramssteady_state, it_, " - << "ss_param_deriv, ss_param_2nd_deriv)" << endl - << model_local_vars_output.str() - << model_output.str() - << "rp = zeros(" << equations.size() << ", " - << symbol_table.param_nbr() << ");" << endl - << jacobian_output.str() - << "gp = zeros(" << equations.size() << ", " << dynJacobianColsNbr << ", " << symbol_table.param_nbr() << ");" << endl - << hessian_output.str() - << "rpp = zeros(" << residuals_params_second_derivatives.size() << ",4);" << endl - << hessian1_output.str() - << "gpp = zeros(" << jacobian_params_second_derivatives.size() << ",5);" << endl - << third_derivs_output.str() - << "hp = zeros(" << hessian_params_derivatives.size() << ",5);" << endl - << third_derivs1_output.str() - << "(rp, gp, rpp, gpp, hp)" << endl - << "end" << endl - << "end" << endl; - - paramsDerivsFile.close(); -} - -void -DynamicModel::writeChainRuleDerivative(ostream &output, int eqr, int varr, int lag, - ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms) const -{ - map >, expr_t>::const_iterator it = first_chain_rule_derivatives.find(make_pair(eqr, make_pair(varr, lag))); - if (it != first_chain_rule_derivatives.end()) - (it->second)->writeOutput(output, output_type, temporary_terms); - else - output << 0; -} - -void -DynamicModel::writeLatexFile(const string &basename, const bool write_equation_tags) const -{ - writeLatexModelFile(basename + "_dynamic", oLatexDynamicModel, write_equation_tags); -} - -void -DynamicModel::writeLatexOriginalFile(const string &basename, const bool write_equation_tags) const -{ - writeLatexModelFile(basename + "_original", oLatexDynamicModel, write_equation_tags); -} - -void -DynamicModel::substituteEndoLeadGreaterThanTwo(bool deterministic_model) -{ - substituteLeadLagInternal(avEndoLead, deterministic_model, vector()); -} - -void -DynamicModel::substituteEndoLagGreaterThanTwo(bool deterministic_model) -{ - substituteLeadLagInternal(avEndoLag, deterministic_model, vector()); -} - -void -DynamicModel::substituteExoLead(bool deterministic_model) -{ - substituteLeadLagInternal(avExoLead, deterministic_model, vector()); -} - -void -DynamicModel::substituteExoLag(bool deterministic_model) -{ - substituteLeadLagInternal(avExoLag, deterministic_model, vector()); -} - -void -DynamicModel::substituteLeadLagInternal(aux_var_t type, bool deterministic_model, const vector &subset) -{ - ExprNode::subst_table_t subst_table; - vector neweqs; - - // Substitute in used model local variables - set used_local_vars; - for (size_t i = 0; i < equations.size(); i++) - equations[i]->collectVariables(eModelLocalVariable, used_local_vars); - - for (set::const_iterator it = used_local_vars.begin(); - it != used_local_vars.end(); ++it) - { - const expr_t value = local_variables_table.find(*it)->second; - expr_t subst; - switch (type) - { - case avEndoLead: - subst = value->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); - break; - case avEndoLag: - subst = value->substituteEndoLagGreaterThanTwo(subst_table, neweqs); - break; - case avExoLead: - subst = value->substituteExoLead(subst_table, neweqs, deterministic_model); - break; - case avExoLag: - subst = value->substituteExoLag(subst_table, neweqs); - break; - case avDiffForward: - subst = value->differentiateForwardVars(subset, subst_table, neweqs); - break; - default: - cerr << "DynamicModel::substituteLeadLagInternal: impossible case" << endl; - exit(EXIT_FAILURE); - } - local_variables_table[*it] = subst; - } - - // Substitute in equations - for (int i = 0; i < (int) equations.size(); i++) - { - expr_t subst; - switch (type) - { - case avEndoLead: - subst = equations[i]->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); - break; - case avEndoLag: - subst = equations[i]->substituteEndoLagGreaterThanTwo(subst_table, neweqs); - break; - case avExoLead: - subst = equations[i]->substituteExoLead(subst_table, neweqs, deterministic_model); - break; - case avExoLag: - subst = equations[i]->substituteExoLag(subst_table, neweqs); - break; - case avDiffForward: - subst = equations[i]->differentiateForwardVars(subset, subst_table, neweqs); - break; - default: - cerr << "DynamicModel::substituteLeadLagInternal: impossible case" << endl; - exit(EXIT_FAILURE); - } - BinaryOpNode *substeq = dynamic_cast(subst); - assert(substeq != NULL); - equations[i] = substeq; - } - - // Substitute in aux_equations - // Without this loop, the auxiliary equations in equations - // will diverge from those in aux_equations - for (int i = 0; i < (int) aux_equations.size(); i++) - { - expr_t subst; - switch (type) - { - case avEndoLead: - subst = aux_equations[i]->substituteEndoLeadGreaterThanTwo(subst_table, - neweqs, deterministic_model); - break; - case avEndoLag: - subst = aux_equations[i]->substituteEndoLagGreaterThanTwo(subst_table, neweqs); - break; - case avExoLead: - subst = aux_equations[i]->substituteExoLead(subst_table, neweqs, deterministic_model); - break; - case avExoLag: - subst = aux_equations[i]->substituteExoLag(subst_table, neweqs); - break; - case avDiffForward: - subst = aux_equations[i]->differentiateForwardVars(subset, subst_table, neweqs); - break; - default: - cerr << "DynamicModel::substituteLeadLagInternal: impossible case" << endl; - exit(EXIT_FAILURE); - } - BinaryOpNode *substeq = dynamic_cast(subst); - assert(substeq != NULL); - aux_equations[i] = substeq; - } - - // Add new equations - for (int i = 0; i < (int) neweqs.size(); i++) - addEquation(neweqs[i], -1); - - // Order of auxiliary variable definition equations: - // - expectation (entered before this function is called) - // - lead variables from lower lead to higher lead - // - lag variables from lower lag to higher lag - copy(neweqs.begin(), neweqs.end(), back_inserter(aux_equations)); - - if (neweqs.size() > 0) - { - cout << "Substitution of "; - switch (type) - { - case avEndoLead: - cout << "endo leads >= 2"; - break; - case avEndoLag: - cout << "endo lags >= 2"; - break; - case avExoLead: - cout << "exo leads"; - break; - case avExoLag: - cout << "exo lags"; - break; - case avExpectation: - cout << "expectation"; - break; - case avDiffForward: - cout << "forward vars"; - break; - case avMultiplier: - cerr << "avMultiplier encountered: impossible case" << endl; - exit(EXIT_FAILURE); - } - cout << ": added " << neweqs.size() << " auxiliary variables and equations." << endl; - } -} - -void -DynamicModel::substituteExpectation(bool partial_information_model) -{ - ExprNode::subst_table_t subst_table; - vector neweqs; - - // Substitute in model local variables - for (map::iterator it = local_variables_table.begin(); - it != local_variables_table.end(); it++) - it->second = it->second->substituteExpectation(subst_table, neweqs, partial_information_model); - - // Substitute in equations - for (int i = 0; i < (int) equations.size(); i++) - { - BinaryOpNode *substeq = dynamic_cast(equations[i]->substituteExpectation(subst_table, neweqs, partial_information_model)); - assert(substeq != NULL); - equations[i] = substeq; - } - - // Add new equations - for (int i = 0; i < (int) neweqs.size(); i++) - addEquation(neweqs[i], -1); - - // Add the new set of equations at the *beginning* of aux_equations - copy(neweqs.rbegin(), neweqs.rend(), front_inserter(aux_equations)); - - if (subst_table.size() > 0) - { - if (partial_information_model) - cout << "Substitution of Expectation operator: added " << subst_table.size() << " auxiliary variables and " << neweqs.size() << " auxiliary equations." << endl; - else - cout << "Substitution of Expectation operator: added " << neweqs.size() << " auxiliary variables and equations." << endl; - } -} - -void -DynamicModel::transformPredeterminedVariables() -{ - for (int i = 0; i < (int) equations.size(); i++) - { - BinaryOpNode *substeq = dynamic_cast(equations[i]->decreaseLeadsLagsPredeterminedVariables()); - assert(substeq != NULL); - equations[i] = substeq; - } -} - -void -DynamicModel::detrendEquations() -{ - // We go backwards in the list of trend_vars, to deal correctly with I(2) processes - for (nonstationary_symbols_map_t::const_reverse_iterator it = nonstationary_symbols_map.rbegin(); - it != nonstationary_symbols_map.rend(); ++it) - for (int i = 0; i < (int) equations.size(); i++) - { - BinaryOpNode *substeq = dynamic_cast(equations[i]->detrend(it->first, it->second.first, it->second.second)); - assert(substeq != NULL); - equations[i] = dynamic_cast(substeq); - } - - for (int i = 0; i < (int) equations.size(); i++) - { - BinaryOpNode *substeq = dynamic_cast(equations[i]->removeTrendLeadLag(trend_symbols_map)); - assert(substeq != NULL); - equations[i] = dynamic_cast(substeq); - } -} - -void -DynamicModel::removeTrendVariableFromEquations() -{ - for (int i = 0; i < (int) equations.size(); i++) - { - BinaryOpNode *substeq = dynamic_cast(equations[i]->replaceTrendVar()); - assert(substeq != NULL); - equations[i] = dynamic_cast(substeq); - } -} - -void -DynamicModel::differentiateForwardVars(const vector &subset) -{ - substituteLeadLagInternal(avDiffForward, true, subset); -} - -void -DynamicModel::fillEvalContext(eval_context_t &eval_context) const -{ - // First, auxiliary variables - for (deque::const_iterator it = aux_equations.begin(); - it != aux_equations.end(); it++) - { - assert((*it)->get_op_code() == oEqual); - VariableNode *auxvar = dynamic_cast((*it)->get_arg1()); - assert(auxvar != NULL); - try - { - double val = (*it)->get_arg2()->eval(eval_context); - eval_context[auxvar->get_symb_id()] = val; - } - catch (ExprNode::EvalException &e) - { - // Do nothing - } - } - - // Second, model local variables - for (map::const_iterator it = local_variables_table.begin(); - it != local_variables_table.end(); it++) - { - try - { - const expr_t expression = it->second; - double val = expression->eval(eval_context); - eval_context[it->first] = val; - } - catch (ExprNode::EvalException &e) - { - // Do nothing - } - } - - //Third, trend variables - vector trendVars = symbol_table.getTrendVarIds(); - for (vector ::const_iterator it = trendVars.begin(); - it != trendVars.end(); it++) - eval_context[*it] = 2; //not <= 0 bc of log, not 1 bc of powers -} - -bool -DynamicModel::isModelLocalVariableUsed() const -{ - set used_local_vars; - size_t i = 0; - while (i < equations.size() && used_local_vars.size() == 0) - { - equations[i]->collectVariables(eModelLocalVariable, used_local_vars); - i++; - } - return used_local_vars.size() > 0; -} - -void -DynamicModel::addStaticOnlyEquation(expr_t eq, int lineno, const vector > &eq_tags) -{ - BinaryOpNode *beq = dynamic_cast(eq); - assert(beq != NULL && beq->get_op_code() == oEqual); - - vector > soe_eq_tags; - for (size_t i = 0; i < eq_tags.size(); i++) - soe_eq_tags.push_back(eq_tags[i]); - - static_only_equations.push_back(beq); - static_only_equations_lineno.push_back(lineno); - static_only_equations_equation_tags.push_back(soe_eq_tags); -} - -size_t -DynamicModel::staticOnlyEquationsNbr() const -{ - return static_only_equations.size(); -} - -size_t -DynamicModel::dynamicOnlyEquationsNbr() const -{ - set eqs; - - for (vector > >::const_iterator it = equation_tags.begin(); - it != equation_tags.end(); ++it) - if (it->second.first == "dynamic") - eqs.insert(it->first); - - return eqs.size(); -} - -#ifndef PRIVATE_BUFFER_SIZE -# define PRIVATE_BUFFER_SIZE 1024 -#endif - -bool -DynamicModel::isChecksumMatching(const string &basename) const -{ - boost::crc_32_type result; - - std::stringstream buffer; - - // Write equation tags - for (size_t i = 0; i < equation_tags.size(); i++) - buffer << " " << equation_tags[i].first + 1 - << equation_tags[i].second.first - << equation_tags[i].second.second; - - ExprNodeOutputType buffer_type = oCDynamicModel; - - for (int eq = 0; eq < (int) equations.size(); eq++) - { - BinaryOpNode *eq_node = equations[eq]; - expr_t lhs = eq_node->get_arg1(); - expr_t rhs = eq_node->get_arg2(); - - // Test if the right hand side of the equation is empty. - double vrhs = 1.0; - try - { - vrhs = rhs->eval(eval_context_t()); - } - catch (ExprNode::EvalException &e) - { - } - - if (vrhs != 0) // The right hand side of the equation is not empty ==> residual=lhs-rhs; - { - buffer << "lhs ="; - lhs->writeOutput(buffer, buffer_type, temporary_terms); - buffer << ";" << endl; - - buffer << "rhs ="; - rhs->writeOutput(buffer, buffer_type, temporary_terms); - buffer << ";" << endl; - - buffer << "residual" << LEFT_ARRAY_SUBSCRIPT(buffer_type) - << eq + ARRAY_SUBSCRIPT_OFFSET(buffer_type) - << RIGHT_ARRAY_SUBSCRIPT(buffer_type) - << "= lhs-rhs;" << endl; - } - else // The right hand side of the equation is empty ==> residual=lhs; - { - buffer << "residual" << LEFT_ARRAY_SUBSCRIPT(buffer_type) - << eq + ARRAY_SUBSCRIPT_OFFSET(buffer_type) - << RIGHT_ARRAY_SUBSCRIPT(buffer_type) - << " = "; - lhs->writeOutput(buffer, buffer_type, temporary_terms); - buffer << ";" << endl; - } - } - - char private_buffer[PRIVATE_BUFFER_SIZE]; - while (buffer) - { - buffer.get(private_buffer, PRIVATE_BUFFER_SIZE); - result.process_bytes(private_buffer, strlen(private_buffer)); - } - - bool basename_dir_exists = false; -#ifdef _WIN32 - int r = mkdir(basename.c_str()); -#else - int r = mkdir(basename.c_str(), 0777); -#endif - if (r < 0) - if (errno != EEXIST) - { - perror("ERROR"); - exit(EXIT_FAILURE); - } - else - basename_dir_exists = true; - - // check whether basename directory exist. If not, create it. - // If it does, read old checksum if it exist - fstream checksum_file; - string filename = basename + "/checksum"; - unsigned int old_checksum = 0; - // read old checksum if it exists - if (basename_dir_exists) - { - checksum_file.open(filename.c_str(), ios::in | ios::binary); - if (checksum_file.is_open()) - { - checksum_file >> old_checksum; - checksum_file.close(); - } - } - // write new checksum file if none or different from old checksum - if (old_checksum != result.checksum()) - { - checksum_file.open(filename.c_str(), ios::out | ios::binary); - if (!checksum_file.is_open()) - { - cerr << "ERROR: Can't open file " << filename << endl; - exit(EXIT_FAILURE); - } - checksum_file << result.checksum(); - checksum_file.close(); - return false; - } - - return true; -} - -void -DynamicModel::writeCOutput(ostream &output, const string &basename, bool block_decomposition, bool byte_code, bool use_dll, int order, bool estimation_present) const -{ - int lag_presence[3]; - // Loop on endogenous variables - vector zeta_back, zeta_mixed, zeta_fwrd, zeta_static; - for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++) - { - // Loop on periods - for (int lag = 0; lag <= 2; lag++) - { - lag_presence[lag] = 1; - try - { - getDerivID(symbol_table.getID(eEndogenous, endoID), lag-1); - } - catch (UnknownDerivIDException &e) - { - lag_presence[lag] = 0; - } - } - if (lag_presence[0] == 1) - if (lag_presence[2] == 1) - zeta_mixed.push_back(endoID); - else - zeta_back.push_back(endoID); - else if (lag_presence[2] == 1) - zeta_fwrd.push_back(endoID); - else - zeta_static.push_back(endoID); - - } - output << "size_t nstatic = " << zeta_static.size() << ";" << endl - << "size_t nfwrd = " << zeta_fwrd.size() << ";" << endl - << "size_t nback = " << zeta_back.size() << ";" << endl - << "size_t nmixed = " << zeta_mixed.size() << ";" << endl; - output << "size_t zeta_static[" << zeta_static.size() << "] = {"; - for (vector::iterator i = zeta_static.begin(); i != zeta_static.end(); ++i) - { - if (i != zeta_static.begin()) - output << ","; - output << *i; - } - output << "};" << endl; - - output << "size_t zeta_back[" << zeta_back.size() << "] = {"; - for (vector::iterator i = zeta_back.begin(); i != zeta_back.end(); ++i) - { - if (i != zeta_back.begin()) - output << ","; - output << *i; - } - output << "};" << endl; - - output << "size_t zeta_fwrd[" << zeta_fwrd.size() << "] = {"; - for (vector::iterator i = zeta_fwrd.begin(); i != zeta_fwrd.end(); ++i) - { - if (i != zeta_fwrd.begin()) - output << ","; - output << *i; - } - output << "};" << endl; - - output << "size_t zeta_mixed[" << zeta_mixed.size() << "] = {"; - for (vector::iterator i = zeta_mixed.begin(); i != zeta_mixed.end(); ++i) - { - if (i != zeta_mixed.begin()) - output << ","; - output << *i; - } - output << "};" << endl; - - // Write number of non-zero derivatives - // Use -1 if the derivatives have not been computed - output << "int *NNZDerivatives[3] = {"; - switch (order) - { - case 0: - output << NNZDerivatives[0] << ",-1,-1};" << endl; - break; - case 1: - output << NNZDerivatives[0] << "," << NNZDerivatives[1] << ",-1};" << endl; - break; - case 2: - output << NNZDerivatives[0] << "," << NNZDerivatives[1] << "," << NNZDerivatives[2] << "};" << endl; - break; - default: - cerr << "Order larger than 3 not implemented" << endl; - exit(EXIT_FAILURE); - } -} - -void -DynamicModel::writeResidualsC(const string &basename, bool cuda) const -{ - string filename = basename + "_residuals.c"; - ofstream mDynamicModelFile, mDynamicMexFile; - - mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); - if (!mDynamicModelFile.is_open()) - { - cerr << "Error: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - mDynamicModelFile << "/*" << endl - << " * " << filename << " : Computes residuals of the model for Dynare" << endl - << " *" << endl - << " * Warning : this file is generated automatically by Dynare" << endl - << " * from model " << basename << "(.mod)" << endl - << " */" << endl -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - << "#ifdef _MSC_VER" << endl - << "#define _USE_MATH_DEFINES" << endl - << "#endif" << endl -#endif - << "#include " << endl; - - mDynamicModelFile << "#include " << endl; - - mDynamicModelFile << "#define max(a, b) (((a) > (b)) ? (a) : (b))" << endl - << "#define min(a, b) (((a) > (b)) ? (b) : (a))" << endl; - - // Write function definition if oPowerDeriv is used - // even for residuals if doing Ramsey - writePowerDerivCHeader(mDynamicModelFile); - writeNormcdfCHeader(mDynamicModelFile); - - mDynamicModelFile << "void Residuals(const double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual)" << endl - << "{" << endl; - - // this is always empty here, but needed by d1->writeOutput - deriv_node_temp_terms_t tef_terms; - - ostringstream model_output; // Used for storing model equations - writeModelEquations(model_output, oCDynamic2Model); - - mDynamicModelFile << " double lhs, rhs;" << endl - << endl - << " /* Residual equations */" << endl - << model_output.str() - << "}" << endl; - - writePowerDeriv(mDynamicModelFile); - writeNormcdf(mDynamicModelFile); - mDynamicModelFile.close(); - -} - -void -DynamicModel::writeFirstDerivativesC(const string &basename, bool cuda) const -{ - string filename = basename + "_first_derivatives.c"; - ofstream mDynamicModelFile, mDynamicMexFile; - - mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); - if (!mDynamicModelFile.is_open()) - { - cerr << "Error: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - mDynamicModelFile << "/*" << endl - << " * " << filename << " : Computes first order derivatives of the model for Dynare" << endl - << " *" << endl - << " * Warning : this file is generated automatically by Dynare" << endl - << " * from model " << basename << "(.mod)" << endl - << " */" << endl -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - << "#ifdef _MSC_VER" << endl - << "#define _USE_MATH_DEFINES" << endl - << "#endif" << endl -#endif - << "#include " << endl; - - mDynamicModelFile << "#include " << endl; - - mDynamicModelFile << "#define max(a, b) (((a) > (b)) ? (a) : (b))" << endl - << "#define min(a, b) (((a) > (b)) ? (b) : (a))" << endl; - - // Write function definition if oPowerDeriv is used - writePowerDerivCHeader(mDynamicModelFile); - writeNormcdfCHeader(mDynamicModelFile); - - mDynamicModelFile << "void FirstDerivatives(const double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, double *g1, double *v2, double *v3)" << endl - << "{" << endl; - - // this is always empty here, but needed by d1->writeOutput - deriv_node_temp_terms_t tef_terms; - - // Writing Jacobian - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - int eq = it->first.first; - int var = it->first.second; - expr_t d1 = it->second; - - jacobianHelper(mDynamicModelFile, eq, getDynJacobianCol(var), oCDynamicModel); - mDynamicModelFile << "="; - // oCStaticModel makes reference to the static variables - // oCDynamicModel makes reference to the dynamic variables - d1->writeOutput(mDynamicModelFile, oCDynamicModel, temporary_terms, tef_terms); - mDynamicModelFile << ";" << endl; - } - - mDynamicModelFile << "}" << endl; - - mDynamicModelFile.close(); - -} - -// using compressed sparse row format (CSR) -void -DynamicModel::writeFirstDerivativesC_csr(const string &basename, bool cuda) const -{ - string filename = basename + "_first_derivatives.c"; - ofstream mDynamicModelFile, mDynamicMexFile; - - mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); - if (!mDynamicModelFile.is_open()) - { - cerr << "Error: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - mDynamicModelFile << "/*" << endl - << " * " << filename << " : Computes first order derivatives of the model for Dynare" << endl - << " *" << endl - << " * Warning : this file is generated automatically by Dynare" << endl - << " * from model " << basename << "(.mod)" << endl - << " */" << endl -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - << "#ifdef _MSC_VER" << endl - << "#define _USE_MATH_DEFINES" << endl - << "#endif" << endl -#endif - << "#include " << endl; - - mDynamicModelFile << "#include " << endl; - - mDynamicModelFile << "#define max(a, b) (((a) > (b)) ? (a) : (b))" << endl - << "#define min(a, b) (((a) > (b)) ? (b) : (a))" << endl; - - // Write function definition if oPowerDeriv is used - writePowerDerivCHeader(mDynamicModelFile); - writeNormcdfCHeader(mDynamicModelFile); - - mDynamicModelFile << "void FirstDerivatives(const double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, int *row_ptr, int *col_ptr, double *value)" << endl - << "{" << endl; - - int cols_nbr = 3*symbol_table.endo_nbr() + symbol_table.exo_nbr() + symbol_table.exo_det_nbr(); - // this is always empty here, but needed by d1->writeOutput - deriv_node_temp_terms_t tef_terms; - - // Indexing derivatives in column order - vector D; - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - int eq = it->first.first; - int dynvar = it->first.second; - int lag = getLagByDerivID(dynvar); - int symb_id = getSymbIDByDerivID(dynvar); - SymbolType type = getTypeByDerivID(dynvar); - int tsid = symbol_table.getTypeSpecificID(symb_id); - int col_id; - switch (type) - { - case eEndogenous: - col_id = tsid+(lag+1)*symbol_table.endo_nbr(); - break; - case eExogenous: - col_id = tsid+3*symbol_table.endo_nbr(); - break; - case eExogenousDet: - col_id = tsid+3*symbol_table.endo_nbr()+symbol_table.exo_nbr(); - break; - default: - std::cerr << "This case shouldn't happen" << std::endl; - exit(EXIT_FAILURE); - } - derivative deriv(col_id + eq *cols_nbr, col_id, eq, it->second); - D.push_back(deriv); - } - sort(D.begin(), D.end(), derivative_less_than()); - - // writing sparse Jacobian - vector row_ptr(equations.size()); - fill(row_ptr.begin(), row_ptr.end(), 0.0); - int k = 0; - for (vector::const_iterator it = D.begin(); it != D.end(); ++it) - { - row_ptr[it->row_nbr]++; - mDynamicModelFile << "col_ptr[" << k << "] " - << "=" << it->col_nbr << ";" << endl; - mDynamicModelFile << "value[" << k << "] = "; - // oCstaticModel makes reference to the static variables - it->value->writeOutput(mDynamicModelFile, oCDynamic2Model, temporary_terms, tef_terms); - mDynamicModelFile << ";" << endl; - k++; - } - - // row_ptr must point to the relative address of the first element of the row - int cumsum = 0; - mDynamicModelFile << "int row_ptr_data[" << row_ptr.size() + 1 << "] = { 0"; - for (vector::iterator it = row_ptr.begin(); it != row_ptr.end(); ++it) - { - cumsum += *it; - mDynamicModelFile << ", " << cumsum; - } - mDynamicModelFile << "};" << endl - << "int i;" << endl - << "for (i=0; i < " << row_ptr.size() + 1 << "; i++) row_ptr[i] = row_ptr_data[i];" << endl; - mDynamicModelFile << "}" << endl; - - mDynamicModelFile.close(); - -} -void -DynamicModel::writeSecondDerivativesC_csr(const string &basename, bool cuda) const -{ - - string filename = basename + "_second_derivatives.c"; - ofstream mDynamicModelFile, mDynamicMexFile; - - mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); - if (!mDynamicModelFile.is_open()) - { - cerr << "Error: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - mDynamicModelFile << "/*" << endl - << " * " << filename << " : Computes second order derivatives of the model for Dynare" << endl - << " *" << endl - << " * Warning : this file is generated automatically by Dynare" << endl - << " * from model " << basename << "(.mod)" << endl - << " */" << endl -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - << "#ifdef _MSC_VER" << endl - << "#define _USE_MATH_DEFINES" << endl - << "#endif" << endl -#endif - << "#include " << endl; - - mDynamicModelFile << "#include " << endl; - - mDynamicModelFile << "#define max(a, b) (((a) > (b)) ? (a) : (b))" << endl - << "#define min(a, b) (((a) > (b)) ? (b) : (a))" << endl; - - // write function definition if oPowerDeriv is used - writePowerDerivCHeader(mDynamicModelFile); - writeNormcdfCHeader(mDynamicModelFile); - - mDynamicModelFile << "void SecondDerivatives(const double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, int *row_ptr, int *col_ptr, double *value)" << endl - << "{" << endl; - - // this is always empty here, but needed by d1->writeOutput - deriv_node_temp_terms_t tef_terms; - - // Indexing derivatives in column order - vector D; - int hessianColsNbr = dynJacobianColsNbr*dynJacobianColsNbr; - for (second_derivatives_t::const_iterator it = second_derivatives.begin(); - it != second_derivatives.end(); it++) - { - int eq = it->first.first; - int var1 = it->first.second.first; - int var2 = it->first.second.second; - - int id1 = getDynJacobianCol(var1); - int id2 = getDynJacobianCol(var2); - - int col_nb = id1 * dynJacobianColsNbr + id2; - - derivative deriv(col_nb + eq *hessianColsNbr, col_nb, eq, it->second); - D.push_back(deriv); - if (id1 != id2) - { - col_nb = id2 * dynJacobianColsNbr + id1; - derivative deriv(col_nb + eq *hessianColsNbr, col_nb, eq, it->second); - D.push_back(deriv); - } - } - sort(D.begin(), D.end(), derivative_less_than()); - - // Writing Hessian - vector row_ptr(equations.size()); - fill(row_ptr.begin(), row_ptr.end(), 0.0); - int k = 0; - for (vector::const_iterator it = D.begin(); it != D.end(); ++it) - { - row_ptr[it->row_nbr]++; - mDynamicModelFile << "col_ptr[" << k << "] " - << "=" << it->col_nbr << ";" << endl; - mDynamicModelFile << "value[" << k << "] = "; - // oCstaticModel makes reference to the static variables - it->value->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms); - mDynamicModelFile << ";" << endl; - k++; - } - - // row_ptr must point to the relative address of the first element of the row - int cumsum = 0; - mDynamicModelFile << "row_ptr = [ 0"; - for (vector::iterator it = row_ptr.begin(); it != row_ptr.end(); ++it) - { - cumsum += *it; - mDynamicModelFile << ", " << cumsum; - } - mDynamicModelFile << "];" << endl; - - mDynamicModelFile << "}" << endl; - - writePowerDeriv(mDynamicModelFile); - writeNormcdf(mDynamicModelFile); - mDynamicModelFile.close(); -} - -void -DynamicModel::writeThirdDerivativesC_csr(const string &basename, bool cuda) const -{ - string filename = basename + "_third_derivatives.c"; - ofstream mDynamicModelFile, mDynamicMexFile; - - mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary); - if (!mDynamicModelFile.is_open()) - { - cerr << "Error: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - mDynamicModelFile << "/*" << endl - << " * " << filename << " : Computes third order derivatives of the model for Dynare" << endl - << " *" << endl - << " * Warning : this file is generated automatically by Dynare" << endl - << " * from model " << basename << "(.mod)" << endl - << " */" << endl -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - << "#ifdef _MSC_VER" << endl - << "#define _USE_MATH_DEFINES" << endl - << "#endif" << endl -#endif - << "#include " << endl; - - mDynamicModelFile << "#include " << endl; - - mDynamicModelFile << "#define max(a, b) (((a) > (b)) ? (a) : (b))" << endl - << "#define min(a, b) (((a) > (b)) ? (b) : (a))" << endl; - - // Write function definition if oPowerDeriv is used - writePowerDerivCHeader(mDynamicModelFile); - writeNormcdfCHeader(mDynamicModelFile); - - mDynamicModelFile << "void ThirdDerivatives(const double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, double *g1, double *v2, double *v3)" << endl - << "{" << endl; - - // this is always empty here, but needed by d1->writeOutput - deriv_node_temp_terms_t tef_terms; - - vector D; - int hessianColsNbr = dynJacobianColsNbr*dynJacobianColsNbr; - int thirdDerivativesColsNbr = hessianColsNbr*dynJacobianColsNbr; - for (third_derivatives_t::const_iterator it = third_derivatives.begin(); - it != third_derivatives.end(); it++) - { - int eq = it->first.first; - int var1 = it->first.second.first; - int var2 = it->first.second.second.first; - int var3 = it->first.second.second.second; - - int id1 = getDynJacobianCol(var1); - int id2 = getDynJacobianCol(var2); - int id3 = getDynJacobianCol(var3); - - // Reference column number for the g3 matrix (with symmetrical derivatives) - vector cols; - long unsigned int col_nb = id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3; - int thirdDColsNbr = hessianColsNbr*dynJacobianColsNbr; - derivative deriv(col_nb + eq *thirdDColsNbr, col_nb, eq, it->second); - D.push_back(deriv); - cols.push_back(col_nb); - col_nb = id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2; - if (find(cols.begin(), cols.end(), col_nb) == cols.end()) - { - derivative deriv(col_nb + eq *thirdDerivativesColsNbr, col_nb, eq, it->second); - D.push_back(deriv); - cols.push_back(col_nb); - } - col_nb = id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3; - if (find(cols.begin(), cols.end(), col_nb) == cols.end()) - { - derivative deriv(col_nb + eq *thirdDerivativesColsNbr, col_nb, eq, it->second); - D.push_back(deriv); - cols.push_back(col_nb); - } - col_nb = id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1; - if (find(cols.begin(), cols.end(), col_nb) == cols.end()) - { - derivative deriv(col_nb + eq *thirdDerivativesColsNbr, col_nb, eq, it->second); - D.push_back(deriv); - cols.push_back(col_nb); - } - col_nb = id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2; - if (find(cols.begin(), cols.end(), col_nb) == cols.end()) - { - derivative deriv(col_nb + eq *thirdDerivativesColsNbr, col_nb, eq, it->second); - D.push_back(deriv); - cols.push_back(col_nb); - } - col_nb = id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1; - if (find(cols.begin(), cols.end(), col_nb) == cols.end()) - { - derivative deriv(col_nb + eq *thirdDerivativesColsNbr, col_nb, eq, it->second); - D.push_back(deriv); - } - } - - sort(D.begin(), D.end(), derivative_less_than()); - - vector row_ptr(equations.size()); - fill(row_ptr.begin(), row_ptr.end(), 0.0); - int k = 0; - for (vector::const_iterator it = D.begin(); it != D.end(); ++it) - { - row_ptr[it->row_nbr]++; - mDynamicModelFile << "col_ptr[" << k << "] " - << "=" << it->col_nbr << ";" << endl; - mDynamicModelFile << "value[" << k << "] = "; - // oCstaticModel makes reference to the static variables - it->value->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms); - mDynamicModelFile << ";" << endl; - k++; - } - - // row_ptr must point to the relative address of the first element of the row - int cumsum = 0; - mDynamicModelFile << "row_ptr = [ 0"; - for (vector::iterator it = row_ptr.begin(); it != row_ptr.end(); ++it) - { - cumsum += *it; - mDynamicModelFile << ", " << cumsum; - } - mDynamicModelFile << "];" << endl; - - mDynamicModelFile << "}" << endl; - - writePowerDeriv(mDynamicModelFile); - writeNormcdf(mDynamicModelFile); - mDynamicModelFile.close(); - -} - -void -DynamicModel::writeCCOutput(ostream &output, const string &basename, bool block_decomposition, bool byte_code, bool use_dll, int order, bool estimation_present) const -{ - int lag_presence[3]; - // Loop on endogenous variables - for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++) - { - // Loop on periods - for (int lag = 0; lag <= 2; lag++) - { - lag_presence[lag] = 1; - try - { - getDerivID(symbol_table.getID(eEndogenous, endoID), lag-1); - } - catch (UnknownDerivIDException &e) - { - lag_presence[lag] = 0; - } - } - if (lag_presence[0] == 1) - if (lag_presence[2] == 1) - output << "zeta_mixed.push_back(" << endoID << ");" << endl; - else - output << "zeta_back.push_back(" << endoID << ");" << endl; - else if (lag_presence[2] == 1) - output << "zeta_fwrd.push_back(" << endoID << ");" << endl; - else - output << "zeta_static.push_back(" << endoID << ");" << endl; - - } - output << "nstatic = zeta_static.size();" << endl - << "nfwrd = zeta_fwrd.size();" << endl - << "nback = zeta_back.size();" << endl - << "nmixed = zeta_mixed.size();" << endl; - - // Write number of non-zero derivatives - // Use -1 if the derivatives have not been computed - output << endl - << "NNZDerivatives.push_back(" << NNZDerivatives[0] << ");" << endl; - if (order > 1) - { - output << "NNZDerivatives.push_back(" << NNZDerivatives[1] << ");" << endl; - if (order > 2) - output << "NNZDerivatives.push_back(" << NNZDerivatives[2] << ");" << endl; - else - output << "NNZDerivatives.push_back(-1);" << endl; - } - else - output << "NNZDerivatives.push_back(-1);" << endl - << "NNZDerivatives.push_back(-1);" << endl; -} - -void -DynamicModel::writeJsonOutput(ostream &output) const -{ - writeJsonModelEquations(output, false); - output << ", "; - writeJsonXrefs(output); -} - -void -DynamicModel::writeJsonXrefsHelper(ostream &output, const map, set > &xrefs) const -{ - for (map, set >::const_iterator it = xrefs.begin(); - it != xrefs.end(); it++) - { - if (it != xrefs.begin()) - output << ", "; - output << "{\"name\": \"" << symbol_table.getName(it->first.first) << "\"" - << ", \"shift\": " << it->first.second - << ", \"equations\": ["; - for (set::const_iterator it1 = it->second.begin(); - it1 != it->second.end(); it1++) - { - if (it1 != it->second.begin()) - output << ", "; - output << *it1 + 1; - } - output << "]}"; - } -} - -void -DynamicModel::writeJsonXrefs(ostream &output) const -{ - output << "\"xrefs\": {" - << "\"parameters\": ["; - writeJsonXrefsHelper(output, xref_param); - output << "]" - << ", \"endogenous\": ["; - writeJsonXrefsHelper(output, xref_endo); - output << "]" - << ", \"exogenous\": ["; - writeJsonXrefsHelper(output, xref_exo); - output << "]" - << ", \"exogenous_deterministic\": ["; - writeJsonXrefsHelper(output, xref_exo_det); - output << "]}" << endl; -} - -void -DynamicModel::writeJsonOriginalModelOutput(ostream &output) const -{ - writeJsonModelEquations(output, false); -} - -void -DynamicModel::writeJsonDynamicModelInfo(ostream &output) const -{ - output << "\"model_info\": {" - << "\"lead_lag_incidence\": ["; - // Loop on endogenous variables - int nstatic = 0, - nfwrd = 0, - npred = 0, - nboth = 0; - for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++) - { - if (endoID != 0) - output << ","; - output << "["; - int sstatic = 1, - sfwrd = 0, - spred = 0, - sboth = 0; - // Loop on periods - for (int lag = -max_endo_lag; lag <= max_endo_lead; lag++) - { - // Print variableID if exists with current period, otherwise print 0 - try - { - if (lag != -max_endo_lag) - output << ","; - int varID = getDerivID(symbol_table.getID(eEndogenous, endoID), lag); - output << " " << getDynJacobianCol(varID) + 1; - if (lag == -1) - { - sstatic = 0; - spred = 1; - } - else if (lag == 1) - { - if (spred == 1) - { - sboth = 1; - spred = 0; - } - else - { - sstatic = 0; - sfwrd = 1; - } - } - } - catch (UnknownDerivIDException &e) - { - output << " 0"; - } - } - nstatic += sstatic; - nfwrd += sfwrd; - npred += spred; - nboth += sboth; - output << "]"; - } - output << "], " - << "\"nstatic\": " << nstatic << ", " - << "\"nfwrd\": " << nfwrd << ", " - << "\"npred\": " << npred << ", " - << "\"nboth\": " << nboth << ", " - << "\"nsfwrd\": " << nfwrd+nboth << ", " - << "\"nspred\": " << npred+nboth << ", " - << "\"ndynamic\": " << npred+nboth+nfwrd << endl; - output << "}"; -} - -void -DynamicModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) const -{ - ostringstream model_local_vars_output; // Used for storing model local vars - ostringstream model_output; // Used for storing model temp vars and equations - ostringstream jacobian_output; // Used for storing jacobian equations - ostringstream hessian_output; // Used for storing Hessian equations - ostringstream third_derivatives_output; // Used for storing third order derivatives equations - - deriv_node_temp_terms_t tef_terms; - temporary_terms_t temp_term_empty; - temporary_terms_t temp_term_union = temporary_terms_res; - temporary_terms_t temp_term_union_m_1; - - string concat = ""; - int hessianColsNbr = dynJacobianColsNbr * dynJacobianColsNbr; - - writeJsonModelLocalVariables(model_local_vars_output, tef_terms); - - writeJsonTemporaryTerms(temporary_terms_res, temp_term_union_m_1, model_output, tef_terms, concat); - model_output << ", "; - writeJsonModelEquations(model_output, true); - - // Writing Jacobian - temp_term_union_m_1 = temp_term_union; - temp_term_union.insert(temporary_terms_g1.begin(), temporary_terms_g1.end()); - concat = "jacobian"; - writeJsonTemporaryTerms(temp_term_union, temp_term_union_m_1, jacobian_output, tef_terms, concat); - jacobian_output << ", \"jacobian\": {" - << " \"nrows\": " << equations.size() - << ", \"ncols\": " << dynJacobianColsNbr - << ", \"entries\": ["; - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - if (it != first_derivatives.begin()) - jacobian_output << ", "; - - int eq = it->first.first; - int var = it->first.second; - int col = getDynJacobianCol(var); - expr_t d1 = it->second; - - if (writeDetails) - jacobian_output << "{\"eq\": " << eq + 1; - else - jacobian_output << "{\"row\": " << eq + 1; - - jacobian_output << ", \"col\": " << col + 1; - - if (writeDetails) - jacobian_output << ", \"var\": \"" << symbol_table.getName(getSymbIDByDerivID(var)) << "\"" - << ", \"shift\": " << getLagByDerivID(var); - - jacobian_output << ", \"val\": \""; - d1->writeJsonOutput(jacobian_output, temp_term_union, tef_terms); - jacobian_output << "\"}" << endl; - } - jacobian_output << "]}"; - - // Writing Hessian - temp_term_union_m_1 = temp_term_union; - temp_term_union.insert(temporary_terms_g2.begin(), temporary_terms_g2.end()); - concat = "hessian"; - writeJsonTemporaryTerms(temp_term_union, temp_term_union_m_1, hessian_output, tef_terms, concat); - hessian_output << ", \"hessian\": {" - << " \"nrows\": " << equations.size() - << ", \"ncols\": " << hessianColsNbr - << ", \"entries\": ["; - for (second_derivatives_t::const_iterator it = second_derivatives.begin(); - it != second_derivatives.end(); it++) - { - if (it != second_derivatives.begin()) - hessian_output << ", "; - - int eq = it->first.first; - int var1 = it->first.second.first; - int var2 = it->first.second.second; - expr_t d2 = it->second; - int id1 = getDynJacobianCol(var1); - int id2 = getDynJacobianCol(var2); - int col_nb = id1 * dynJacobianColsNbr + id2; - int col_nb_sym = id2 * dynJacobianColsNbr + id1; - - if (writeDetails) - hessian_output << "{\"eq\": " << eq + 1; - else - hessian_output << "{\"row\": " << eq + 1; - - hessian_output << ", \"col\": [" << col_nb + 1; - if (id1 != id2) - hessian_output << ", " << col_nb_sym + 1; - hessian_output << "]"; - - if (writeDetails) - hessian_output << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" - << ", \"shift1\": " << getLagByDerivID(var1) - << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" - << ", \"shift2\": " << getLagByDerivID(var2); - - hessian_output << ", \"val\": \""; - d2->writeJsonOutput(hessian_output, temp_term_union, tef_terms); - hessian_output << "\"}" << endl; - } - hessian_output << "]}"; - - // Writing third derivatives - temp_term_union_m_1 = temp_term_union; - temp_term_union.insert(temporary_terms_g3.begin(), temporary_terms_g3.end()); - concat = "third_derivatives"; - writeJsonTemporaryTerms(temp_term_union, temp_term_union_m_1, third_derivatives_output, tef_terms, concat); - third_derivatives_output << ", \"third_derivative\": {" - << " \"nrows\": " << equations.size() - << ", \"ncols\": " << hessianColsNbr * dynJacobianColsNbr - << ", \"entries\": ["; - for (third_derivatives_t::const_iterator it = third_derivatives.begin(); - it != third_derivatives.end(); it++) - { - if (it != third_derivatives.begin()) - third_derivatives_output << ", "; - - int eq = it->first.first; - int var1 = it->first.second.first; - int var2 = it->first.second.second.first; - int var3 = it->first.second.second.second; - expr_t d3 = it->second; - - if (writeDetails) - third_derivatives_output << "{\"eq\": " << eq + 1; - else - third_derivatives_output << "{\"row\": " << eq + 1; - - int id1 = getDynJacobianCol(var1); - int id2 = getDynJacobianCol(var2); - int id3 = getDynJacobianCol(var3); - set cols; - cols.insert(id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3); - cols.insert(id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2); - cols.insert(id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3); - cols.insert(id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1); - cols.insert(id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2); - cols.insert(id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1); - - third_derivatives_output << ", \"col\": ["; - for (set::iterator it2 = cols.begin(); it2 != cols.end(); it2++) - { - if (it2 != cols.begin()) - third_derivatives_output << ", "; - third_derivatives_output << *it2 + 1; - } - third_derivatives_output << "]"; - - if (writeDetails) - third_derivatives_output << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" - << ", \"shift1\": " << getLagByDerivID(var1) - << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" - << ", \"shift2\": " << getLagByDerivID(var2) - << ", \"var3\": \"" << symbol_table.getName(getSymbIDByDerivID(var3)) << "\"" - << ", \"shift3\": " << getLagByDerivID(var3); - - third_derivatives_output << ", \"val\": \""; - d3->writeJsonOutput(third_derivatives_output, temp_term_union, tef_terms); - third_derivatives_output << "\"}" << endl; - } - third_derivatives_output << "]}"; - - if (writeDetails) - output << "\"dynamic_model\": {"; - else - output << "\"dynamic_model_simple\": {"; - output << model_local_vars_output.str() - << ", " << model_output.str() - << ", " << jacobian_output.str() - << ", " << hessian_output.str() - << ", " << third_derivatives_output.str() - << "}"; -} - -void -DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) const -{ - if (!residuals_params_derivatives.size() - && !residuals_params_second_derivatives.size() - && !jacobian_params_derivatives.size() - && !jacobian_params_second_derivatives.size() - && !hessian_params_derivatives.size()) - return; - - ostringstream model_local_vars_output; // Used for storing model local vars - ostringstream model_output; // Used for storing model temp vars and equations - ostringstream jacobian_output; // Used for storing jacobian equations - ostringstream hessian_output; // Used for storing Hessian equations - ostringstream hessian1_output; // Used for storing Hessian equations - ostringstream third_derivs_output; // Used for storing third order derivatives equations - ostringstream third_derivs1_output; // Used for storing third order derivatives equations - - deriv_node_temp_terms_t tef_terms; - writeJsonModelLocalVariables(model_local_vars_output, tef_terms); - - temporary_terms_t temp_terms_empty; - string concat = "all"; - writeJsonTemporaryTerms(params_derivs_temporary_terms, temp_terms_empty, model_output, tef_terms, concat); - jacobian_output << "\"deriv_wrt_params\": {" - << " \"neqs\": " << equations.size() - << ", \"nparamcols\": " << symbol_table.param_nbr() - << ", \"entries\": ["; - for (first_derivatives_t::const_iterator it = residuals_params_derivatives.begin(); - it != residuals_params_derivatives.end(); it++) - { - if (it != residuals_params_derivatives.begin()) - jacobian_output << ", "; - - int eq = it->first.first; - int param = it->first.second; - expr_t d1 = it->second; - - int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; - - if (writeDetails) - jacobian_output << "{\"eq\": " << eq + 1; - else - jacobian_output << "{\"row\": " << eq + 1; - - jacobian_output << ", \"param_col\": " << param_col + 1; - - if (writeDetails) - jacobian_output << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; - - jacobian_output << ", \"val\": \""; - d1->writeJsonOutput(jacobian_output, params_derivs_temporary_terms, tef_terms); - jacobian_output << "\"}" << endl; - } - jacobian_output << "]}"; - hessian_output << "\"deriv_jacobian_wrt_params\": {" - << " \"neqs\": " << equations.size() - << ", \"nvarcols\": " << dynJacobianColsNbr - << ", \"nparamcols\": " << symbol_table.param_nbr() - << ", \"entries\": ["; - for (second_derivatives_t::const_iterator it = jacobian_params_derivatives.begin(); - it != jacobian_params_derivatives.end(); it++) - { - if (it != jacobian_params_derivatives.begin()) - hessian_output << ", "; - - int eq = it->first.first; - int var = it->first.second.first; - int param = it->first.second.second; - expr_t d2 = it->second; - - int var_col = getDynJacobianCol(var) + 1; - int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; - - if (writeDetails) - hessian_output << "{\"eq\": " << eq + 1; - else - hessian_output << "{\"row\": " << eq + 1; - - hessian_output << ", \"var_col\": " << var_col + 1 - << ", \"param_col\": " << param_col + 1; - - if (writeDetails) - hessian_output << ", \"var\": \"" << symbol_table.getName(getSymbIDByDerivID(var)) << "\"" - << ", \"lag\": " << getLagByDerivID(var) - << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; - - hessian_output << ", \"val\": \""; - d2->writeJsonOutput(hessian_output, params_derivs_temporary_terms, tef_terms); - hessian_output << "\"}" << endl; - } - hessian_output << "]}"; - - hessian1_output << "\"second_deriv_residuals_wrt_params\": {" - << " \"nrows\": " << equations.size() - << ", \"nparam1cols\": " << symbol_table.param_nbr() - << ", \"nparam2cols\": " << symbol_table.param_nbr() - << ", \"entries\": ["; - for (second_derivatives_t::const_iterator it = residuals_params_second_derivatives.begin(); - it != residuals_params_second_derivatives.end(); ++it) - { - if (it != residuals_params_second_derivatives.begin()) - hessian1_output << ", "; - - int eq = it->first.first; - int param1 = it->first.second.first; - int param2 = it->first.second.second; - expr_t d2 = it->second; - - int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; - int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; - - if (writeDetails) - hessian1_output << "{\"eq\": " << eq + 1; - else - hessian1_output << "{\"row\": " << eq + 1; - hessian1_output << ", \"param1_col\": " << param1_col + 1 - << ", \"param2_col\": " << param2_col + 1; - - if (writeDetails) - hessian1_output << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param1)) << "\"" - << ", \"param2\": \"" << symbol_table.getName(getSymbIDByDerivID(param2)) << "\""; - - hessian1_output << ", \"val\": \""; - d2->writeJsonOutput(hessian1_output, params_derivs_temporary_terms, tef_terms); - hessian1_output << "\"}" << endl; - } - hessian1_output << "]}"; - third_derivs_output << "\"second_deriv_jacobian_wrt_params\": {" - << " \"neqs\": " << equations.size() - << ", \"nvarcols\": " << dynJacobianColsNbr - << ", \"nparam1cols\": " << symbol_table.param_nbr() - << ", \"nparam2cols\": " << symbol_table.param_nbr() - << ", \"entries\": ["; - for (third_derivatives_t::const_iterator it = jacobian_params_second_derivatives.begin(); - it != jacobian_params_second_derivatives.end(); ++it) - { - if (it != jacobian_params_second_derivatives.begin()) - third_derivs_output << ", "; - - int eq = it->first.first; - int var = it->first.second.first; - int param1 = it->first.second.second.first; - int param2 = it->first.second.second.second; - expr_t d2 = it->second; - - int var_col = getDynJacobianCol(var) + 1; - int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; - int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; - - if (writeDetails) - third_derivs_output << "{\"eq\": " << eq + 1; - else - third_derivs_output << "{\"row\": " << eq + 1; - - third_derivs_output << ", \"var_col\": " << var_col + 1 - << ", \"param1_col\": " << param1_col + 1 - << ", \"param2_col\": " << param2_col + 1; - - if (writeDetails) - third_derivs_output << ", \"var\": \"" << symbol_table.getName(var) << "\"" - << ", \"lag\": " << getLagByDerivID(var) - << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param1)) << "\"" - << ", \"param2\": \"" << symbol_table.getName(getSymbIDByDerivID(param2)) << "\""; - - third_derivs_output << ", \"val\": \""; - d2->writeJsonOutput(third_derivs_output, params_derivs_temporary_terms, tef_terms); - third_derivs_output << "\"}" << endl; - } - third_derivs_output << "]}" << endl; - - third_derivs1_output << "\"derivative_hessian_wrt_params\": {" - << " \"neqs\": " << equations.size() - << ", \"nvar1cols\": " << dynJacobianColsNbr - << ", \"nvar2cols\": " << dynJacobianColsNbr - << ", \"nparamcols\": " << symbol_table.param_nbr() - << ", \"entries\": ["; - for (third_derivatives_t::const_iterator it = hessian_params_derivatives.begin(); - it != hessian_params_derivatives.end(); ++it) - { - if (it != hessian_params_derivatives.begin()) - third_derivs1_output << ", "; - - int eq = it->first.first; - int var1 = it->first.second.first; - int var2 = it->first.second.second.first; - int param = it->first.second.second.second; - expr_t d2 = it->second; - - int var1_col = getDynJacobianCol(var1) + 1; - int var2_col = getDynJacobianCol(var2) + 1; - int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; - - if (writeDetails) - third_derivs1_output << "{\"eq\": " << eq + 1; - else - third_derivs1_output << "{\"row\": " << eq + 1; - - third_derivs1_output << ", \"var1_col\": " << var1_col + 1 - << ", \"var2_col\": " << var2_col + 1 - << ", \"param_col\": " << param_col + 1; - - if (writeDetails) - third_derivs1_output << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" - << ", \"lag1\": " << getLagByDerivID(var1) - << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" - << ", \"lag2\": " << getLagByDerivID(var2) - << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; - - third_derivs1_output << ", \"val\": \""; - d2->writeJsonOutput(third_derivs1_output, params_derivs_temporary_terms, tef_terms); - third_derivs1_output << "\"}" << endl; - } - third_derivs1_output << "]}" << endl; - - if (writeDetails) - output << "\"dynamic_model_params_derivative\": {"; - else - output << "\"dynamic_model_params_derivatives_simple\": {"; - output << model_local_vars_output.str() - << ", " << model_output.str() - << ", " << jacobian_output.str() - << ", " << hessian_output.str() - << ", " << hessian1_output.str() - << ", " << third_derivs_output.str() - << ", " << third_derivs1_output.str() - << "}"; -} diff --git a/preprocessor/DynamicModel.hh b/preprocessor/DynamicModel.hh deleted file mode 100644 index 3a93a7ced..000000000 --- a/preprocessor/DynamicModel.hh +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright (C) 2003-2018 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 . - */ - -#ifndef _DYNAMICMODEL_HH -#define _DYNAMICMODEL_HH - -using namespace std; -#define ZERO_BAND 1e-8 - -#include -#include - -#include "StaticModel.hh" - -//! Stores a dynamic model -class DynamicModel : public ModelTree -{ -private: - //! Stores equations declared as [static] - /*! They will be used in toStatic() to replace equations marked as [dynamic] */ - vector static_only_equations; - - //! Stores line numbers of equations declared as [static] - vector static_only_equations_lineno; - - //! Stores the equation tags of equations declared as [static] - vector > > static_only_equations_equation_tags; - - typedef map, int> deriv_id_table_t; - //! Maps a pair (symbol_id, lag) to a deriv ID - deriv_id_table_t deriv_id_table; - //! Maps a deriv ID to a pair (symbol_id, lag) - vector > inv_deriv_id_table; - - //! Maps a deriv_id to the column index of the dynamic Jacobian - /*! Contains only endogenous, exogenous and exogenous deterministic */ - map dyn_jacobian_cols_table; - - //! Maximum lag and lead over all types of variables (positive values) - /*! Set by computeDerivIDs() */ - int max_lag, max_lead; - //! Maximum lag and lead over endogenous variables (positive values) - /*! Set by computeDerivIDs() */ - int max_endo_lag, max_endo_lead; - //! Maximum lag and lead over exogenous variables (positive values) - /*! Set by computeDerivIDs() */ - int max_exo_lag, max_exo_lead; - //! Maximum lag and lead over deterministic exogenous variables (positive values) - /*! Set by computeDerivIDs() */ - int max_exo_det_lag, max_exo_det_lead; - //! Maximum lag and lead over all types of variables (positive values) of original model - int max_lag_orig, max_lead_orig; - //! Maximum lag and lead over endogenous variables (positive values) of original model - int max_endo_lag_orig, max_endo_lead_orig; - //! Maximum lag and lead over exogenous variables (positive values) of original model - int max_exo_lag_orig, max_exo_lead_orig; - //! Maximum lag and lead over deterministic exogenous variables (positive values) of original model - int max_exo_det_lag_orig, max_exo_det_lead_orig; - - //! Cross reference information - map xrefs; - map, set > xref_param; - map, set > xref_endo; - map, set > xref_exo; - map, set > xref_exo_det; - - //! Nonzero equations in the Hessian - map 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 > v_temporary_terms; - - vector v_temporary_terms_inuse; - - //! Store the derivatives or the chainrule derivatives:map, 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 >, 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 >, expr_t> collect_first_order_derivatives_endogenous(); - - //! Allocates the derivation IDs for all dynamic variables of the model - /*! Also computes max_{endo,exo}_{lead_lag}, and initializes dynJacobianColsNbr to the number of dynamic endos */ - void computeDerivIDs(); - - //! Write chain rule derivative of a recursive equation w.r. to a variable - void writeChainRuleDerivative(ostream &output, int eq, int var, int lag, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const; - - //! Collecte the derivatives w.r. to endogenous of the block, to endogenous of previouys blocks and to exogenous - void collect_block_first_order_derivatives(); - - //! Collecte the informations about exogenous, deterministic exogenous and endogenous from the previous block for each block - void collectBlockVariables(); - - //! Factorized code for substitutions of leads/lags - /*! \param[in] type determines which type of variables is concerned - \param[in] deterministic_model whether we are in a deterministic model (only for exogenous leads/lags) - \param[in] subset variables to which to apply the transformation (only for diff of forward vars) - */ - void substituteLeadLagInternal(aux_var_t type, bool deterministic_model, const vector &subset); - -private: - //! Indicate if the temporary terms are computed for the overall model (true) or not (false). Default value true - bool global_temporary_terms; - - //! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a expr_t on the new normalized equation - equation_type_and_normalized_equation_t equation_type_and_normalized_equation; - - //! for each block contains pair< Simulation_Type, pair < Block_Size, Recursive_part_Size > > - block_type_firstequation_size_mfs_t block_type_firstequation_size_mfs; - - //! for all blocks derivatives description - blocks_derivatives_t blocks_derivatives; - - //! The jacobian without the elements below the cutoff - dynamic_jacob_map_t dynamic_jacobian; - - //! Vector indicating if the block is linear in endogenous variable (true) or not (false) - vector blocks_linear; - - //! Map the derivatives for a block pair - typedef map >, expr_t> derivative_t; - //! Vector of derivative for each blocks - vector derivative_endo, derivative_other_endo, derivative_exo, derivative_exo_det; - - //!List for each block and for each lag-lead all the other endogenous variables and exogenous variables - typedef set var_t; - typedef map lag_var_t; - vector other_endo_block, exo_block, exo_det_block; - - //!List for each block the exogenous variables - vector > block_var_exo; - - map< int, map > block_exo_index, block_det_exo_index, block_other_endo_index; - - //! for each block described the number of static, forward, backward and mixed variables in the block - /*! pair< pair, pair > */ - vector, pair > > block_col_type; - - //! Help computeXrefs to compute the reverse references (i.e. param->eqs, endo->eqs, etc) - void computeRevXref(map, set > &xrefset, const set > &eiref, int eqn); - - //! Write reverse cross references - void writeRevXrefs(ostream &output, const map, set > &xrefmap, const string &type) const; - - //! List for each variable its block number and its maximum lag and lead inside the block - vector > > variable_block_lead_lag; - //! List for each equation its block number - vector equation_block; - - //!Maximum lead and lag for each block on endogenous of the block, endogenous of the previous blocks, exogenous and deterministic exogenous - vector > endo_max_leadlag_block, other_endo_max_leadlag_block, exo_max_leadlag_block, exo_det_max_leadlag_block, max_leadlag_block; - -public: - DynamicModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_argx); - //! Adds a variable node - /*! This implementation allows for non-zero lag */ - virtual VariableNode *AddVariable(int symb_id, int lag = 0); - - //! Compute cross references - void computeXrefs(); - - //! Write cross references - void writeXrefs(ostream &output) const; - - //! Execute computations (variable sorting + derivation) - /*! - \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 hessian whether 2nd derivatives w.r. to exo, exo_det and endo should be computed (implies jacobianExo = true) - \param thirdDerivatives whether 3rd derivatives w.r. to endo/exo/exo_det should be computed (implies jacobianExo = true) - \param paramsDerivsOrder order of derivatives w.r. to a pair (endo/exo/exo_det, parameter) to be computed (>0 implies jacobianExo = true) - \param eval_context evaluation context for normalization - \param no_tmp_terms if true, no temporary terms will be computed in the dynamic files - */ - void computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, int paramsDerivsOrder, - const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode, const bool nopreprocessoroutput); - //! Writes model initialization and lead/lag incidence matrix to output - 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; - - //! Write JSON Output - void writeJsonOutput(ostream &output) const; - - //! Write JSON Output representation of original dynamic model - void writeJsonOriginalModelOutput(ostream &output) const; - - //! Write JSON Output representation of model info (useful stuff from M_) - void writeJsonDynamicModelInfo(ostream &output) const; - - //! Write JSON Output representation of dynamic model after computing pass - void writeJsonComputingPassOutput(ostream &output, bool writeDetails) const; - - //! Write JSON prams derivatives file - void writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) const; - - //! Write cross reference output if the xref maps have been filed - void writeJsonXrefs(ostream &output) const; - void writeJsonXrefsHelper(ostream &output, const map, set > &xrefs) const; - - //! Print equations that have non-zero second derivatives - void printNonZeroHessianEquations(ostream &output) const; - - //! Set the equations that have non-zero second derivatives - void setNonZeroHessianEquations(map &eqs); - - //! 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 - void writeParamsDerivativesFile(const string &basename, bool julia) const; - - //! Converts to static model (only the equations) - /*! It assumes that the static model given in argument has just been allocated */ - void toStatic(StaticModel &static_model) const; - - //! Find endogenous variables not used in model - set findUnusedEndogenous(); - //! Find exogenous variables not used in model - set findUnusedExogenous(); - - //! Set the max leads/lags of the original model - void setLeadsLagsOrig(); - - //! Copies a dynamic model (only the equations) - /*! It assumes that the dynamic model given in argument has just been allocated */ - void cloneDynamic(DynamicModel &dynamic_model) const; - - //! 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 - void replaceMyEquations(DynamicModel &dynamic_model) const; - - //! Adds an equation marked as [static] - void addStaticOnlyEquation(expr_t eq, int lineno, const vector > &eq_tags); - - //! Returns number of static only equations - size_t staticOnlyEquationsNbr() const; - - //! Returns number of dynamic only equations - size_t dynamicOnlyEquationsNbr() const; - - //! Writes LaTeX file with the equations of the dynamic model - void writeLatexFile(const string &basename, const bool write_equation_tags) const; - - //! 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; - - virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException); - virtual int getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDException); - virtual void addAllParamDerivId(set &deriv_id_set); - - //! Returns true indicating that this is a dynamic model - virtual bool - isDynamic() const - { - return true; - }; - - //! Drive test of detrended equations - void runTrendTest(const eval_context_t &eval_context); - - //! Transforms the model by removing all leads greater or equal than 2 on endos - /*! Note that this can create new lags on endos and exos */ - void substituteEndoLeadGreaterThanTwo(bool deterministic_model); - - //! Transforms the model by removing all lags greater or equal than 2 on endos - void substituteEndoLagGreaterThanTwo(bool deterministic_model); - - //! Transforms the model by removing all leads on exos - /*! Note that this can create new lags on endos and exos */ - void substituteExoLead(bool deterministic_model); - - //! Transforms the model by removing all lags on exos - void substituteExoLag(bool deterministic_model); - - //! Transforms the model by removing all oExpectation - void substituteExpectation(bool partial_information_model); - - //! Transforms the model by decreasing the lead/lag of predetermined variables in model equations by one - void transformPredeterminedVariables(); - - //! Transforms the model by removing trends specified by the user - void detrendEquations(); - - //! Transforms the model by replacing trend variables with a 1 - void removeTrendVariableFromEquations(); - - //! Transforms the model by creating aux vars for the diff of forward vars - /*! If subset is empty, does the transformation for all fwrd vars; otherwise - restrict it to the vars in subset */ - void differentiateForwardVars(const vector &subset); - - //! Fills eval context with values of model local variables and auxiliary variables - void fillEvalContext(eval_context_t &eval_context) const; - - //! Return the number of blocks - virtual unsigned int - getNbBlocks() const - { - return (block_type_firstequation_size_mfs.size()); - }; - //! Determine the simulation type of each block - virtual BlockSimulationType - getBlockSimulationType(int block_number) 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::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 the block number containing the endogenous variable variable_number - int - getBlockVariableID(int variable_number) const - { - return (variable_block_lead_lag[variable_number].first); - }; - //! 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 >::const_iterator it = block_exo_index.find(block_number); - if (it != block_exo_index.end()) - { - map::const_iterator it1 = it->second.find(variable_number); - if (it1 != it->second.end()) - return it1->second; - else - return -1; - } - else - return (-1); - }; - //! 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 >::const_iterator it = block_det_exo_index.find(block_number); - if (it != block_det_exo_index.end()) - { - map::const_iterator it1 = it->second.find(variable_number); - if (it1 != it->second.end()) - return it1->second; - else - return -1; - } - else - return (-1); - }; - //! 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 >::const_iterator it = block_other_endo_index.find(block_number); - if (it != block_other_endo_index.end()) - { - map::const_iterator it1 = it->second.find(variable_number); - if (it1 != it->second.end()) - return it1->second; - else - return -1; - } - else - return (-1); - }; - bool isModelLocalVariableUsed() const; - - //! Returns true if a parameter was used in the model block with a lead or lag - bool ParamUsedWithLeadLag() const; - - //! Writes model initialization and lead/lag incidence matrix to C output - void writeCOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll, int order, bool estimation_present) const; - //! 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; -}; - -//! Classes to re-order derivatives for various sparse storage formats -class derivative -{ -public: - long unsigned int linear_address; - long unsigned int col_nbr; - 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) - { - }; -}; - -class derivative_less_than -{ -public: - bool - operator()(const derivative &d1, const derivative &d2) const - { - return d1.linear_address < d2.linear_address; - } -}; -#endif diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy deleted file mode 100644 index 64c3a796c..000000000 --- a/preprocessor/DynareBison.yy +++ /dev/null @@ -1,3766 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -%skeleton "lalr1.cc" -%require "2.5" -%defines - -%code top { -class ParsingDriver; -} - -%code requires { -#include "ExprNode.hh" -#include "CodeInterpreter.hh" -} - -%name-prefix "Dynare" - -%parse-param { ParsingDriver &driver } -%lex-param { ParsingDriver &driver } - -%locations -%initial-action -{ - // Initialize the locations' filenames to the filename maintained by the lexer - @$.begin.filename = @$.end.filename = &(driver.lexer->filename); -} - -%debug -%error-verbose - -%union -{ - string *string_val; - expr_t node_val; - SymbolType symbol_type_val; - vector *vector_string_val; - vector *vector_int_val; - pair *string_pair_val; - vector *> *vector_string_pair_val; - PriorDistributions prior_distributions_val; -}; - -%code { -/* Little hack: we redefine the macro which computes the locations, because - we need to access the location from within the parsing driver for error - and warning messages. */ -#define YYLLOC_DEFAULT(Current, Rhs, N) \ - do { \ - if (N) \ - { \ - (Current).begin = YYRHSLOC(Rhs, 1).begin; \ - (Current).end = YYRHSLOC(Rhs, N).end; \ - } \ - else \ - { \ - (Current).begin = (Current).end = YYRHSLOC(Rhs, 0).end; \ - } \ - driver.location = (Current); \ - } while(false) - -#include "ParsingDriver.hh" - -/* this "connects" the bison parser in the driver to the flex scanner class - * object. it defines the yylex() function call to pull the next token from the - * current lexer object of the driver context. */ -#undef yylex -#define yylex driver.lexer->lex -} - -%token AIM_SOLVER ANALYTIC_DERIVATION ANALYTIC_DERIVATION_MODE AR AUTOCORR POSTERIOR_SAMPLING_METHOD -%token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION SILENT_OPTIMIZER -%token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION DR_DISPLAY_TOL HUGE_NUMBER FIG_NAME WRITE_XLS -%token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA INTERACTIVE SCREEN_SHOCKS STEADYSTATE -%token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN DETAIL_PLOT TYPE -%token BVAR_REPLIC BYTECODE ALL_VALUES_REQUIRED PROPOSAL_DISTRIBUTION REALTIME VINTAGE -%token CALIB_SMOOTHER CHANGE_TYPE CHECK CONDITIONAL_FORECAST CONDITIONAL_FORECAST_PATHS CONF_SIG CONSTANT CONTROLLED_VAREXO CORR COVAR CUTOFF CYCLE_REDUCTION LOGARITHMIC_REDUCTION -%token CONSIDER_ALL_ENDOGENOUS CONSIDER_ONLY_OBSERVED INITIAL_CONDITION_DECOMPOSITION -%token DATAFILE FILE SERIES DOUBLING DR_CYCLE_REDUCTION_TOL DR_LOGARITHMIC_REDUCTION_TOL DR_LOGARITHMIC_REDUCTION_MAXITER DR_ALGO DROP DSAMPLE DYNASAVE DYNATYPE CALIBRATION DIFFERENTIATE_FORWARD_VARS -%token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT EXTENDED_PATH ENDOGENOUS_PRIOR -%token FILENAME DIRNAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME OSR_PARAMS_BOUNDS KEEP_KALMAN_ALGO_IF_SINGULARITY_IS_DETECTED -%token FLOAT_NUMBER DATES -%token DEFAULT FIXED_POINT OPT_ALGO -%token FORECAST K_ORDER_SOLVER INSTRUMENTS SHIFT MEAN STDEV VARIANCE MODE INTERVAL SHAPE DOMAINN -%token GAMMA_PDF GRAPH GRAPH_FORMAT CONDITIONAL_VARIANCE_DECOMPOSITION NOCHECK STD -%token HISTVAL HISTVAL_FILE HOMOTOPY_SETUP HOMOTOPY_MODE HOMOTOPY_STEPS HOMOTOPY_FORCE_CONTINUE HP_FILTER HP_NGRID HYBRID ONE_SIDED_HP_FILTER -%token IDENTIFICATION INF_CONSTANT INITVAL INITVAL_FILE BOUNDS JSCALE INIT INFILE INVARS -%token INT_NUMBER -%token INV_GAMMA_PDF INV_GAMMA1_PDF INV_GAMMA2_PDF IRF IRF_SHOCKS IRF_PLOT_THRESHOLD IRF_CALIBRATION -%token FAST_KALMAN_FILTER KALMAN_ALGO KALMAN_TOL DIFFUSE_KALMAN_TOL SUBSAMPLES OPTIONS TOLF TOLX PLOT_INIT_DATE PLOT_END_DATE -%token LAPLACE LIK_ALGO LIK_INIT LINEAR LOAD_IDENT_FILES LOAD_MH_FILE LOAD_RESULTS_AFTER_LOAD_MH LOAD_PARAMS_AND_STEADY_STATE LOGLINEAR LOGDATA LYAPUNOV LINEAR_APPROXIMATION -%token LYAPUNOV_FIXED_POINT_TOL LYAPUNOV_DOUBLING_TOL LYAPUNOV_SQUARE_ROOT_SOLVER_TOL LOG_DEFLATOR LOG_TREND_VAR LOG_GROWTH_FACTOR MARKOWITZ MARGINAL_DENSITY MAX MAXIT -%token MFS MH_CONF_SIG MH_DROP MH_INIT_SCALE MH_JSCALE MH_MODE MH_NBLOCKS MH_REPLIC MH_RECOVER POSTERIOR_MAX_SUBSAMPLE_DRAWS MIN MINIMAL_SOLVING_PERIODS -%token MODE_CHECK MODE_CHECK_NEIGHBOURHOOD_SIZE MODE_CHECK_SYMMETRIC_PLOTS MODE_CHECK_NUMBER_OF_POINTS MODE_COMPUTE MODE_FILE MODEL MODEL_COMPARISON MODEL_INFO MSHOCKS ABS SIGN -%token MODEL_DIAGNOSTICS MODIFIEDHARMONICMEAN MOMENTS_VARENDO CONTEMPORANEOUS_CORRELATION DIFFUSE_FILTER SUB_DRAWS TAPER_STEPS GEWEKE_INTERVAL RAFTERY_LEWIS_QRS RAFTERY_LEWIS_DIAGNOSTICS MCMC_JUMPING_COVARIANCE MOMENT_CALIBRATION -%token NUMBER_OF_PARTICLES RESAMPLING SYSTEMATIC GENERIC RESAMPLING_THRESHOLD RESAMPLING_METHOD KITAGAWA STRATIFIED SMOOTH -%token CPF_WEIGHTS AMISANOTRISTANI MURRAYJONESPARSLOW WRITE_EQUATION_TAGS -%token NONLINEAR_FILTER_INITIALIZATION FILTER_ALGORITHM PROPOSAL_APPROXIMATION CUBATURE UNSCENTED MONTECARLO DISTRIBUTION_APPROXIMATION -%token NAME -%token USE_PENALIZED_OBJECTIVE_FOR_HESSIAN INIT_STATE FAST_REALTIME RESCALE_PREDICTION_ERROR_COVARIANCE GENERATE_IRFS -%token NAN_CONSTANT NO_STATIC NOBS NOCONSTANT NODISPLAY NOCORR NODIAGNOSTIC NOFUNCTIONS NO_HOMOTOPY -%token NOGRAPH POSTERIOR_NOGRAPH POSTERIOR_GRAPH NOMOMENTS NOPRINT NORMAL_PDF SAVE_DRAWS STDERR_MULTIPLES DIAGONAL_ONLY -%token OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS MAX_DIM_COVA_GROUP ADVANCED OUTFILE OUTVARS OVERWRITE -%token PARALLEL_LOCAL_FILES PARAMETERS PARAMETER_SET PARTIAL_INFORMATION PERIODS PERIOD PLANNER_OBJECTIVE PLOT_CONDITIONAL_FORECAST PLOT_PRIORS PREFILTER PRESAMPLE -%token PERFECT_FORESIGHT_SETUP PERFECT_FORESIGHT_SOLVER NO_POSTERIOR_KERNEL_DENSITY FUNCTION -%token PRINT PRIOR_MC PRIOR_TRUNC PRIOR_MODE PRIOR_MEAN POSTERIOR_MODE POSTERIOR_MEAN POSTERIOR_MEDIAN MLE_MODE PRUNING -%token QUOTED_STRING -%token QZ_CRITERIUM QZ_ZERO_THRESHOLD FULL DSGE_VAR DSGE_VARLAG DSGE_PRIOR_WEIGHT TRUNCATE -%token RELATIVE_IRF REPLIC SIMUL_REPLIC RPLOT SAVE_PARAMS_AND_STEADY_STATE PARAMETER_UNCERTAINTY -%token SHOCKS SHOCK_DECOMPOSITION SHOCK_GROUPS USE_SHOCK_GROUPS SIGMA_E SIMUL SIMUL_ALGO SIMUL_SEED ENDOGENOUS_TERMINAL_PERIOD -%token SMOOTHER SMOOTHER2HISTVAL SQUARE_ROOT_SOLVER STACK_SOLVE_ALGO STEADY_STATE_MODEL SOLVE_ALGO SOLVER_PERIODS ROBUST_LIN_SOLVE -%token STDERR STEADY STOCH_SIMUL SURPRISE SYLVESTER SYLVESTER_FIXED_POINT_TOL REGIMES REGIME REALTIME_SHOCK_DECOMPOSITION -%token TEX RAMSEY_MODEL RAMSEY_POLICY RAMSEY_CONSTRAINTS PLANNER_DISCOUNT DISCRETIONARY_POLICY DISCRETIONARY_TOL -%token TEX_NAME -%token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL USEAUTOCORR GSA_SAMPLE_FILE USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED -%token VALUES VAR VAREXO VAREXO_DET VAROBS PREDETERMINED_VARIABLES PLOT_SHOCK_DECOMPOSITION MODEL_LOCAL_VARIABLE -%token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL WRITE_LATEX_ORIGINAL_MODEL WRITE_LATEX_STEADY_STATE_MODEL -%token XLS_SHEET XLS_RANGE LMMCP OCCBIN BANDPASS_FILTER COLORMAP QOQ YOY AOA -%left COMMA -%left EQUAL_EQUAL EXCLAMATION_EQUAL -%left LESS GREATER LESS_EQUAL GREATER_EQUAL -%left PLUS MINUS -%left TIMES DIVIDE -%left UMINUS UPLUS -%nonassoc POWER -%token EXP LOG LN LOG10 SIN COS TAN ASIN ACOS ATAN SINH COSH TANH ERF -%token ASINH ACOSH ATANH SQRT NORMCDF NORMPDF STEADY_STATE EXPECTATION -/* GSA analysis */ -%token DYNARE_SENSITIVITY MORRIS STAB REDFORM PPRIOR PRIOR_RANGE PPOST ILPTAU MORRIS_NLIV -%token MORRIS_NTRA NSAM LOAD_REDFORM LOAD_RMSE LOAD_STAB ALPHA2_STAB LOGTRANS_REDFORM THRESHOLD_REDFORM -%token KSSTAT_REDFORM ALPHA2_REDFORM NAMENDO NAMLAGENDO NAMEXO RMSE LIK_ONLY VAR_RMSE PFILT_RMSE ISTART_RMSE -%token ALPHA_RMSE ALPHA2_RMSE -/* end of GSA analysis*/ -%token FREQ INITIAL_YEAR INITIAL_SUBPERIOD FINAL_YEAR FINAL_SUBPERIOD DATA VLIST LOG_VAR PERCENT_VAR -%token VLISTLOG VLISTPER SPECTRAL_DENSITY -%token RESTRICTION RESTRICTION_FNAME CROSS_RESTRICTIONS NLAGS CONTEMP_REDUCED_FORM REAL_PSEUDO_FORECAST -%token DUMMY_OBS NSTATES INDXSCALESSTATES NO_BAYESIAN_PRIOR SPECIFICATION SIMS_ZHA -%token ALPHA BETA ABAND NINV CMS NCMS CNUM GAMMA INV_GAMMA INV_GAMMA1 INV_GAMMA2 NORMAL UNIFORM EPS PDF FIG DR NONE PRIOR PRIOR_VARIANCE HESSIAN IDENTITY_MATRIX DIRICHLET DIAGONAL OPTIMAL -%token GSIG2_LMDM Q_DIAG FLAT_PRIOR NCSK NSTD WEIBULL WEIBULL_PDF -%token INDXPARR INDXOVR INDXAP APBAND INDXIMF IMFBAND INDXFORE FOREBAND INDXGFOREHAT INDXGIMFHAT -%token INDXESTIMA INDXGDLS EQ_MS FILTER_COVARIANCE FILTER_DECOMPOSITION SMOOTHED_STATE_UNCERTAINTY -%token EQ_CMS TLINDX TLNUMBER BANACT RESTRICTIONS POSTERIOR_SAMPLER_OPTIONS -%token OUTPUT_FILE_TAG DRAWS_NBR_BURN_IN_1 DRAWS_NBR_BURN_IN_2 HORIZON -%token SBVAR TREND_VAR DEFLATOR GROWTH_FACTOR MS_IRF MS_VARIANCE_DECOMPOSITION -%token MS_ESTIMATION MS_SIMULATION MS_COMPUTE_MDD MS_COMPUTE_PROBABILITIES MS_FORECAST -%token SVAR_IDENTIFICATION EQUATION EXCLUSION LAG UPPER_CHOLESKY LOWER_CHOLESKY MONTHLY QUARTERLY -%token MARKOV_SWITCHING CHAIN DURATION NUMBER_OF_REGIMES NUMBER_OF_LAGS -%token SVAR SVAR_GLOBAL_IDENTIFICATION_CHECK COEFF COEFFICIENTS VARIANCES CONSTANTS EQUATIONS -%token EXTERNAL_FUNCTION EXT_FUNC_NAME EXT_FUNC_NARGS FIRST_DERIV_PROVIDED SECOND_DERIV_PROVIDED -%token SELECTED_VARIABLES_ONLY COVA_COMPUTE SIMULATION_FILE_TAG FILE_TAG -%token NO_ERROR_BANDS ERROR_BAND_PERCENTILES SHOCKS_PER_PARAMETER NO_CREATE_INIT -%token SHOCK_DRAWS FREE_PARAMETERS MEDIAN DATA_OBS_NBR NEIGHBORHOOD_WIDTH PVALUE_KS PVALUE_CORR -%token FILTERED_PROBABILITIES REAL_TIME_SMOOTHED PRIOR_FUNCTION POSTERIOR_FUNCTION SAMPLING_DRAWS -%token PROPOSAL_TYPE PROPOSAL_UPPER_BOUND PROPOSAL_LOWER_BOUND PROPOSAL_DRAWS USE_MEAN_CENTER -%token ADAPTIVE_MH_DRAWS THINNING_FACTOR COEFFICIENTS_PRIOR_HYPERPARAMETERS SMM_ESTIMATION GMM_ESTIMATION -%token CONVERGENCE_STARTING_VALUE CONVERGENCE_ENDING_VALUE CONVERGENCE_INCREMENT_VALUE -%token MAX_ITERATIONS_STARTING_VALUE MAX_ITERATIONS_INCREMENT_VALUE MAX_BLOCK_ITERATIONS -%token MAX_REPEATED_OPTIMIZATION_RUNS FUNCTION_CONVERGENCE_CRITERION SAVE_REALTIME -%token PARAMETER_CONVERGENCE_CRITERION NUMBER_OF_LARGE_PERTURBATIONS NUMBER_OF_SMALL_PERTURBATIONS -%token NUMBER_OF_POSTERIOR_DRAWS_AFTER_PERTURBATION MAX_NUMBER_OF_STAGES -%token RANDOM_FUNCTION_CONVERGENCE_CRITERION RANDOM_PARAMETER_CONVERGENCE_CRITERION -%token CENTERED_MOMENTS AUTOLAG RECURSIVE_ORDER_ESTIMATION BARTLETT_KERNEL_LAG WEIGHTING_MATRIX PENALIZED_ESTIMATOR VERBOSE -%token SIMULATION_MULTIPLE SEED BOUNDED_SHOCK_SUPPORT -%token ANALYTICAL_GIRF IRF_IN_PERCENT EMAS_GIRF EMAS_DROP EMAS_TOLF EMAS_MAX_ITER - -%token SYMBOL_VEC - -%type expression expression_or_empty -%type equation hand_side -%type non_negative_number signed_number signed_integer date_str -%type filename symbol vec_of_vec_value vec_value_list date_expr -%type vec_value_1 vec_value signed_inf signed_number_w_inf -%type range vec_value_w_inf vec_value_1_w_inf -%type integer_range signed_integer_range sub_sampling_options list_sub_sampling_option -%type named_var_elem -%type named_var named_var_1 -%type change_type_arg -%type change_type_var_list subsamples_eq_opt prior_eq_opt options_eq_opt calibration_range -%type vec_int_elem vec_int_1 vec_int vec_int_number -%type prior_pdf prior_distribution -%% - -%start statement_list; - -statement_list : statement - | statement_list statement - ; - -statement : parameters - | var - | varexo - | varexo_det - | predetermined_variables - | model_local_variable - | change_type - | periods - | model - | initval - | initval_file - | endval - | histval - | init_param - | shocks - | mshocks - | sigma_e - | steady - | check - | simul - | stoch_simul - | estimation - | estimated_params - | estimated_params_bounds - | estimated_params_init - | set_time - | data - | prior - | prior_eq - | subsamples - | subsamples_eq - | options - | options_eq - | varobs - | observation_trends - | unit_root_vars - | dsample - | rplot - | optim_weights - | osr_params - | osr_params_bounds - | osr - | dynatype - | dynasave - | model_comparison - | model_info - | planner_objective - | ramsey_model - | ramsey_policy - | ramsey_constraints - | discretionary_policy - | bvar_density - | bvar_forecast - | sbvar - | dynare_sensitivity - | homotopy_setup - | forecast - | load_params_and_steady_state - | save_params_and_steady_state - | identification - | write_latex_dynamic_model - | write_latex_static_model - | write_latex_original_model - | write_latex_steady_state_model - | shock_decomposition - | realtime_shock_decomposition - | plot_shock_decomposition - | initial_condition_decomposition - | conditional_forecast - | conditional_forecast_paths - | plot_conditional_forecast - | svar_identification - | svar_global_identification_check - | markov_switching - | svar - | external_function - | steady_state_model - | trend_var - | generate_irfs - | log_trend_var - | ms_estimation - | ms_simulation - | ms_compute_mdd - | ms_compute_probabilities - | ms_forecast - | ms_irf - | ms_variance_decomposition - | calib_smoother - | extended_path - | model_diagnostics - | moment_calibration - | irf_calibration - | smoother2histval - | histval_file - | perfect_foresight_setup - | perfect_foresight_solver - | prior_function - | posterior_function - | gmm_estimation - | smm_estimation - | shock_groups - ; - -dsample : DSAMPLE INT_NUMBER ';' - { driver.dsample($2); } - | DSAMPLE INT_NUMBER INT_NUMBER ';' - { driver.dsample($2, $3); } - ; - -rplot : RPLOT symbol_list ';' { driver.rplot(); }; - -trend_var : TREND_VAR '(' GROWTH_FACTOR EQUAL { driver.begin_trend(); } hand_side ')' trend_var_list ';' - { driver.end_trend_var($6); } - ; - -trend_var_list : trend_var_list symbol - { driver.declare_trend_var(false, $2); } - | trend_var_list COMMA symbol - { driver.declare_trend_var(false, $3); } - | symbol - { driver.declare_trend_var(false, $1); } - | trend_var_list symbol TEX_NAME - { driver.declare_trend_var(false, $2, $3); } - | trend_var_list COMMA symbol TEX_NAME - { driver.declare_trend_var(false, $3, $4); } - | symbol TEX_NAME - { driver.declare_trend_var(false, $1, $2); } - ; - -log_trend_var : LOG_TREND_VAR '(' LOG_GROWTH_FACTOR EQUAL { driver.begin_trend(); } hand_side ')' log_trend_var_list ';' - { driver.end_trend_var($6); } - ; - -log_trend_var_list : log_trend_var_list symbol - { driver.declare_trend_var(true, $2); } - | log_trend_var_list COMMA symbol - { driver.declare_trend_var(true, $3); } - | symbol - { driver.declare_trend_var(true, $1); } - | log_trend_var_list symbol TEX_NAME - { driver.declare_trend_var(true, $2, $3); } - | log_trend_var_list COMMA symbol TEX_NAME - { driver.declare_trend_var(true, $3, $4); } - | symbol TEX_NAME - { driver.declare_trend_var(true, $1, $2); } - ; - -var : VAR var_list ';' - | VAR '(' DEFLATOR EQUAL { driver.begin_trend(); } hand_side ')' nonstationary_var_list ';' - { driver.end_nonstationary_var(false, $6); } - | VAR '(' LOG_DEFLATOR EQUAL { driver.begin_trend(); } hand_side ')' nonstationary_var_list ';' - { driver.end_nonstationary_var(true, $6); } - ; - -nonstationary_var_list : nonstationary_var_list symbol - { driver.declare_nonstationary_var($2); } - | nonstationary_var_list COMMA symbol - { driver.declare_nonstationary_var($3); } - | symbol - { driver.declare_nonstationary_var($1); } - | nonstationary_var_list symbol named_var - { driver.declare_nonstationary_var($2, NULL, $3); } - | nonstationary_var_list COMMA symbol named_var - { driver.declare_nonstationary_var($3, NULL, $4); } - | symbol named_var - { driver.declare_nonstationary_var($1, NULL, $2); } - | nonstationary_var_list symbol TEX_NAME - { driver.declare_nonstationary_var($2, $3); } - | nonstationary_var_list COMMA symbol TEX_NAME - { driver.declare_nonstationary_var($3, $4); } - | symbol TEX_NAME - { driver.declare_nonstationary_var($1, $2); } - | nonstationary_var_list symbol TEX_NAME named_var - { driver.declare_nonstationary_var($2, $3, $4); } - | nonstationary_var_list COMMA symbol TEX_NAME named_var - { driver.declare_nonstationary_var($3, $4, $5); } - | symbol TEX_NAME named_var - { driver.declare_nonstationary_var($1, $2, $3); } - ; - -varexo : VAREXO varexo_list ';'; - -varexo_det : VAREXO_DET varexo_det_list ';'; - -predetermined_variables : PREDETERMINED_VARIABLES predetermined_variables_list ';'; - -parameters : PARAMETERS parameter_list ';'; - -model_local_variable : MODEL_LOCAL_VARIABLE model_local_variable_list ';'; - -named_var_elem : symbol EQUAL QUOTED_STRING - { - pair *pr = new pair($1, $3); - $$ = pr; - } - -named_var_1 : '(' named_var_elem - { - $$ = new vector *>(); - $$->push_back($2); - } - | '(' COMMA named_var_elem - { - $$ = new vector *>(); - $$->push_back($3); - } - | named_var_1 named_var_elem - { - $1->push_back($2); - $$ = $1; - } - | named_var_1 COMMA named_var_elem - { - $1->push_back($3); - $$ = $1; - } - ; - -named_var : named_var_1 ')' { $$ = $1; } - | named_var_1 COMMA ')' { $$ = $1; } - ; - -var_list : var_list symbol - { driver.declare_endogenous($2); } - | var_list COMMA symbol - { driver.declare_endogenous($3); } - | symbol - { driver.declare_endogenous($1); } - | var_list symbol named_var - { driver.declare_endogenous($2, NULL, $3); } - | var_list COMMA symbol named_var - { driver.declare_endogenous($3, NULL, $4); } - | symbol named_var - { driver.declare_endogenous($1, NULL, $2); } - | var_list symbol TEX_NAME - { driver.declare_endogenous($2, $3); } - | var_list COMMA symbol TEX_NAME - { driver.declare_endogenous($3, $4); } - | symbol TEX_NAME - { driver.declare_endogenous($1, $2); } - | var_list symbol TEX_NAME named_var - { driver.declare_endogenous($2, $3, $4); } - | var_list COMMA symbol TEX_NAME named_var - { driver.declare_endogenous($3, $4, $5); } - | symbol TEX_NAME named_var - { driver.declare_endogenous($1, $2, $3); } - ; - -varexo_list : varexo_list symbol - { driver.declare_exogenous($2); } - | varexo_list COMMA symbol - { driver.declare_exogenous($3); } - | symbol - { driver.declare_exogenous($1); } - | varexo_list symbol named_var - { driver.declare_exogenous($2, NULL, $3); } - | varexo_list COMMA symbol named_var - { driver.declare_exogenous($3, NULL, $4); } - | symbol named_var - { driver.declare_exogenous($1, NULL, $2); } - | varexo_list symbol TEX_NAME - { driver.declare_exogenous($2, $3); } - | varexo_list COMMA symbol TEX_NAME - { driver.declare_exogenous($3, $4); } - | symbol TEX_NAME - { driver.declare_exogenous($1, $2); } - | varexo_list symbol TEX_NAME named_var - { driver.declare_exogenous($2, $3, $4); } - | varexo_list COMMA symbol TEX_NAME named_var - { driver.declare_exogenous($3, $4, $5); } - | symbol TEX_NAME named_var - { driver.declare_exogenous($1, $2, $3); } - ; - -varexo_det_list : varexo_det_list symbol - { driver.declare_exogenous_det($2); } - | varexo_det_list COMMA symbol - { driver.declare_exogenous_det($3); } - | symbol - { driver.declare_exogenous_det($1); } - | varexo_det_list symbol named_var - { driver.declare_exogenous_det($2, NULL, $3); } - | varexo_det_list COMMA symbol named_var - { driver.declare_exogenous_det($3, NULL, $4); } - | symbol named_var - { driver.declare_exogenous_det($1, NULL, $2); } - | varexo_det_list symbol TEX_NAME - { driver.declare_exogenous_det($2, $3); } - | varexo_det_list COMMA symbol TEX_NAME - { driver.declare_exogenous_det($3, $4); } - | symbol TEX_NAME - { driver.declare_exogenous_det($1, $2); } - | varexo_det_list symbol TEX_NAME named_var - { driver.declare_exogenous_det($2, $3, $4); } - | varexo_det_list COMMA symbol TEX_NAME named_var - { driver.declare_exogenous_det($3, $4, $5); } - | symbol TEX_NAME named_var - { driver.declare_exogenous_det($1, $2, $3); } - ; - -parameter_list : parameter_list symbol - { driver.declare_parameter($2); } - | parameter_list COMMA symbol - { driver.declare_parameter($3); } - | symbol - { driver.declare_parameter($1); } - | parameter_list symbol named_var - { driver.declare_parameter($2, NULL, $3); } - | parameter_list COMMA symbol named_var - { driver.declare_parameter($3, NULL, $4); } - | symbol named_var - { driver.declare_parameter($1, NULL, $2); } - | parameter_list symbol TEX_NAME - { driver.declare_parameter($2, $3); } - | parameter_list COMMA symbol TEX_NAME - { driver.declare_parameter($3, $4); } - | symbol TEX_NAME - { driver.declare_parameter($1, $2); } - | parameter_list symbol TEX_NAME named_var - { driver.declare_parameter($2, $3, $4); } - | parameter_list COMMA symbol TEX_NAME named_var - { driver.declare_parameter($3, $4, $5); } - | symbol TEX_NAME named_var - { driver.declare_parameter($1, $2, $3); } - ; - -predetermined_variables_list : predetermined_variables_list symbol - { driver.add_predetermined_variable($2); } - | predetermined_variables_list COMMA symbol - { driver.add_predetermined_variable($3); } - | symbol - { driver.add_predetermined_variable($1); } - ; - -model_local_variable_list : model_local_variable_list symbol - { driver.declare_model_local_variable($2); } - | model_local_variable_list COMMA symbol - { driver.declare_model_local_variable($3); } - | symbol - { driver.declare_model_local_variable($1); } - | model_local_variable_list symbol TEX_NAME - { driver.declare_model_local_variable($2, $3); } - | model_local_variable_list COMMA symbol TEX_NAME - { driver.declare_model_local_variable($3, $4); } - | symbol TEX_NAME - { driver.declare_model_local_variable($1, $2); } - ; - -change_type : CHANGE_TYPE '(' change_type_arg ')' change_type_var_list ';' - { driver.change_type($3, $5); } - ; - -change_type_arg : PARAMETERS - { $$ = eParameter; } - | VAR - { $$ = eEndogenous; } - | VAREXO - { $$ = eExogenous; } - | VAREXO_DET - { $$ = eExogenousDet; } - ; - -change_type_var_list : symbol - { $$ = new vector(); $$->push_back($1); } - | change_type_var_list symbol - { $$ = $1; $1->push_back($2); } - | change_type_var_list COMMA symbol - { $$ = $1; $1->push_back($3); } - ; - -periods : PERIODS INT_NUMBER ';' - { driver.periods($2); } - | PERIODS EQUAL INT_NUMBER ';' - { driver.periods($3); } - ; - -init_param : symbol EQUAL expression ';' { driver.init_param($1, $3); }; - -expression : '(' expression ')' - { $$ = $2;} - | symbol - { $$ = driver.add_expression_variable($1); } - | non_negative_number - { $$ = driver.add_non_negative_constant($1); } - | expression PLUS expression - { $$ = driver.add_plus($1, $3); } - | expression MINUS expression - { $$ = driver.add_minus($1, $3); } - | expression DIVIDE expression - { $$ = driver.add_divide($1, $3); } - | expression TIMES expression - { $$ = driver.add_times($1, $3); } - | expression POWER expression - { $$ = driver.add_power($1, $3); } - | expression LESS expression - { $$ = driver.add_less($1, $3); } - | expression GREATER expression - { $$ = driver.add_greater($1, $3); } - | expression LESS_EQUAL expression - { $$ = driver.add_less_equal($1, $3); } - | expression GREATER_EQUAL expression - { $$ = driver.add_greater_equal($1, $3); } - | expression EQUAL_EQUAL expression - { $$ = driver.add_equal_equal($1, $3); } - | expression EXCLAMATION_EQUAL expression - { $$ = driver.add_different($1, $3); } - | MINUS expression %prec UMINUS - { $$ = driver.add_uminus($2); } - | PLUS expression %prec UPLUS - { $$ = $2; } - | EXP '(' expression ')' - { $$ = driver.add_exp($3); } - | LOG '(' expression ')' - { $$ = driver.add_log($3); } - | LN '(' expression ')' - { $$ = driver.add_log($3); } - | LOG10 '(' expression ')' - { $$ = driver.add_log10($3); } - | SIN '(' expression ')' - { $$ = driver.add_sin($3); } - | COS '(' expression ')' - { $$ = driver.add_cos($3); } - | TAN '(' expression ')' - { $$ = driver.add_tan($3); } - | ASIN '(' expression ')' - { $$ = driver.add_asin($3); } - | ACOS '(' expression ')' - { $$ = driver.add_acos($3); } - | ATAN '(' expression ')' - { $$ = driver.add_atan($3); } - | SQRT '(' expression ')' - { $$ = driver.add_sqrt($3); } - | ABS '(' expression ')' - { $$ = driver.add_abs($3); } - | SIGN '(' expression ')' - { $$ = driver.add_sign($3); } - | MAX '(' expression COMMA expression ')' - { $$ = driver.add_max($3, $5); } - | MIN '(' expression COMMA expression ')' - { $$ = driver.add_min($3, $5); } - | symbol { driver.push_external_function_arg_vector_onto_stack(); } '(' comma_expression ')' - { $$ = driver.add_model_var_or_external_function($1, false); } - | NORMCDF '(' expression COMMA expression COMMA expression ')' - { $$ = driver.add_normcdf($3, $5, $7); } - | NORMCDF '(' expression ')' - { $$ = driver.add_normcdf($3); } - | NORMPDF '(' expression COMMA expression COMMA expression ')' - { $$ = driver.add_normpdf($3, $5, $7); } - | NORMPDF '(' expression ')' - { $$ = driver.add_normpdf($3); } - | ERF '(' expression ')' - { $$ = driver.add_erf($3); } - | NAN_CONSTANT - { $$ = driver.add_nan_constant(); } - | INF_CONSTANT - { $$ = driver.add_inf_constant(); } - ; - -comma_expression : expression - { driver.add_external_function_arg($1); } - | comma_expression COMMA expression - { driver.add_external_function_arg($3); } - ; - -expression_or_empty : {$$ = driver.add_nan_constant();} - | expression - ; - -initval : INITVAL ';' initval_list END ';' - { driver.end_initval(false); } - | INITVAL '(' ALL_VALUES_REQUIRED ')' ';' initval_list END ';' - { driver.end_initval(true); } - ; - -initval_file : INITVAL_FILE '(' FILENAME EQUAL filename ')' ';' - { driver.initval_file($5); } - ; - -endval : ENDVAL ';' initval_list END ';' - { driver.end_endval(false); } - | ENDVAL '(' ALL_VALUES_REQUIRED ')' ';' initval_list END ';' - { driver.end_endval(true); } - ; - -initval_list : initval_list initval_elem - | initval_elem - ; - -initval_elem : symbol EQUAL expression ';' { driver.init_val($1, $3); }; - -histval : HISTVAL ';' histval_list END ';' - { driver.end_histval(false); }; - | HISTVAL '(' ALL_VALUES_REQUIRED ')' ';' histval_list END ';' - { driver.end_histval(true); } - ; - -histval_list : histval_list histval_elem - | histval_elem - ; - -histval_elem : symbol '(' signed_integer ')' EQUAL expression ';' { driver.hist_val($1, $3, $6); }; - -histval_file : HISTVAL_FILE '(' FILENAME EQUAL filename ')' ';' - { driver.histval_file($5); } - ; - -model_options : BLOCK { driver.block(); } - | o_cutoff - | o_mfs - | BYTECODE { driver.byte_code(); } - | USE_DLL { driver.use_dll(); } - | NO_STATIC { driver.no_static();} - | DIFFERENTIATE_FORWARD_VARS { driver.differentiate_forward_vars_all(); } - | DIFFERENTIATE_FORWARD_VARS EQUAL '(' symbol_list ')' { driver.differentiate_forward_vars_some(); } - | o_linear - | PARALLEL_LOCAL_FILES EQUAL '(' parallel_local_filename_list ')' - ; - -model_options_list : model_options_list COMMA model_options - | model_options - ; - -model : MODEL ';' { driver.begin_model(); } - equation_list END ';' { driver.end_model(); } - | MODEL '(' model_options_list ')' ';' { driver.begin_model(); } - equation_list END ';' { driver.end_model(); } - ; - -equation_list : equation_list equation - | equation_list pound_expression - | equation - | pound_expression - ; - -equation : hand_side EQUAL hand_side ';' - { $$ = driver.add_model_equal($1, $3); } - | hand_side ';' - { $$ = driver.add_model_equal_with_zero_rhs($1); } - | '[' tags_list ']' hand_side EQUAL hand_side ';' - { $$ = driver.add_model_equal($4, $6); } - | '[' tags_list ']' hand_side ';' - { $$ = driver.add_model_equal_with_zero_rhs($4); } - ; - -tags_list : tags_list COMMA tag_pair - | tag_pair - ; - -tag_pair : NAME EQUAL QUOTED_STRING - { driver.add_equation_tags($1, $3); } - | NAME - { driver.add_equation_tags($1, new string()); } - ; - -hand_side : '(' hand_side ')' - { $$ = $2;} - | symbol - { $$ = driver.add_model_variable($1); } - | non_negative_number - { $$ = driver.add_non_negative_constant($1); } - | hand_side PLUS hand_side - { $$ = driver.add_plus($1, $3); } - | hand_side MINUS hand_side - { $$ = driver.add_minus($1, $3); } - | hand_side DIVIDE hand_side - { $$ = driver.add_divide($1, $3); } - | hand_side TIMES hand_side - { $$ = driver.add_times($1, $3); } - | hand_side LESS hand_side - { $$ = driver.add_less($1, $3); } - | hand_side GREATER hand_side - { $$ = driver.add_greater($1, $3); } - | hand_side LESS_EQUAL hand_side - { $$ = driver.add_less_equal($1, $3); } - | hand_side GREATER_EQUAL hand_side - { $$ = driver.add_greater_equal($1, $3); } - | hand_side EQUAL_EQUAL hand_side - { $$ = driver.add_equal_equal($1, $3); } - | hand_side EXCLAMATION_EQUAL hand_side - { $$ = driver.add_different($1, $3); } - | hand_side POWER hand_side - { $$ = driver.add_power($1, $3); } - | EXPECTATION '(' signed_integer ')''(' hand_side ')' - { $$ = driver.add_expectation($3, $6); } - | MINUS hand_side %prec UMINUS - { $$ = driver.add_uminus($2); } - | PLUS hand_side - { $$ = $2; } - | EXP '(' hand_side ')' - { $$ = driver.add_exp($3); } - | LOG '(' hand_side ')' - { $$ = driver.add_log($3); } - | LN '(' hand_side ')' - { $$ = driver.add_log($3); } - | LOG10 '(' hand_side ')' - { $$ = driver.add_log10($3); } - | SIN '(' hand_side ')' - { $$ = driver.add_sin($3); } - | COS '(' hand_side ')' - { $$ = driver.add_cos($3); } - | TAN '(' hand_side ')' - { $$ = driver.add_tan($3); } - | ASIN '(' hand_side ')' - { $$ = driver.add_asin($3); } - | ACOS '(' hand_side ')' - { $$ = driver.add_acos($3); } - | ATAN '(' hand_side ')' - { $$ = driver.add_atan($3); } - | SQRT '(' hand_side ')' - { $$ = driver.add_sqrt($3); } - | ABS '(' hand_side ')' - { $$ = driver.add_abs($3); } - | SIGN '(' hand_side ')' - { $$ = driver.add_sign($3); } - | MAX '(' hand_side COMMA hand_side ')' - { $$ = driver.add_max($3, $5); } - | MIN '(' hand_side COMMA hand_side ')' - { $$ = driver.add_min($3, $5); } - | symbol { driver.push_external_function_arg_vector_onto_stack(); } '(' comma_hand_side ')' - { $$ = driver.add_model_var_or_external_function($1, true); } - | NORMCDF '(' hand_side COMMA hand_side COMMA hand_side ')' - { $$ = driver.add_normcdf($3, $5, $7); } - | NORMCDF '(' hand_side ')' - { $$ = driver.add_normcdf($3); } - | NORMPDF '(' hand_side COMMA hand_side COMMA hand_side ')' - { $$ = driver.add_normpdf($3, $5, $7); } - | NORMPDF '(' hand_side ')' - { $$ = driver.add_normpdf($3); } - | ERF '(' hand_side ')' - { $$ = driver.add_erf($3); } - | STEADY_STATE '(' hand_side ')' - { $$ = driver.add_steady_state($3); } - ; - -comma_hand_side : hand_side - { driver.add_external_function_arg($1); } - | comma_hand_side COMMA hand_side - { driver.add_external_function_arg($3); } - ; - -pound_expression: '#' symbol EQUAL hand_side ';' - { driver.declare_and_init_model_local_variable($2, $4); }; - -shocks : SHOCKS ';' shock_list END ';' { driver.end_shocks(false); } - | SHOCKS '(' OVERWRITE ')' ';' shock_list END ';' { driver.end_shocks(true); } - ; - -shock_list : shock_list shock_elem - | shock_elem - ; - -shock_elem : det_shock_elem - | VAR symbol ';' STDERR expression ';' - { driver.add_stderr_shock($2, $5); } - | VAR symbol EQUAL expression ';' - { driver.add_var_shock($2, $4); } - | VAR symbol COMMA symbol EQUAL expression ';' - { driver.add_covar_shock($2, $4, $6); } - | CORR symbol COMMA symbol EQUAL expression ';' - { driver.add_correl_shock($2, $4, $6); } - ; - -det_shock_elem : VAR symbol ';' PERIODS period_list ';' VALUES value_list ';' - { driver.add_det_shock($2, false); } - ; - -svar_identification : SVAR_IDENTIFICATION {driver.begin_svar_identification();} ';' svar_identification_list END ';' - { driver.end_svar_identification(); } - ; - -svar_identification_list : svar_identification_list svar_identification_elem - | svar_identification_elem - ; - -svar_identification_elem : EXCLUSION LAG INT_NUMBER ';' svar_equation_list - { driver.combine_lag_and_restriction($3); } - | EXCLUSION CONSTANTS ';' - { driver.add_constants_exclusion(); } - | RESTRICTION EQUATION INT_NUMBER COMMA - { driver.add_restriction_equation_nbr($3);} - restriction_expression EQUAL - {driver.add_restriction_equal();} - restriction_expression ';' - | UPPER_CHOLESKY ';' - { driver.add_upper_cholesky(); } - | LOWER_CHOLESKY ';' - { driver.add_lower_cholesky(); } - ; - -svar_equation_list : svar_equation_list EQUATION INT_NUMBER COMMA svar_var_list ';' - { driver.add_restriction_in_equation($3); } - | EQUATION INT_NUMBER COMMA svar_var_list ';' - { driver.add_restriction_in_equation($2); } - ; - -svar_var_list : svar_var_list COMMA symbol - { driver.add_in_svar_restriction_symbols($3); } - | symbol - { driver.add_in_svar_restriction_symbols($1); } - ; - -restriction_expression : expression {driver.check_restriction_expression_constant($1);} - | restriction_expression_1 - ; - -restriction_expression_1 : restriction_elem_expression - | restriction_expression_1 restriction_elem_expression - ; - -restriction_elem_expression : COEFF '(' symbol COMMA INT_NUMBER ')' - { driver.add_positive_restriction_element($3,$5);} - | PLUS COEFF '(' symbol COMMA INT_NUMBER ')' - { driver.add_positive_restriction_element($4,$6);} - | MINUS COEFF '(' symbol COMMA INT_NUMBER ')' - { driver.add_negative_restriction_element($4,$6);} - | expression TIMES COEFF '(' symbol COMMA INT_NUMBER ')' - { driver.add_positive_restriction_element($1,$5,$7);} - ; - -svar_global_identification_check: SVAR_GLOBAL_IDENTIFICATION_CHECK ';' - { driver.add_svar_global_identification_check(); } - ; - -markov_switching : MARKOV_SWITCHING '(' ms_options_list ')' ';' - { driver.markov_switching(); } - ; - -ms_options_list : ms_options_list COMMA ms_options - | ms_options - ; - -ms_options : o_chain - | o_duration - | o_restrictions - | o_number_of_regimes - | o_number_of_lags - | o_parameters - ; - -svar : SVAR '(' svar_options_list ')' ';' - { driver.svar(); } - ; - -svar_options_list : svar_options_list COMMA svar_options - | svar_options - ; - -svar_options : o_coefficients - | o_variances - | o_equations - | o_chain - ; - -mshocks : MSHOCKS ';' mshock_list END ';' { driver.end_mshocks(false); } - | MSHOCKS '(' OVERWRITE ')' ';' mshock_list END ';' { driver.end_mshocks(true); } - ; - -mshock_list : mshock_list det_shock_elem - | det_shock_elem - ; - -period_list : period_list COMMA INT_NUMBER - { driver.add_period($3); } - | period_list INT_NUMBER - { driver.add_period($2); } - | period_list COMMA INT_NUMBER ':' INT_NUMBER - { driver.add_period($3, $5); } - | period_list INT_NUMBER ':' INT_NUMBER - { driver.add_period($2, $4); } - | INT_NUMBER ':' INT_NUMBER - { driver.add_period($1, $3); } - | INT_NUMBER - { driver.add_period($1); } - ; - -sigma_e : SIGMA_E EQUAL '[' triangular_matrix ']' ';' { driver.do_sigma_e(); }; - -value_list : value_list COMMA '(' expression ')' - { driver.add_value($4); } - | value_list '(' expression ')' - { driver.add_value($3); } - | '(' expression ')' - { driver.add_value($2); } - | value_list COMMA signed_number - { driver.add_value($3); } - | value_list signed_number - { driver.add_value($2); } - | signed_number - { driver.add_value($1); } - ; - -triangular_matrix : triangular_matrix ';' triangular_row - { driver.end_of_row(); } - | triangular_row - { driver.end_of_row(); } - ; - -triangular_row : triangular_row COMMA '(' expression ')' - { driver.add_to_row($4); } - | triangular_row COMMA signed_number - { driver.add_to_row_const($3); } - | triangular_row '(' expression ')' - { driver.add_to_row($3); } - | triangular_row signed_number - { driver.add_to_row_const($2); } - | '(' expression ')' - { driver.add_to_row($2); } - | signed_number - { driver.add_to_row_const($1); } - ; - -steady : STEADY ';' - { driver.steady(); } - | STEADY '(' steady_options_list ')' ';' - { driver.steady(); } - ; - -steady_options_list : steady_options_list COMMA steady_options - | steady_options - ; - -steady_options : o_solve_algo - | o_homotopy_mode - | o_homotopy_steps - | o_homotopy_force_continue - | o_markowitz - | o_steady_maxit - | o_nocheck - | o_steady_tolf - ; - -check : CHECK ';' - { driver.check(); } - | CHECK '(' check_options_list ')' ';' - { driver.check(); } - ; - -check_options_list : check_options_list COMMA check_options - | check_options - ; - -check_options : steady_options - | o_qz_zero_threshold - ; - -model_info : MODEL_INFO ';' - { driver.model_info(); } - | MODEL_INFO '(' model_info_options_list ')' ';' - { driver.model_info(); } - ; - -model_info_options_list : model_info_options_list COMMA model_info_options - | model_info_options - ; -model_info_options : - -perfect_foresight_setup : PERFECT_FORESIGHT_SETUP ';' - { driver.perfect_foresight_setup(); } - | PERFECT_FORESIGHT_SETUP '(' perfect_foresight_setup_options_list ')' ';' - { driver.perfect_foresight_setup(); } - ; - -perfect_foresight_setup_options_list : perfect_foresight_setup_options_list COMMA perfect_foresight_setup_options - | perfect_foresight_setup_options - ; - -perfect_foresight_setup_options : o_periods - | o_datafile - ; - -perfect_foresight_solver : PERFECT_FORESIGHT_SOLVER ';' - { driver.perfect_foresight_solver(); } - | PERFECT_FORESIGHT_SOLVER '(' perfect_foresight_solver_options_list ')' ';' - { driver.perfect_foresight_solver(); } - ; - -perfect_foresight_solver_options_list : perfect_foresight_solver_options_list COMMA perfect_foresight_solver_options - | perfect_foresight_solver_options - ; - -perfect_foresight_solver_options : o_stack_solve_algo - | o_markowitz - | o_minimal_solving_periods - | o_simul_maxit - | o_endogenous_terminal_period - | o_linear_approximation - | o_no_homotopy - | o_solve_algo - | o_robust_lin_solve - | o_lmmcp - | o_occbin - | o_pf_tolf - | o_pf_tolx - ; - -gmm_smm_common_option : o_datafile - | o_nobs - | o_first_obs - | o_optim - | o_mode_file - | o_mode_compute - | o_prior_trunc - | o_loglinear - | o_logdata - | o_relative_irf - | o_irf - | o_tex - | o_xls_sheet - | o_xls_range - | o_solve_algo - | o_plot_priors - | o_aim_solver - | o_selected_variables_only - | o_irf_shocks - | o_sylvester - | o_sylvester_fixed_point_tol - | o_lyapunov - | o_lyapunov_fixed_point_tol - | o_lyapunov_doubling_tol - | o_dr - | o_dr_cycle_reduction_tol - | o_dr_logarithmic_reduction_tol - | o_dr_logarithmic_reduction_maxiter - | o_qz_zero_threshold - | o_irf_plot_threshold - | o_consider_all_endogenous - | o_consider_only_observed - | o_dirname - | o_huge_number - | o_silent_optimizer - | o_nograph - | o_nodisplay - | o_graph_format - | o_analytical_girf - | o_irf_in_percent - | o_emas_girf - | o_emas_drop - | o_emas_tolf - | o_emas_max_iter - | o_stderr_multiples - | o_diagonal_only - ; - -gmm_estimation : GMM_ESTIMATION '(' gmm_estimation_options_list ')' ';' - { driver.gmm_estimation(); } - | GMM_ESTIMATION '(' gmm_estimation_options_list ')' symbol_list ';' - { driver.gmm_estimation(); } - ; - -gmm_estimation_options_list : gmm_estimation_option COMMA gmm_estimation_options_list - | gmm_estimation_option - ; - -gmm_estimation_option : gmm_smm_common_option - | o_gmm_order - | o_gmm_centered_moments - | o_gmm_autolag - | o_gmm_recursive_order_estimation - | o_gmm_bartlett_kernel_lag - | o_gmm_weighting_matrix - | o_gmm_penalized_estimator - | o_gmm_verbose - ; - -smm_estimation : SMM_ESTIMATION '(' smm_estimation_options_list ')' ';' - { driver.smm_estimation(); } - | SMM_ESTIMATION '(' smm_estimation_options_list ')' symbol_list ';' - { driver.smm_estimation(); } - ; - -smm_estimation_options_list : smm_estimation_option COMMA smm_estimation_options_list - | smm_estimation_option - ; - -smm_estimation_option : gmm_smm_common_option - | o_smm_order - | o_smm_centered_moments - | o_smm_autolag - | o_smm_recursive_order_estimation - | o_smm_bartlett_kernel_lag - | o_smm_weighting_matrix - | o_smm_penalized_estimator - | o_smm_verbose - | o_smm_simulation_multiple - | o_smm_drop - | o_smm_seed - | o_smm_bounded_shock_support - ; - -prior_function : PRIOR_FUNCTION '(' prior_posterior_function_options_list ')' ';' - { driver.prior_posterior_function(true); } - ; - -posterior_function : POSTERIOR_FUNCTION '(' prior_posterior_function_options_list ')' ';' - { driver.prior_posterior_function(false); } - ; - -prior_posterior_function_options_list : prior_posterior_function_options_list COMMA prior_posterior_function_options - | prior_posterior_function_options - ; - -prior_posterior_function_options : o_function - | o_sampling_draws - ; - -simul : SIMUL ';' - { driver.simul(); } - | SIMUL '(' simul_options_list ')' ';' - { driver.simul(); } - ; - -simul_options_list : simul_options_list COMMA simul_options - | simul_options - ; - -simul_options : perfect_foresight_setup_options - | perfect_foresight_solver_options - ; - -external_function : EXTERNAL_FUNCTION '(' external_function_options_list ')' ';' - { driver.external_function(); } - ; - -external_function_options_list : external_function_options_list COMMA external_function_options - | external_function_options - ; - -external_function_options : o_ext_func_name - | o_ext_func_nargs - | o_first_deriv_provided - | o_second_deriv_provided - ; - -stoch_simul : STOCH_SIMUL ';' - { driver.stoch_simul(); } - | STOCH_SIMUL '(' stoch_simul_options_list ')' ';' - { driver.stoch_simul(); } - | STOCH_SIMUL symbol_list ';' - { driver.stoch_simul(); } - | STOCH_SIMUL '(' stoch_simul_options_list ')' symbol_list ';' - { driver.stoch_simul(); } - ; - -stoch_simul_options_list : stoch_simul_options_list COMMA stoch_simul_options - | stoch_simul_options - ; - -stoch_simul_primary_options : o_dr_algo - | o_solve_algo - | o_simul_algo - | o_linear - | o_order - | o_replic - | o_drop - | o_ar - | o_nocorr - | o_contemporaneous_correlation - | o_nofunctions - | o_nomoments - | o_nograph - | o_nodisplay - | o_graph_format - | o_irf - | o_irf_shocks - | o_relative_irf - | o_analytical_girf - | o_irf_in_percent - | o_emas_girf - | o_emas_drop - | o_emas_tolf - | o_emas_max_iter - | o_stderr_multiples - | o_diagonal_only - | o_hp_filter - | o_hp_ngrid - | o_periods - | o_simul - | o_simul_seed - | o_simul_replic - | o_qz_criterium - | o_qz_zero_threshold - | o_print - | o_noprint - | o_aim_solver - | o_partial_information - | o_conditional_variance_decomposition - | o_k_order_solver - | o_pruning - | o_sylvester - | o_sylvester_fixed_point_tol - | o_dr - | o_dr_cycle_reduction_tol - | o_dr_logarithmic_reduction_tol - | o_dr_logarithmic_reduction_maxiter - | o_irf_plot_threshold - | o_dr_display_tol - | o_tex - ; - -stoch_simul_options : stoch_simul_primary_options - | o_loglinear - | o_nodecomposition - | o_spectral_density - | o_bandpass_filter - | o_one_sided_hp_filter - ; - -symbol_list : symbol_list symbol - { driver.add_in_symbol_list($2); } - | symbol_list COMMA symbol - { driver.add_in_symbol_list($3); } - | symbol - { driver.add_in_symbol_list($1); } - ; - -symbol_list_ext : symbol_list - | ':' - { - string *colon = new string(":"); - driver.add_in_symbol_list(colon); - } - ; - -signed_integer : PLUS INT_NUMBER - { $$ = $2; } - | MINUS INT_NUMBER - { $2->insert(0, "-"); $$ = $2; } - | INT_NUMBER - ; - -non_negative_number : INT_NUMBER - | FLOAT_NUMBER - ; - -signed_number : PLUS non_negative_number - { $$ = $2; } - | MINUS non_negative_number - { $2->insert(0, "-"); $$ = $2; } - | non_negative_number - ; - -signed_inf : PLUS INF_CONSTANT - { $$ = new string ("Inf"); } - | MINUS INF_CONSTANT - { $$ = new string ("-Inf"); } - | INF_CONSTANT - { $$ = new string ("Inf"); } - ; - -signed_number_w_inf : signed_inf - | signed_number - ; - -estimated_params : ESTIMATED_PARAMS ';' estimated_list END ';' { driver.estimated_params(); }; - -estimated_list : estimated_list estimated_elem - { driver.add_estimated_params_element(); } - | estimated_elem - { driver.add_estimated_params_element(); } - ; - -estimated_elem : estimated_elem1 COMMA estimated_elem2 ';' - | estimated_elem1 ';' - -estimated_elem1 : STDERR symbol - { - driver.estim_params.type = 1; - driver.estim_params.name = *$2; - delete $2; - } - | symbol - { - driver.estim_params.type = 2; - driver.estim_params.name = *$1; - delete $1; - } - | CORR symbol COMMA symbol - { - driver.estim_params.type = 3; - driver.estim_params.name = *$2; - driver.estim_params.name2 = *$4; - delete $2; - delete $4; - } - | DSGE_PRIOR_WEIGHT - { - driver.estim_params.type = 2; - driver.estim_params.name = "dsge_prior_weight"; - } - ; - -estimated_elem2 : prior_pdf COMMA estimated_elem3 - { - driver.estim_params.prior = $1; - } - | expression_or_empty COMMA prior_pdf COMMA estimated_elem3 - { - driver.estim_params.init_val = $1; - driver.estim_params.prior = $3; - } - | expression_or_empty COMMA expression_or_empty COMMA expression_or_empty COMMA prior_pdf COMMA estimated_elem3 - { - driver.estim_params.init_val = $1; - driver.estim_params.low_bound = $3; - driver.estim_params.up_bound = $5; - driver.estim_params.prior = $7; - } - | expression - { - driver.estim_params.init_val = $1; - } - | expression_or_empty COMMA expression_or_empty COMMA expression_or_empty - { - driver.estim_params.init_val = $1; - driver.estim_params.low_bound = $3; - driver.estim_params.up_bound = $5; - } - ; - -estimated_elem3 : expression_or_empty COMMA expression_or_empty - { - driver.estim_params.mean = $1; - driver.estim_params.std = $3; - } - | expression_or_empty COMMA expression_or_empty COMMA expression_or_empty - { - driver.estim_params.mean = $1; - driver.estim_params.std = $3; - driver.estim_params.p3 = $5; - } - | expression_or_empty COMMA expression_or_empty COMMA expression_or_empty COMMA expression_or_empty - { - driver.estim_params.mean = $1; - driver.estim_params.std = $3; - driver.estim_params.p3 = $5; - driver.estim_params.p4 = $7; - } - | expression_or_empty COMMA expression_or_empty COMMA expression_or_empty COMMA expression_or_empty COMMA expression - { - driver.estim_params.mean = $1; - driver.estim_params.std = $3; - driver.estim_params.p3 = $5; - driver.estim_params.p4 = $7; - driver.estim_params.jscale = $9; - } - ; - -estimated_params_init : ESTIMATED_PARAMS_INIT ';' estimated_init_list END ';' - { driver.estimated_params_init(); } - | ESTIMATED_PARAMS_INIT '(' USE_CALIBRATION ')' ';' END ';' - { driver.estimated_params_init(true); } - | ESTIMATED_PARAMS_INIT '(' USE_CALIBRATION ')' ';' estimated_init_list END ';' - { driver.estimated_params_init(true); } - ; - -estimated_init_list : estimated_init_list estimated_init_elem - { driver.add_estimated_params_element(); } - | estimated_init_elem - { driver.add_estimated_params_element(); } - ; - -estimated_init_elem : STDERR symbol COMMA expression ';' - { - driver.estim_params.type = 1; - driver.estim_params.name = *$2; - driver.estim_params.init_val = $4; - delete $2; - } - | CORR symbol COMMA symbol COMMA expression ';' - { - driver.estim_params.type = 3; - driver.estim_params.name = *$2; - driver.estim_params.name2 = *$4; - driver.estim_params.init_val = $6; - delete $2; - delete $4; - } - | symbol COMMA expression ';' - { - driver.estim_params.type = 2; - driver.estim_params.name = *$1; - driver.estim_params.init_val = $3; - delete $1; - } - ; - -estimated_params_bounds : ESTIMATED_PARAMS_BOUNDS ';' estimated_bounds_list END ';' - { driver.estimated_params_bounds(); }; - -estimated_bounds_list : estimated_bounds_list estimated_bounds_elem - { driver.add_estimated_params_element(); } - | estimated_bounds_elem - { driver.add_estimated_params_element(); } - ; - -estimated_bounds_elem : STDERR symbol COMMA expression COMMA expression ';' - { - driver.estim_params.type = 1; - driver.estim_params.name = *$2; - driver.estim_params.low_bound = $4; - driver.estim_params.up_bound = $6; - delete $2; - } - | CORR symbol COMMA symbol COMMA expression COMMA expression ';' - { - driver.estim_params.type = 3; - driver.estim_params.name = *$2; - driver.estim_params.name2 = *$4; - driver.estim_params.low_bound = $6; - driver.estim_params.up_bound = $8; - delete $2; - delete $4; - } - | symbol COMMA expression COMMA expression ';' - { - driver.estim_params.type = 2; - driver.estim_params.name = *$1; - driver.estim_params.low_bound = $3; - driver.estim_params.up_bound = $5; - delete $1; - } - ; - -osr_params_bounds : OSR_PARAMS_BOUNDS ';' osr_bounds_list END ';' - { driver.osr_params_bounds(); }; - -osr_bounds_list : osr_bounds_list osr_bounds_elem - { driver.add_osr_params_element(); } - | osr_bounds_elem - { driver.add_osr_params_element(); } - ; - -osr_bounds_elem : symbol COMMA expression COMMA expression ';' - { - driver.osr_params.name = *$1; - driver.osr_params.low_bound = $3; - driver.osr_params.up_bound = $5; - delete $1; - } - ; - -prior_distribution : BETA - { $$ = eBeta; } - | GAMMA - { $$ = eGamma; } - | NORMAL - { $$ = eNormal; } - | INV_GAMMA - { $$ = eInvGamma; } - | INV_GAMMA1 - { $$ = eInvGamma1; } - | UNIFORM - { $$ = eUniform; } - | INV_GAMMA2 - { $$ = eInvGamma2; } - | DIRICHLET - { $$ = eDirichlet; } - | WEIBULL - { $$ = eWeibull; } - ; - -prior_pdf : BETA_PDF - { $$ = eBeta; } - | GAMMA_PDF - { $$ = eGamma; } - | NORMAL_PDF - { $$ = eNormal; } - | INV_GAMMA_PDF - { $$ = eInvGamma; } - | INV_GAMMA1_PDF - { $$ = eInvGamma1; } - | UNIFORM_PDF - { $$ = eUniform; } - | INV_GAMMA2_PDF - { $$ = eInvGamma2; } - | WEIBULL_PDF - { $$ = eWeibull; } - ; - -date_str : DATES { $$ = $1; } - -date_expr : date_str - { $$ = $1; } - | date_expr PLUS INT_NUMBER - { $$ = $1; $$->append("+").append(*$3); } - ; - -set_time : SET_TIME '(' date_expr ')' ';' - { driver.set_time($3); } - ; - -data : DATA '(' data_options_list ')'';' - { driver.estimation_data(); } - ; - -data_options_list : data_options_list COMMA data_options - | data_options - ; - -data_options : o_file - | o_series - | o_data_first_obs - | o_data_last_obs - | o_data_nobs - | o_xls_sheet - | o_xls_range - ; - -subsamples : subsamples_eq_opt '(' subsamples_name_list ')' ';' - { driver.set_subsamples($1->at(0), $1->at(1)); } - ; - -subsamples_eq : subsamples_eq_opt EQUAL subsamples_eq_opt ';' - { - driver.copy_subsamples($1->at(0), $1->at(1), $3->at(0), $3->at(1)); - delete $1; - delete $3; - } - ; - -subsamples_eq_opt : symbol '.' SUBSAMPLES - { - $$ = new vector(); - $$->push_back($1); - $$->push_back(new string ("")); - } - | STD '(' symbol ')' '.'SUBSAMPLES - { - $$ = new vector(); - $$->push_back($3); - $$->push_back(new string ("")); - } - | CORR '(' symbol COMMA symbol ')' '.' SUBSAMPLES - { - $$ = new vector(); - $$->push_back($3); - $$->push_back($5); - } - ; - -subsamples_name_list : subsamples_name_list COMMA o_subsample_name - | o_subsample_name - ; - -prior : symbol '.' PRIOR { driver.set_prior_variance(); driver.prior_shape = eNoShape; } '(' prior_options_list ')' ';' - { driver.set_prior($1, new string ("")); } - | symbol '.' symbol '.' PRIOR { driver.set_prior_variance(); driver.prior_shape = eNoShape; } '(' prior_options_list ')' ';' - { driver.set_prior($1, $3); } - | SYMBOL_VEC '.' PRIOR { driver.set_prior_variance(); driver.prior_shape = eNoShape; } '(' joint_prior_options_list ')' ';' - { driver.set_joint_prior($1); } - | STD '(' symbol ')' '.' PRIOR { driver.set_prior_variance(); driver.prior_shape = eNoShape; } '(' prior_options_list ')' ';' - { driver.set_std_prior($3, new string ("")); } - | STD '(' symbol ')' '.' symbol '.' PRIOR { driver.set_prior_variance(); driver.prior_shape = eNoShape; } '(' prior_options_list ')' ';' - { driver.set_std_prior($3, $6); } - | CORR '(' symbol COMMA symbol ')' '.' PRIOR { driver.set_prior_variance(); driver.prior_shape = eNoShape; } '(' prior_options_list ')' ';' - { driver.set_corr_prior($3, $5, new string ("")); } - | CORR '(' symbol COMMA symbol ')' '.' symbol '.' PRIOR { driver.set_prior_variance(); driver.prior_shape = eNoShape; } '(' prior_options_list ')' ';' - { driver.set_corr_prior($3, $5, $8); } - ; - -prior_options_list : prior_options_list COMMA prior_options - | prior_options - ; - -prior_options : o_shift - | o_mean - | o_median - | o_stdev - | o_truncate - | o_variance - | o_mode - | o_interval - | o_shape - | o_domain - ; - -joint_prior_options_list : joint_prior_options_list COMMA joint_prior_options - | joint_prior_options - ; - -joint_prior_options : o_shift - | o_mean_vec - | o_median - | o_stdev - | o_truncate - | o_variance_mat - | o_mode - | o_interval - | o_shape - | o_domain - ; - -prior_eq : prior_eq_opt EQUAL prior_eq_opt ';' - { - driver.copy_prior($1->at(0), $1->at(1), $1->at(2), $1->at(3), - $3->at(0), $3->at(1), $3->at(2), $3->at(3)); - delete $1; - delete $3; - } - ; - -prior_eq_opt : symbol '.' PRIOR - { - $$ = new vector(); - $$->push_back(new string ("par")); - $$->push_back($1); - $$->push_back(new string ("")); - $$->push_back(new string ("")); - } - | symbol '.' symbol '.' PRIOR - { - $$ = new vector(); - $$->push_back(new string ("par")); - $$->push_back($1); - $$->push_back(new string ("")); - $$->push_back($3); - } - | STD '(' symbol ')' '.' PRIOR - { - $$ = new vector(); - $$->push_back(new string ("std")); - $$->push_back($3); - $$->push_back(new string ("")); - $$->push_back(new string ("")); - } - | STD '(' symbol ')' '.' symbol '.' PRIOR - { - $$ = new vector(); - $$->push_back(new string ("std")); - $$->push_back($3); - $$->push_back(new string ("")); - $$->push_back($6); - } - | CORR '(' symbol COMMA symbol ')' '.' PRIOR - { - $$ = new vector(); - $$->push_back(new string ("corr")); - $$->push_back($3); - $$->push_back($5); - $$->push_back(new string ("")); - } - | CORR '(' symbol COMMA symbol ')' '.' symbol '.' PRIOR - { - $$ = new vector(); - $$->push_back(new string ("corr")); - $$->push_back($3); - $$->push_back($5); - $$->push_back($8); - } - ; - -options : symbol '.' OPTIONS '(' options_options_list ')' ';' - { driver.set_options($1, new string ("")); } - | symbol '.' symbol '.' OPTIONS '(' options_options_list ')' ';' - { driver.set_options($1, $3); } - | STD '(' symbol ')' '.' OPTIONS '(' options_options_list ')' ';' - { driver.set_std_options($3, new string ("")); } - | STD '(' symbol ')' '.' symbol '.' OPTIONS '(' options_options_list ')' ';' - { driver.set_std_options($3, $6); } - | CORR '(' symbol COMMA symbol ')' '.' OPTIONS '(' options_options_list ')' ';' - { driver.set_corr_options($3, $5, new string ("")); } - | CORR '(' symbol COMMA symbol ')' '.' symbol '.' OPTIONS '(' options_options_list ')' ';' - { driver.set_corr_options($3, $5, $8); } - ; - -options_options_list : options_options_list COMMA options_options - | options_options - ; - -options_options : o_jscale - | o_init - | o_bounds - ; - -options_eq : options_eq_opt EQUAL options_eq_opt ';' - { - driver.copy_options($1->at(0), $1->at(1), $1->at(2), $1->at(3), - $3->at(0), $3->at(1), $3->at(2), $3->at(3)); - delete $1; - delete $3; - } - ; - -options_eq_opt : symbol '.' OPTIONS - { - $$ = new vector(); - $$->push_back(new string ("par")); - $$->push_back($1); - $$->push_back(new string ("")); - $$->push_back(new string ("")); - } - | symbol '.' symbol '.' OPTIONS - { - $$ = new vector(); - $$->push_back(new string ("par")); - $$->push_back($1); - $$->push_back(new string ("")); - $$->push_back($3); - } - | STD '(' symbol ')' '.' OPTIONS - { - $$ = new vector(); - $$->push_back(new string ("std")); - $$->push_back($3); - $$->push_back(new string ("")); - $$->push_back(new string ("")); - } - | STD '(' symbol ')' '.' symbol '.' OPTIONS - { - $$ = new vector(); - $$->push_back(new string ("std")); - $$->push_back($3); - $$->push_back(new string ("")); - $$->push_back($6); - } - | CORR '(' symbol COMMA symbol ')' '.' OPTIONS - { - $$ = new vector(); - $$->push_back(new string ("corr")); - $$->push_back($3); - $$->push_back($5); - $$->push_back(new string ("")); - } - | CORR '(' symbol COMMA symbol ')' '.' symbol '.' OPTIONS - { - $$ = new vector(); - $$->push_back(new string ("corr")); - $$->push_back($3); - $$->push_back($5); - $$->push_back($8); - } - ; - -estimation : ESTIMATION ';' - { driver.run_estimation(); } - | ESTIMATION '(' estimation_options_list ')' ';' - { driver.run_estimation(); } - | ESTIMATION symbol_list ';' - { driver.run_estimation(); } - | ESTIMATION '(' estimation_options_list ')' symbol_list ';' - { driver.run_estimation(); } - ; - -estimation_options_list : estimation_options_list COMMA estimation_options - | estimation_options - ; - -estimation_options : o_datafile - | o_nobs - | o_est_first_obs - | o_prefilter - | o_presample - | o_lik_algo - | o_lik_init - | o_nograph - | o_posterior_nograph - | o_nodisplay - | o_graph_format - | o_forecasts_conf_sig - | o_mh_conf_sig - | o_mh_replic - | o_mh_drop - | o_mh_jscale - | o_optim - | o_mh_init_scale - | o_mode_file - | o_mode_compute - | o_mode_check - | o_mode_check_neighbourhood_size - | o_mode_check_symmetric_plots - | o_mode_check_number_of_points - | o_prior_trunc - | o_mh_mode - | o_mh_nblocks - | o_load_mh_file - | o_load_results_after_load_mh - | o_loglinear - | o_logdata - | o_nodecomposition - | o_nodiagnostic - | o_bayesian_irf - | o_relative_irf - | o_dsge_var - | o_dsge_varlag - | o_irf - | o_tex - | o_forecast - | o_smoother - | o_moments_varendo - | o_contemporaneous_correlation - | o_filtered_vars - | o_fast_kalman_filter - | o_kalman_algo - | o_kalman_tol - | o_diffuse_kalman_tol - | o_xls_sheet - | o_xls_range - | o_filter_step_ahead - | o_solve_algo - | o_constant - | o_noconstant - | o_mh_recover - | o_diffuse_filter - | o_plot_priors - | o_order - | o_aim_solver - | o_partial_information - | o_filter_covariance - | o_filter_decomposition - | o_smoothed_state_uncertainty - | o_selected_variables_only - | o_conditional_variance_decomposition - | o_cova_compute - | o_irf_shocks - | o_sub_draws - | o_sylvester - | o_sylvester_fixed_point_tol - | o_lyapunov - | o_lyapunov_fixed_point_tol - | o_lyapunov_doubling_tol - | o_dr - | o_dr_cycle_reduction_tol - | o_dr_logarithmic_reduction_tol - | o_dr_logarithmic_reduction_maxiter - | o_analytic_derivation - | o_ar - | o_endogenous_prior - | o_use_univariate_filters_if_singularity_is_detected - | o_qz_zero_threshold - | o_taper_steps - | o_geweke_interval - | o_raftery_lewis_qrs - | o_raftery_lewis_diagnostics - | o_mcmc_jumping_covariance - | o_irf_plot_threshold - | o_posterior_max_subsample_draws - | o_consider_all_endogenous - | o_consider_only_observed - | o_number_of_particles - | o_resampling - | o_resampling_threshold - | o_resampling_method - | o_filter_algorithm - | o_nonlinear_filter_initialization - | o_cpf_weights - | o_proposal_approximation - | o_distribution_approximation - | o_dirname - | o_huge_number - | o_silent_optimizer - | o_proposal_distribution - | o_no_posterior_kernel_density - | o_posterior_sampling_method - | o_posterior_sampler_options - | o_keep_kalman_algo_if_singularity_is_detected - | o_use_penalized_objective_for_hessian - | o_rescale_prediction_error_covariance - | o_analytical_girf - | o_irf_in_percent - | o_emas_girf - | o_emas_drop - | o_emas_tolf - | o_emas_max_iter - | o_stderr_multiples - | o_diagonal_only - ; - -list_optim_option : QUOTED_STRING COMMA QUOTED_STRING - { driver.optim_options_string($1, $3); } - | QUOTED_STRING COMMA signed_number - { driver.optim_options_num($1, $3); } - ; - -optim_options : list_optim_option - | optim_options COMMA list_optim_option; - ; - -list_sub_sampling_option : QUOTED_STRING COMMA QUOTED_STRING - { - $1->insert(0, "''"); - $1->append("'', ''"); - $1->append(*$3); - $1->append("''"); - $$ = $1; - } - | QUOTED_STRING COMMA signed_number - { - $1->insert(0, "''"); - $1->append("'',"); - $1->append(*$3); - $$ = $1; - } - ; - -sub_sampling_options : list_sub_sampling_option - { $$ = $1; } - | sub_sampling_options COMMA list_sub_sampling_option - { - $1->append(","); - $1->append(*$3); - $$ = $1; - } - ; - -list_sampling_option : QUOTED_STRING COMMA QUOTED_STRING - { driver.sampling_options_string($1, $3); } - | QUOTED_STRING COMMA signed_number - { driver.sampling_options_num($1, $3); } - | QUOTED_STRING COMMA '(' sub_sampling_options ')' - { - $4->insert(0,"("); - $4->append(")"); - driver.sampling_options_string($1, $4); - } - ; - -sampling_options : list_sampling_option - | sampling_options COMMA list_sampling_option; - ; - -varobs : VAROBS { driver.check_varobs(); } varobs_list ';'; - -varobs_list : varobs_list symbol - { driver.add_varobs($2); } - | varobs_list COMMA symbol - { driver.add_varobs($3); } - | symbol - { driver.add_varobs($1); } - ; - -observation_trends : OBSERVATION_TRENDS ';' trend_list END ';' { driver.set_trends(); }; - -trend_list : trend_list trend_element - | trend_element - ; - -trend_element : symbol '(' expression ')' ';' { driver.set_trend_element($1, $3); }; - -unit_root_vars : UNIT_ROOT_VARS symbol_list ';' { driver.set_unit_root_vars(); }; - -optim_weights : OPTIM_WEIGHTS ';' optim_weights_list END ';' { driver.optim_weights(); }; - -optim_weights_list : optim_weights_list symbol expression ';' - { driver.set_optim_weights($2, $3); } - | optim_weights_list symbol COMMA symbol expression ';' - { driver.set_optim_weights($2, $4, $5); } - | symbol expression ';' - { driver.set_optim_weights($1, $2); } - | symbol COMMA symbol expression ';' - { driver.set_optim_weights($1, $3, $4); } - ; - -osr_params : OSR_PARAMS symbol_list ';' { driver.set_osr_params(); }; - - -osr_options_list : osr_options_list COMMA osr_options - | osr_options - ; - -osr_options : stoch_simul_primary_options - | o_osr_maxit - | o_osr_tolf - | o_opt_algo - | o_optim - | o_huge_number - | o_silent_optimizer - ; - -osr : OSR ';' - { driver.run_osr(); } - | OSR '(' osr_options_list ')' ';' - { driver.run_osr(); } - | OSR symbol_list ';' - { driver.run_osr(); } - | OSR '(' osr_options_list ')' symbol_list ';' - {driver.run_osr(); } - ; - -dynatype : DYNATYPE '(' filename ')' ';' - { driver.run_dynatype($3); } - | DYNATYPE '(' filename ')' symbol_list ';' - { driver.run_dynatype($3); } - ; - -dynasave : DYNASAVE '(' filename ')' ';' - { driver.run_dynasave($3); } - | DYNASAVE '(' filename ')' symbol_list ';' - { driver.run_dynasave($3); } - ; - -load_params_and_steady_state : LOAD_PARAMS_AND_STEADY_STATE '(' filename ')' ';' - { driver.run_load_params_and_steady_state($3); } - ; - -save_params_and_steady_state : SAVE_PARAMS_AND_STEADY_STATE '(' filename ')' ';' - { driver.run_save_params_and_steady_state($3); } - ; - -identification : IDENTIFICATION ';' - { driver.run_identification(); } - | IDENTIFICATION '(' identification_options_list ')' ';' - { driver.run_identification(); } - ; - -identification_options_list : identification_option COMMA identification_options_list - | identification_option - ; - -identification_option : o_ar - | o_useautocorr - | o_load_ident_files - | o_prior_mc - | o_advanced - | o_max_dim_cova_group - | o_gsa_prior_range - | o_periods - | o_replic - | o_gsa_sample_file - | o_parameter_set - | o_lik_init - | o_kalman_algo - | o_nograph - | o_nodisplay - | o_graph_format - | o_diffuse_filter - | o_prior_trunc - | o_analytic_derivation - | o_analytic_derivation_mode - ; - -model_comparison : MODEL_COMPARISON mc_filename_list ';' - { driver.run_model_comparison(); } - | MODEL_COMPARISON '(' o_marginal_density ')' mc_filename_list ';' - { driver.run_model_comparison(); } - ; - -filename : symbol - | QUOTED_STRING - ; - -parallel_local_filename_list : filename - { driver.add_parallel_local_file($1); } - | parallel_local_filename_list COMMA filename - { driver.add_parallel_local_file($3); } - ; - -mc_filename_list : filename - { driver.add_mc_filename($1); } - | filename '(' non_negative_number ')' - { driver.add_mc_filename($1, $3); } - | mc_filename_list filename - { driver.add_mc_filename($2); } - | mc_filename_list filename '(' non_negative_number ')' - { driver.add_mc_filename($2, $4); } - | mc_filename_list COMMA filename - { driver.add_mc_filename($3); } - | mc_filename_list COMMA filename '(' non_negative_number ')' - { driver.add_mc_filename($3, $5); } - ; - -planner_objective : PLANNER_OBJECTIVE { driver.begin_planner_objective(); } - hand_side { driver.end_planner_objective($3); } ';'; - -ramsey_model : RAMSEY_MODEL ';' - { driver.ramsey_model(); } - | RAMSEY_MODEL '(' ramsey_model_options_list ')' ';' - { driver.ramsey_model(); } - ; - -ramsey_policy : RAMSEY_POLICY ';' - { driver.ramsey_policy(); } - | RAMSEY_POLICY '(' ramsey_policy_options_list ')' ';' - { driver.ramsey_policy(); } - | RAMSEY_POLICY symbol_list ';' - { driver.ramsey_policy(); } - | RAMSEY_POLICY '(' ramsey_policy_options_list ')' ramsey_policy_list ';' - { driver.ramsey_policy(); } - ; - -ramsey_policy_list : ramsey_policy_list ramsey_policy_element - | ramsey_policy_element - ; - -ramsey_policy_element : symbol { driver.add_to_ramsey_policy_list($1); } - ; - -ramsey_constraints : RAMSEY_CONSTRAINTS ';' ramsey_constraints_list END ';' - { driver.add_ramsey_constraints_statement(); } - ; - -ramsey_constraints_list : ramsey_constraints_list ramsey_constraint - | ramsey_constraint - ; - -ramsey_constraint : NAME LESS expression ';' - { driver.ramsey_constraint_add_less($1,$3); } - | NAME GREATER expression ';' - { driver.ramsey_constraint_add_greater($1,$3); } - | NAME LESS_EQUAL expression ';' - { driver.ramsey_constraint_add_less_equal($1,$3); } - | NAME GREATER_EQUAL expression ';' - { driver.ramsey_constraint_add_greater_equal($1,$3); } - ; - -discretionary_policy : DISCRETIONARY_POLICY ';' - { driver.discretionary_policy(); } - | DISCRETIONARY_POLICY '(' discretionary_policy_options_list ')' ';' - { driver.discretionary_policy(); } - | DISCRETIONARY_POLICY symbol_list ';' - { driver.discretionary_policy(); } - | DISCRETIONARY_POLICY '(' discretionary_policy_options_list ')' symbol_list ';' - { driver.discretionary_policy(); } - ; - -discretionary_policy_options_list : discretionary_policy_options_list COMMA discretionary_policy_options - | discretionary_policy_options - ; - -discretionary_policy_options : ramsey_policy_options - | o_discretionary_tol; - | o_dp_maxit; - ; - -ramsey_model_options_list : ramsey_model_options_list COMMA ramsey_model_options - | ramsey_model_options - ; - -ramsey_model_options : o_planner_discount - | o_instruments - ; - -ramsey_policy_options_list : ramsey_policy_options_list COMMA ramsey_policy_options - | ramsey_policy_options - ; - -ramsey_policy_options : stoch_simul_primary_options - | o_planner_discount - | o_instruments - ; - -write_latex_dynamic_model : WRITE_LATEX_DYNAMIC_MODEL ';' - { driver.write_latex_dynamic_model(false); } - | WRITE_LATEX_DYNAMIC_MODEL '(' WRITE_EQUATION_TAGS ')' ';' - { driver.write_latex_dynamic_model(true); } - ; - -write_latex_static_model : WRITE_LATEX_STATIC_MODEL ';' - { driver.write_latex_static_model(false); } - | WRITE_LATEX_STATIC_MODEL '(' WRITE_EQUATION_TAGS ')' ';' - { driver.write_latex_static_model(true); } - ; - -write_latex_original_model : WRITE_LATEX_ORIGINAL_MODEL ';' - { driver.write_latex_original_model(false); } - | WRITE_LATEX_ORIGINAL_MODEL '(' WRITE_EQUATION_TAGS ')' ';' - { driver.write_latex_original_model(true); } - ; - -write_latex_steady_state_model : WRITE_LATEX_STEADY_STATE_MODEL ';' - { driver.write_latex_steady_state_model(); } - ; - -shock_decomposition : SHOCK_DECOMPOSITION ';' - {driver.shock_decomposition(); } - | SHOCK_DECOMPOSITION '(' shock_decomposition_options_list ')' ';' - { driver.shock_decomposition(); } - | SHOCK_DECOMPOSITION symbol_list ';' - { driver.shock_decomposition(); } - | SHOCK_DECOMPOSITION '(' shock_decomposition_options_list ')' symbol_list ';' - { driver.shock_decomposition(); } - ; - -realtime_shock_decomposition : REALTIME_SHOCK_DECOMPOSITION ';' - {driver.realtime_shock_decomposition(); } - | REALTIME_SHOCK_DECOMPOSITION '(' realtime_shock_decomposition_options_list ')' ';' - { driver.realtime_shock_decomposition(); } - | REALTIME_SHOCK_DECOMPOSITION symbol_list ';' - { driver.realtime_shock_decomposition(); } - | REALTIME_SHOCK_DECOMPOSITION '(' realtime_shock_decomposition_options_list ')' symbol_list ';' - { driver.realtime_shock_decomposition(); } - ; - -plot_shock_decomposition : PLOT_SHOCK_DECOMPOSITION ';' - {driver.plot_shock_decomposition(); } - | PLOT_SHOCK_DECOMPOSITION '(' plot_shock_decomposition_options_list ')' ';' - { driver.plot_shock_decomposition(); } - | PLOT_SHOCK_DECOMPOSITION symbol_list ';' - { driver.plot_shock_decomposition(); } - | PLOT_SHOCK_DECOMPOSITION '(' plot_shock_decomposition_options_list ')' symbol_list ';' - { driver.plot_shock_decomposition(); } - ; - -initial_condition_decomposition : INITIAL_CONDITION_DECOMPOSITION ';' - {driver.initial_condition_decomposition(); } - | INITIAL_CONDITION_DECOMPOSITION '(' initial_condition_decomposition_options_list ')' ';' - { driver.initial_condition_decomposition(); } - | INITIAL_CONDITION_DECOMPOSITION symbol_list ';' - { driver.initial_condition_decomposition(); } - | INITIAL_CONDITION_DECOMPOSITION '(' initial_condition_decomposition_options_list ')' symbol_list ';' - { driver.initial_condition_decomposition(); } - ; - -bvar_prior_option : o_bvar_prior_tau - | o_bvar_prior_decay - | o_bvar_prior_lambda - | o_bvar_prior_mu - | o_bvar_prior_omega - | o_bvar_prior_flat - | o_bvar_prior_train - ; - -bvar_common_option : bvar_prior_option - | o_datafile - | o_xls_sheet - | o_xls_range - | o_first_obs - | o_presample - | o_nobs - | o_prefilter - | o_constant - | o_noconstant - ; - -bvar_density_options_list : bvar_common_option COMMA bvar_density_options_list - | bvar_common_option - ; - -bvar_density : BVAR_DENSITY INT_NUMBER ';' - { driver.bvar_density($2); } - | BVAR_DENSITY '(' bvar_density_options_list ')' INT_NUMBER ';' - { driver.bvar_density($5); } - ; - -bvar_forecast_option : bvar_common_option - | o_forecast - | o_bvar_conf_sig - | o_bvar_replic - ; - -bvar_forecast_options_list : bvar_forecast_option COMMA bvar_forecast_options_list - | bvar_forecast_option - ; - -bvar_forecast : BVAR_FORECAST INT_NUMBER ';' - { driver.bvar_forecast($2); } - | BVAR_FORECAST '(' bvar_forecast_options_list ')' INT_NUMBER ';' - { driver.bvar_forecast($5); } - ; - -sbvar_option : o_datafile - | o_freq - | o_initial_year - | o_initial_subperiod - | o_final_year - | o_final_subperiod - | o_data - | o_vlist - | o_vlistlog - | o_vlistper - | o_restriction_fname - | o_nlags - | o_cross_restrictions - | o_contemp_reduced_form - | o_real_pseudo_forecast - | o_no_bayesian_prior - | o_dummy_obs - | o_nstates - | o_indxscalesstates - | o_alpha - | o_beta - | o_gsig2_lmdm - | o_q_diag - | o_flat_prior - | o_ncsk - | o_nstd - | o_ninv - | o_indxparr - | o_indxovr - | o_aband - | o_indxap - | o_apband - | o_indximf - | o_indxfore - | o_foreband - | o_indxgforhat - | o_indxgimfhat - | o_indxestima - | o_indxgdls - | o_eq_ms - | o_cms - | o_ncms - | o_eq_cms - | o_tlindx - | o_tlnumber - | o_cnum - | o_forecast - | o_coefficients_prior_hyperparameters; - ; - -sbvar_options_list : sbvar_option COMMA sbvar_options_list - | sbvar_option - ; - -sbvar : SBVAR ';' - { driver.sbvar(); } - | SBVAR '(' sbvar_options_list ')' ';' - { driver.sbvar(); } - ; - -ms_variance_decomposition_option : o_output_file_tag - | o_file_tag - | o_simulation_file_tag - | o_filtered_probabilities - | o_no_error_bands - | o_error_band_percentiles - | o_shock_draws - | o_shocks_per_parameter - | o_thinning_factor - | o_free_parameters - | o_regime - | o_regimes - | o_parameter_uncertainty - | o_horizon - ; - -ms_variance_decomposition_options_list : ms_variance_decomposition_option COMMA ms_variance_decomposition_options_list - | ms_variance_decomposition_option - ; - -ms_variance_decomposition : MS_VARIANCE_DECOMPOSITION ';' - { driver.ms_variance_decomposition(); } - | MS_VARIANCE_DECOMPOSITION '(' ms_variance_decomposition_options_list ')' ';' - { driver.ms_variance_decomposition(); } - ; - -ms_forecast_option : o_output_file_tag - | o_file_tag - | o_simulation_file_tag - | o_data_obs_nbr - | o_error_band_percentiles - | o_shock_draws - | o_shocks_per_parameter - | o_thinning_factor - | o_free_parameters - | o_median - | o_regime - | o_regimes - | o_parameter_uncertainty - | o_horizon - ; - -ms_forecast_options_list : ms_forecast_option COMMA ms_forecast_options_list - | ms_forecast_option - ; - -ms_forecast : MS_FORECAST ';' - { driver.ms_forecast(); } - | MS_FORECAST '(' ms_forecast_options_list ')' ';' - { driver.ms_forecast(); } - ; - -ms_irf_option : o_output_file_tag - | o_file_tag - | o_simulation_file_tag - | o_parameter_uncertainty - | o_horizon - | o_filtered_probabilities - | o_error_band_percentiles - | o_shock_draws - | o_shocks_per_parameter - | o_thinning_factor - | o_free_parameters - | o_median - | o_regime - | o_regimes - ; - -ms_irf_options_list : ms_irf_option COMMA ms_irf_options_list - | ms_irf_option - ; - -ms_irf : MS_IRF ';' - { driver.ms_irf(); } - | MS_IRF '(' ms_irf_options_list ')' ';' - { driver.ms_irf(); } - | MS_IRF symbol_list ';' - { driver.ms_irf(); } - | MS_IRF '(' ms_irf_options_list ')' symbol_list ';' - { driver.ms_irf(); } - ; - -ms_compute_probabilities_option : o_output_file_tag - | o_file_tag - | o_filtered_probabilities - | o_real_time_smoothed - ; - -ms_compute_probabilities_options_list : ms_compute_probabilities_option COMMA ms_compute_probabilities_options_list - | ms_compute_probabilities_option - ; - -ms_compute_probabilities : MS_COMPUTE_PROBABILITIES ';' - { driver.ms_compute_probabilities(); } - | MS_COMPUTE_PROBABILITIES '(' ms_compute_probabilities_options_list ')' ';' - { driver.ms_compute_probabilities(); } - ; - -ms_compute_mdd_option : o_output_file_tag - | o_file_tag - | o_simulation_file_tag - | o_proposal_type - | o_proposal_lower_bound - | o_proposal_upper_bound - | o_proposal_draws - | o_use_mean_center - ; - -ms_compute_mdd_options_list : ms_compute_mdd_option COMMA ms_compute_mdd_options_list - | ms_compute_mdd_option - ; - -ms_compute_mdd : MS_COMPUTE_MDD ';' - { driver.ms_compute_mdd(); } - | MS_COMPUTE_MDD '(' ms_compute_mdd_options_list ')' ';' - { driver.ms_compute_mdd(); } - ; - -ms_simulation_option : o_output_file_tag - | o_file_tag - | o_ms_mh_replic - | o_ms_drop - | o_thinning_factor - | o_adaptive_mh_draws - | o_save_draws - ; - -ms_simulation_options_list : ms_simulation_option COMMA ms_simulation_options_list - | ms_simulation_option - ; - -ms_simulation : MS_SIMULATION ';' - { driver.ms_simulation(); } - | MS_SIMULATION '(' ms_simulation_options_list ')' ';' - { driver.ms_simulation(); } - ; - -ms_estimation_option : o_coefficients_prior_hyperparameters - | o_freq - | o_initial_year - | o_initial_subperiod - | o_final_year - | o_final_subperiod - | o_datafile - | o_xls_sheet - | o_xls_range - | o_nlags - | o_cross_restrictions - | o_contemp_reduced_form - | o_no_bayesian_prior - | o_alpha - | o_beta - | o_gsig2_lmdm - | o_specification - | o_output_file_tag - | o_file_tag - | o_no_create_init - | o_convergence_starting_value - | o_convergence_ending_value - | o_convergence_increment_value - | o_max_iterations_starting_value - | o_max_iterations_increment_value - | o_max_block_iterations - | o_max_repeated_optimization_runs - | o_function_convergence_criterion - | o_parameter_convergence_criterion - | o_number_of_large_perturbations - | o_number_of_small_perturbations - | o_number_of_posterior_draws_after_perturbation - | o_max_number_of_stages - | o_random_function_convergence_criterion - | o_random_parameter_convergence_criterion - ; - -ms_estimation_options_list : ms_estimation_option COMMA ms_estimation_options_list - | ms_estimation_option - ; - -ms_estimation : MS_ESTIMATION ';' - { driver.ms_estimation(); } - | MS_ESTIMATION '(' ms_estimation_options_list ')' ';' - { driver.ms_estimation(); } - ; - -dynare_sensitivity : DYNARE_SENSITIVITY ';' - { driver.dynare_sensitivity(); } - | DYNARE_SENSITIVITY '(' dynare_sensitivity_options_list ')' ';' - { driver.dynare_sensitivity(); } - ; - -dynare_sensitivity_options_list : dynare_sensitivity_option COMMA dynare_sensitivity_options_list - | dynare_sensitivity_option - ; - -dynare_sensitivity_option : o_gsa_identification - | o_gsa_morris - | o_gsa_stab - | o_gsa_redform - | o_gsa_pprior - | o_gsa_prior_range - | o_gsa_ppost - | o_gsa_ilptau - | o_gsa_morris_nliv - | o_gsa_morris_ntra - | o_gsa_nsam - | o_gsa_load_redform - | o_gsa_load_rmse - | o_gsa_load_stab - | o_gsa_alpha2_stab - | o_gsa_logtrans_redform - | o_gsa_ksstat_redform - | o_gsa_alpha2_redform - | o_gsa_rmse - | o_gsa_lik_only - | o_gsa_pfilt_rmse - | o_gsa_istart_rmse - | o_gsa_alpha_rmse - | o_gsa_alpha2_rmse - | o_gsa_threshold_redform - | o_gsa_namendo - | o_gsa_namexo - | o_gsa_namlagendo - | o_gsa_var_rmse - | o_gsa_neighborhood_width - | o_gsa_pvalue_ks - | o_gsa_pvalue_corr - | o_datafile - | o_nobs - | o_first_obs - | o_prefilter - | o_presample - | o_nograph - | o_nodisplay - | o_graph_format - | o_forecasts_conf_sig - | o_mh_conf_sig - | o_loglinear - | o_mode_file - | o_load_ident_files - | o_useautocorr - | o_ar - | o_kalman_algo - | o_lik_init - | o_diffuse_filter - | o_analytic_derivation - | o_analytic_derivation_mode - ; - -shock_decomposition_options_list : shock_decomposition_option COMMA shock_decomposition_options_list - | shock_decomposition_option - ; - -shock_decomposition_option : o_parameter_set - | o_datafile - | o_use_shock_groups - | o_colormap - | o_shock_decomposition_nograph - | o_first_obs - | o_nobs - | o_init_state - ; - -realtime_shock_decomposition_options_list : realtime_shock_decomposition_option COMMA realtime_shock_decomposition_options_list - | realtime_shock_decomposition_option - ; - -realtime_shock_decomposition_option : o_parameter_set - | o_datafile - | o_first_obs - | o_nobs - | o_use_shock_groups - | o_colormap - | o_shock_decomposition_nograph - | o_shock_decomposition_presample - | o_shock_decomposition_forecast - | o_save_realtime - | o_fast_realtime - ; - -plot_shock_decomposition_options_list : plot_shock_decomposition_option COMMA plot_shock_decomposition_options_list - | plot_shock_decomposition_option - ; - -plot_shock_decomposition_option : o_use_shock_groups - | o_colormap - | o_psd_nodisplay - | o_psd_graph_format - | o_psd_detail_plot - | o_psd_interactive - | o_psd_screen_shocks - | o_psd_steadystate - | o_psd_type - | o_psd_fig_name - | o_psd_write_xls - | o_psd_realtime - | o_psd_vintage - | o_psd_plot_init_date - | o_psd_plot_end_date - ; - -initial_condition_decomposition_options_list : initial_condition_decomposition_option COMMA initial_condition_decomposition_options_list - | initial_condition_decomposition_option - ; - -initial_condition_decomposition_option : o_icd_type - | o_icd_detail_plot - | o_icd_steadystate - | o_icd_write_xls - | o_icd_plot_init_date - | o_icd_plot_end_date - | o_nodisplay - | o_graph_format - | o_psd_fig_name - ; - -homotopy_setup: HOMOTOPY_SETUP ';' homotopy_list END ';' - { driver.end_homotopy();}; - -homotopy_list : homotopy_item - | homotopy_list homotopy_item - ; - -homotopy_item : symbol COMMA expression COMMA expression ';' - { driver.homotopy_val($1, $3, $5);} - | symbol COMMA expression ';' - { driver.homotopy_val($1, NULL, $3);} - ; - -forecast: FORECAST ';' {driver.forecast();} - | FORECAST '(' forecast_options ')' ';' {driver.forecast();} - | FORECAST symbol_list ';' {driver.forecast();} - | FORECAST '(' forecast_options ')' symbol_list ';' {driver.forecast();} - ; - -forecast_options: forecast_option - | forecast_options COMMA forecast_option - ; - -forecast_option: o_periods - | o_forecasts_conf_sig - | o_nograph - | o_nodisplay - | o_graph_format - ; - -conditional_forecast : CONDITIONAL_FORECAST '(' conditional_forecast_options ')' ';' - { driver.conditional_forecast(); } - ; - -conditional_forecast_options : conditional_forecast_option - | conditional_forecast_options COMMA conditional_forecast_option - ; - -conditional_forecast_option : o_periods - | o_replic - | o_conditional_forecast_conf_sig - | o_controlled_varexo - | o_parameter_set - ; - -plot_conditional_forecast : PLOT_CONDITIONAL_FORECAST symbol_list ';' - { driver.plot_conditional_forecast(); } - | PLOT_CONDITIONAL_FORECAST '(' PERIODS EQUAL INT_NUMBER ')' symbol_list ';' - { driver.plot_conditional_forecast($5); } - ; - -conditional_forecast_paths : CONDITIONAL_FORECAST_PATHS ';' conditional_forecast_paths_shock_list END ';' - { driver.conditional_forecast_paths(); } - ; - -conditional_forecast_paths_shock_list : conditional_forecast_paths_shock_elem - | conditional_forecast_paths_shock_list conditional_forecast_paths_shock_elem - ; - -conditional_forecast_paths_shock_elem : VAR symbol ';' PERIODS period_list ';' VALUES value_list ';' - { driver.add_det_shock($2, true); } - ; - -steady_state_model : STEADY_STATE_MODEL ';' { driver.begin_steady_state_model(); } - steady_state_equation_list END ';' { driver.reset_data_tree(); } - ; - -steady_state_equation_list : steady_state_equation_list steady_state_equation - | steady_state_equation - ; - -steady_state_equation : symbol EQUAL expression ';' - { driver.add_steady_state_model_equal($1, $3); } - | '[' symbol_list ']' EQUAL expression ';' - { driver.add_steady_state_model_equal_multiple($5); } - ; - -calib_smoother : CALIB_SMOOTHER ';' - { driver.calib_smoother(); } - | CALIB_SMOOTHER '(' calib_smoother_options_list ')' ';' - { driver.calib_smoother(); } - | CALIB_SMOOTHER symbol_list ';' - { driver.calib_smoother(); } - | CALIB_SMOOTHER '(' calib_smoother_options_list ')' symbol_list ';' - { driver.calib_smoother(); } - ; - -calib_smoother_options_list : calib_smoother_option COMMA calib_smoother_options_list - | calib_smoother_option - ; - -calib_smoother_option : o_filtered_vars - | o_filter_step_ahead - | o_datafile - | o_prefilter - | o_loglinear - | o_first_obs - | o_filter_decomposition - | o_diffuse_kalman_tol - | o_diffuse_filter - | o_smoothed_state_uncertainty - | o_parameter_set - ; - -generate_irfs : GENERATE_IRFS ';' END ';' - { driver.end_generate_irfs(); } - | GENERATE_IRFS ';' generate_irfs_element_list END ';' - { driver.end_generate_irfs(); } - | GENERATE_IRFS '(' generate_irfs_options_list ')' ';' END ';' - { driver.end_generate_irfs(); } - | GENERATE_IRFS '(' generate_irfs_options_list ')' ';' generate_irfs_element_list END ';' - { driver.end_generate_irfs(); } - ; - -generate_irfs_options_list : generate_irfs_option COMMA generate_irfs_options_list - | generate_irfs_option - ; - -generate_irfs_option : o_stderr_multiples - | o_diagonal_only - ; - -generate_irfs_element_list : generate_irfs_element_list generate_irfs_element - | generate_irfs_element - ; - -generate_irfs_element : NAME COMMA generate_irfs_exog_element_list ';' - { driver.add_generate_irfs_element($1); } - ; - -generate_irfs_exog_element_list : generate_irfs_exog_element_list COMMA symbol EQUAL signed_number - { driver.add_generate_irfs_exog_element($3, $5); } - | symbol EQUAL signed_number - { driver.add_generate_irfs_exog_element($1, $3); } - ; - -extended_path : EXTENDED_PATH ';' - { driver.extended_path(); } - | EXTENDED_PATH '(' extended_path_options_list ')' ';' - { driver.extended_path(); } - ; - -extended_path_options_list : extended_path_option COMMA extended_path_options_list - | extended_path_option - ; - -extended_path_option : o_periods - | o_solver_periods - | o_extended_path_order - | o_hybrid - | o_lmmcp - | o_occbin - ; - -model_diagnostics : MODEL_DIAGNOSTICS ';' - { driver.model_diagnostics(); } - ; - -calibration_range : '[' signed_number_w_inf signed_number_w_inf ']' - { - $$ = new vector(); - $$->push_back($2); - $$->push_back($3); - } - | '[' signed_number_w_inf COMMA signed_number_w_inf ']' - { - $$ = new vector(); - $$->push_back($2); - $$->push_back($4); - } - | PLUS - { - $$ = new vector(); - $$->push_back(new string("0")); - $$->push_back(new string("inf")); - } - | MINUS - { - $$ = new vector(); - $$->push_back(new string("-inf")); - $$->push_back(new string("0")); - } - ; - -moment_calibration : MOMENT_CALIBRATION ';' moment_calibration_list END ';' - { driver.end_moment_calibration(); } - ; - -moment_calibration_list : moment_calibration_item - | moment_calibration_list moment_calibration_item - ; - -moment_calibration_item : symbol COMMA symbol COMMA calibration_range ';' - { driver.add_moment_calibration_item($1, $3, new string("0"), $5); } - | symbol COMMA symbol '(' signed_integer ')' COMMA calibration_range ';' - { driver.add_moment_calibration_item($1, $3, $5, $8); } - | symbol COMMA symbol '(' signed_integer_range ')' COMMA calibration_range ';' - { driver.add_moment_calibration_item($1, $3, $5, $8); } - ; - -irf_calibration : IRF_CALIBRATION ';' irf_calibration_list END ';' - { driver.end_irf_calibration(); } - | IRF_CALIBRATION '(' o_relative_irf ')' ';' irf_calibration_list END ';' - { driver.end_irf_calibration(); } - ; - -irf_calibration_list : irf_calibration_item - | irf_calibration_list irf_calibration_item - ; - -irf_calibration_item : symbol COMMA symbol COMMA calibration_range ';' - { driver.add_irf_calibration_item($1, new string("1"), $3, $5); } - | symbol '(' INT_NUMBER ')' COMMA symbol COMMA calibration_range ';' - { driver.add_irf_calibration_item($1, $3, $6, $8); } - | symbol '(' integer_range ')' COMMA symbol COMMA calibration_range ';' - { driver.add_irf_calibration_item($1, $3, $6, $8); } - ; - -smoother2histval : SMOOTHER2HISTVAL ';' - { driver.smoother2histval(); } - | SMOOTHER2HISTVAL '(' smoother2histval_options_list ')' ';' - { driver.smoother2histval(); } - ; - -smoother2histval_options_list : smoother2histval_option COMMA smoother2histval_options_list - | smoother2histval_option - ; - -smoother2histval_option : o_infile - | o_invars - | o_period - | o_outfile - | o_outvars - ; - -shock_groups : SHOCK_GROUPS ';' shock_group_list END ';'{driver.end_shock_groups(new string("default"));} - | SHOCK_GROUPS '(' NAME EQUAL symbol ')' ';' shock_group_list END ';' - {driver.end_shock_groups($5);} - ; - -shock_group_list : shock_group_list shock_group_element - | shock_group_element - ; - -shock_group_element : symbol EQUAL shock_name_list ';' { driver.add_shock_group($1); } - | QUOTED_STRING EQUAL shock_name_list ';' { driver.add_shock_group($1); } - ; - -shock_name_list : shock_name_list COMMA symbol {driver.add_shock_group_element($3);} - | shock_name_list symbol {driver.add_shock_group_element($2);} - | symbol {driver.add_shock_group_element($1);} - ; - -o_dr_algo : DR_ALGO EQUAL INT_NUMBER { - if (*$3 == string("0")) - driver.warning("dr_algo option is now deprecated, and may be removed in a future version of Dynare"); - else - driver.error("dr_algo=1 option is no longer supported"); - }; -o_solve_algo : SOLVE_ALGO EQUAL INT_NUMBER { driver.option_num("solve_algo", $3); }; -o_simul_algo : SIMUL_ALGO EQUAL INT_NUMBER { - if (*$3 == string("0")) - driver.warning("simul_algo option is now deprecated, and may be removed in a future version of Dynare"); - else - driver.error("simul_algo=1 option is no longer supported"); - }; -o_stack_solve_algo : STACK_SOLVE_ALGO EQUAL INT_NUMBER { driver.option_num("stack_solve_algo", $3); }; -o_robust_lin_solve : ROBUST_LIN_SOLVE { driver.option_num("simul.robust_lin_solve", "1"); }; -o_endogenous_terminal_period : ENDOGENOUS_TERMINAL_PERIOD { driver.option_num("endogenous_terminal_period", "1"); }; -o_linear : LINEAR { driver.linear(); }; -o_order : ORDER EQUAL INT_NUMBER { driver.option_num("order", $3); }; -o_replic : REPLIC EQUAL INT_NUMBER { driver.option_num("replic", $3); }; -o_drop : DROP EQUAL INT_NUMBER { driver.option_num("drop", $3); }; -o_ar : AR EQUAL INT_NUMBER { driver.option_num("ar", $3); }; -o_nocorr : NOCORR { driver.option_num("nocorr", "1"); }; -o_nofunctions : NOFUNCTIONS { driver.option_num("nofunctions", "1"); }; -o_nomoments : NOMOMENTS { driver.option_num("nomoments", "1"); }; -o_irf : IRF EQUAL INT_NUMBER { driver.option_num("irf", $3); }; -o_irf_shocks : IRF_SHOCKS EQUAL '(' symbol_list ')' { driver.option_symbol_list("irf_shocks"); }; -o_hp_filter : HP_FILTER EQUAL non_negative_number { driver.option_num("hp_filter", $3); }; -o_hp_ngrid : HP_NGRID EQUAL INT_NUMBER { driver.option_num("hp_ngrid", $3); }; -o_one_sided_hp_filter : ONE_SIDED_HP_FILTER EQUAL non_negative_number { driver.option_num("one_sided_hp_filter", $3); }; -o_periods : PERIODS EQUAL INT_NUMBER { driver.option_num("periods", $3); }; -o_solver_periods : SOLVER_PERIODS EQUAL INT_NUMBER { driver.option_num("ep.periods", $3); }; -o_extended_path_order : ORDER EQUAL INT_NUMBER { driver.option_num("ep.stochastic.order", $3); }; -o_hybrid : HYBRID { driver.option_num("ep.stochastic.hybrid_order", "2"); }; -o_steady_maxit : MAXIT EQUAL INT_NUMBER { driver.option_num("steady.maxit", $3); }; -o_simul_maxit : MAXIT EQUAL INT_NUMBER { driver.option_num("simul.maxit", $3); }; -o_bandpass_filter : BANDPASS_FILTER { driver.option_num("bandpass.indicator", "1"); } - | BANDPASS_FILTER EQUAL vec_int - { - driver.option_num("bandpass.indicator", "1"); - driver.option_vec_int("bandpass.passband", $3); - } - ; -o_dp_maxit : MAXIT EQUAL INT_NUMBER { driver.option_num("dp.maxit", $3); }; -o_osr_maxit : MAXIT EQUAL INT_NUMBER { driver.option_num("osr.maxit", $3); }; -o_osr_tolf : TOLF EQUAL non_negative_number { driver.option_num("osr.tolf", $3); }; -o_pf_tolf : TOLF EQUAL non_negative_number { driver.option_num("dynatol.f", $3); }; -o_pf_tolx : TOLX EQUAL non_negative_number { driver.option_num("dynatol.x", $3); }; -o_steady_tolf : TOLF EQUAL non_negative_number { driver.option_num("solve_tolf", $3); }; -o_opt_algo : OPT_ALGO EQUAL INT_NUMBER { driver.option_num("osr.opt_algo", $3); } - | OPT_ALGO EQUAL filename { driver.option_str("osr.opt_algo", $3); } - ; -o_cutoff : CUTOFF EQUAL non_negative_number { driver.cutoff($3); }; -o_markowitz : MARKOWITZ EQUAL non_negative_number { driver.option_num("markowitz", $3); }; -o_minimal_solving_periods : MINIMAL_SOLVING_PERIODS EQUAL non_negative_number { driver.option_num("minimal_solving_periods", $3); }; -o_mfs : MFS EQUAL INT_NUMBER { driver.mfs($3); }; -o_simul : SIMUL; // Do nothing, only here for backward compatibility -o_simul_replic : SIMUL_REPLIC EQUAL INT_NUMBER { driver.option_num("simul_replic", $3); }; -o_simul_seed : SIMUL_SEED EQUAL INT_NUMBER { driver.error("'simul_seed' option is no longer supported; use 'set_dynare_seed' command instead"); } ; -o_qz_criterium : QZ_CRITERIUM EQUAL non_negative_number { driver.option_num("qz_criterium", $3); }; -o_qz_zero_threshold : QZ_ZERO_THRESHOLD EQUAL non_negative_number { driver.option_num("qz_zero_threshold", $3); }; -o_file : FILE EQUAL filename { driver.option_str("file", $3); }; -o_series : SERIES EQUAL symbol { driver.option_str("series", $3); }; -o_datafile : DATAFILE EQUAL filename { driver.option_str("datafile", $3); }; -o_dirname : DIRNAME EQUAL filename { driver.option_str("dirname", $3); }; -o_huge_number : HUGE_NUMBER EQUAL non_negative_number { driver.option_num("huge_number", $3); }; -o_nobs : NOBS EQUAL vec_int - { driver.option_vec_int("nobs", $3); } - | NOBS EQUAL vec_int_number - { driver.option_vec_int("nobs", $3); } - ; -o_conditional_variance_decomposition : CONDITIONAL_VARIANCE_DECOMPOSITION EQUAL vec_int - { driver.option_vec_int("conditional_variance_decomposition", $3); } - | CONDITIONAL_VARIANCE_DECOMPOSITION EQUAL vec_int_number - { driver.option_vec_int("conditional_variance_decomposition", $3); } - ; -o_est_first_obs : FIRST_OBS EQUAL vec_int - { driver.option_vec_int("first_obs", $3); } - | FIRST_OBS EQUAL vec_int_number - { driver.option_vec_int("first_obs", $3); } - ; -o_posterior_sampling_method : POSTERIOR_SAMPLING_METHOD EQUAL QUOTED_STRING - { driver.option_str("posterior_sampler_options.posterior_sampling_method", $3); } ; -o_first_obs : FIRST_OBS EQUAL INT_NUMBER { driver.option_num("first_obs", $3); }; -o_data_first_obs : FIRST_OBS EQUAL date_expr { driver.option_date("firstobs", $3); } ; -o_data_last_obs : LAST_OBS EQUAL date_expr { driver.option_date("lastobs", $3); } ; -o_keep_kalman_algo_if_singularity_is_detected : KEEP_KALMAN_ALGO_IF_SINGULARITY_IS_DETECTED { driver.option_num("kalman.keep_kalman_algo_if_singularity_is_detected", "1"); } ; -o_data_nobs : NOBS EQUAL INT_NUMBER { driver.option_num("nobs", $3); }; -o_shift : SHIFT EQUAL signed_number { driver.option_num("shift", $3); }; -o_shape : SHAPE EQUAL prior_distribution { driver.prior_shape = $3; }; -o_mode : MODE EQUAL signed_number { driver.option_num("mode", $3); }; -o_mean : MEAN EQUAL signed_number { driver.option_num("mean", $3); }; -o_mean_vec : MEAN EQUAL vec_value { driver.option_num("mean", $3); }; -o_truncate : TRUNCATE EQUAL vec_value { driver.option_num("truncate", $3); }; -o_stdev : STDEV EQUAL non_negative_number { driver.option_num("stdev", $3); }; -o_jscale : JSCALE EQUAL non_negative_number { driver.option_num("jscale", $3); }; -o_init : INIT EQUAL signed_number { driver.option_num("init", $3); }; -o_bounds : BOUNDS EQUAL vec_value_w_inf { driver.option_num("bounds", $3); }; -o_domain : DOMAINN EQUAL vec_value { driver.option_num("domain", $3); }; -o_interval : INTERVAL EQUAL vec_value { driver.option_num("interval", $3); }; -o_variance : VARIANCE EQUAL expression { driver.set_prior_variance($3); } -o_variance_mat : VARIANCE EQUAL vec_of_vec_value { driver.option_num("variance",$3); } -o_prefilter : PREFILTER EQUAL INT_NUMBER { driver.option_num("prefilter", $3); }; -o_presample : PRESAMPLE EQUAL INT_NUMBER { driver.option_num("presample", $3); }; -o_lik_algo : LIK_ALGO EQUAL INT_NUMBER { driver.option_num("lik_algo", $3); }; -o_lik_init : LIK_INIT EQUAL INT_NUMBER { driver.option_num("lik_init", $3); }; -o_nograph : NOGRAPH - { driver.option_num("nograph","1"); } - | GRAPH - { driver.option_num("nograph", "0"); } - ; -o_posterior_nograph : POSTERIOR_NOGRAPH - { driver.option_num("no_graph.posterior","1"); } - | POSTERIOR_GRAPH - { driver.option_num("no_graph.posterior", "0"); } - ; -o_shock_decomposition_nograph : NOGRAPH { driver.option_num("no_graph.shock_decomposition", "1"); } -o_init_state : INIT_STATE EQUAL INT_NUMBER { driver.option_num("shock_decomp.init_state", $3); }; -o_shock_decomposition_presample : PRESAMPLE EQUAL INT_NUMBER { driver.option_num("shock_decomp.presample", $3); }; -o_shock_decomposition_forecast : FORECAST EQUAL INT_NUMBER { driver.option_num("shock_decomp.forecast", $3); }; -o_save_realtime : SAVE_REALTIME EQUAL vec_int { driver.option_vec_int("shock_decomp.save_realtime", $3); }; -o_fast_realtime : FAST_REALTIME EQUAL INT_NUMBER { driver.option_num("shock_decomp.fast_realtime", $3); }; -o_nodisplay : NODISPLAY { driver.option_num("nodisplay","1"); }; -o_psd_nodisplay : NODISPLAY { driver.option_num("plot_shock_decomp.nodisplay","1"); }; -o_graph_format : GRAPH_FORMAT EQUAL allowed_graph_formats - { driver.process_graph_format_option(); } - | GRAPH_FORMAT EQUAL '(' list_allowed_graph_formats ')' - { driver.process_graph_format_option(); } - ; -o_psd_graph_format : GRAPH_FORMAT EQUAL allowed_graph_formats - { driver.plot_shock_decomp_process_graph_format_option(); } - | GRAPH_FORMAT EQUAL '(' list_allowed_graph_formats ')' - { driver.plot_shock_decomp_process_graph_format_option(); } - ; -allowed_graph_formats : EPS - { driver.add_graph_format("eps"); } - | FIG - { driver.add_graph_format("fig"); } - | PDF - { driver.add_graph_format("pdf"); } - | NONE - { driver.add_graph_format("none"); } - ; -list_allowed_graph_formats : allowed_graph_formats - | list_allowed_graph_formats COMMA allowed_graph_formats - ; - -o_subsample_name : symbol EQUAL date_expr ':' date_expr - { driver.set_subsample_name_equal_to_date_range($1, $3, $5); } - ; -o_bvar_conf_sig : CONF_SIG EQUAL non_negative_number { driver.option_num("bvar.conf_sig", $3); }; -o_forecasts_conf_sig : CONF_SIG EQUAL non_negative_number { driver.option_num("forecasts.conf_sig", $3); }; -o_conditional_forecast_conf_sig : CONF_SIG EQUAL non_negative_number { driver.option_num("conditional_forecast.conf_sig", $3); }; -o_mh_conf_sig : MH_CONF_SIG EQUAL non_negative_number { driver.option_num("mh_conf_sig", $3); }; -o_mh_replic : MH_REPLIC EQUAL INT_NUMBER { driver.option_num("mh_replic", $3); }; -o_posterior_max_subsample_draws : POSTERIOR_MAX_SUBSAMPLE_DRAWS EQUAL INT_NUMBER { driver.option_num("posterior_max_subsample_draws", $3); }; -o_mh_drop : MH_DROP EQUAL non_negative_number { driver.option_num("mh_drop", $3); }; -o_mh_jscale : MH_JSCALE EQUAL non_negative_number { driver.option_num("mh_jscale", $3); }; -o_optim : OPTIM EQUAL '(' optim_options ')'; -o_posterior_sampler_options : POSTERIOR_SAMPLER_OPTIONS EQUAL '(' sampling_options ')' ; -o_proposal_distribution : PROPOSAL_DISTRIBUTION EQUAL symbol { driver.option_str("posterior_sampler_options.posterior_sampling_method.proposal_distribution", $3); }; -o_no_posterior_kernel_density : NO_POSTERIOR_KERNEL_DENSITY - { driver.option_num("estimation.moments_posterior_density.indicator", "0"); } - ; -o_mh_init_scale : MH_INIT_SCALE EQUAL non_negative_number { driver.option_num("mh_init_scale", $3); }; -o_mode_file : MODE_FILE EQUAL filename { driver.option_str("mode_file", $3); }; -o_mode_compute : MODE_COMPUTE EQUAL INT_NUMBER { driver.option_num("mode_compute", $3); }; - | MODE_COMPUTE EQUAL symbol { driver.option_str("mode_compute", $3); }; -o_mode_check : MODE_CHECK { driver.option_num("mode_check.status", "1"); }; -o_mode_check_neighbourhood_size : MODE_CHECK_NEIGHBOURHOOD_SIZE EQUAL signed_number_w_inf { driver.option_num("mode_check.neighbourhood_size", $3); }; -o_mode_check_number_of_points : MODE_CHECK_NUMBER_OF_POINTS EQUAL INT_NUMBER { driver.option_num("mode_check.number_of_points", $3); }; -o_mode_check_symmetric_plots : MODE_CHECK_SYMMETRIC_PLOTS EQUAL INT_NUMBER { driver.option_num("mode_check.symmetric_plots", $3); }; -o_prior_trunc : PRIOR_TRUNC EQUAL non_negative_number { driver.option_num("prior_trunc", $3); }; -o_mh_mode : MH_MODE EQUAL INT_NUMBER { driver.option_num("mh_mode", $3); }; -o_mh_nblocks : MH_NBLOCKS EQUAL INT_NUMBER { driver.option_num("mh_nblck", $3); }; -o_load_mh_file : LOAD_MH_FILE { driver.option_num("load_mh_file", "1"); }; -o_load_results_after_load_mh : LOAD_RESULTS_AFTER_LOAD_MH { driver.option_num("load_results_after_load_mh", "1"); }; -o_loglinear : LOGLINEAR { driver.option_num("loglinear", "1"); }; -o_linear_approximation : LINEAR_APPROXIMATION { driver.option_num("linear_approximation", "1"); }; -o_logdata : LOGDATA { driver.option_num("logdata", "1"); }; -o_nodiagnostic : NODIAGNOSTIC { driver.option_num("nodiagnostic", "1"); }; -o_bayesian_irf : BAYESIAN_IRF { driver.option_num("bayesian_irf", "1"); }; -o_dsge_var : DSGE_VAR EQUAL non_negative_number - { driver.option_num("dsge_var", $3); } - | DSGE_VAR EQUAL INF_CONSTANT - { driver.option_num("dsge_var", "Inf"); } - | DSGE_VAR - { driver.option_str("dsge_var", "NaN"); } - ; -o_dsge_varlag : DSGE_VARLAG EQUAL INT_NUMBER { driver.option_num("dsge_varlag", $3); }; -o_tex : TEX { driver.option_num("TeX", "1"); }; -o_forecast : FORECAST EQUAL INT_NUMBER { driver.option_num("forecast", $3); }; -o_smoother : SMOOTHER { driver.option_num("smoother", "1"); }; -o_moments_varendo : MOMENTS_VARENDO { driver.option_num("moments_varendo", "1"); }; -o_contemporaneous_correlation : CONTEMPORANEOUS_CORRELATION { driver.option_num("contemporaneous_correlation", "1"); }; -o_filtered_vars : FILTERED_VARS { driver.option_num("filtered_vars", "1"); }; -o_relative_irf : RELATIVE_IRF { driver.option_num("relative_irf", "1"); }; -o_fast_kalman_filter : FAST_KALMAN_FILTER { driver.option_num("fast_kalman_filter", "1"); }; -o_kalman_algo : KALMAN_ALGO EQUAL INT_NUMBER { driver.option_num("kalman_algo", $3); }; -o_kalman_tol : KALMAN_TOL EQUAL non_negative_number { driver.option_num("kalman_tol", $3); }; -o_diffuse_kalman_tol : DIFFUSE_KALMAN_TOL EQUAL non_negative_number { driver.option_num("diffuse_kalman_tol", $3); }; -o_marginal_density : MARGINAL_DENSITY EQUAL LAPLACE - { driver.option_str("mc_marginal_density", "laplace"); } - | MARGINAL_DENSITY EQUAL MODIFIEDHARMONICMEAN - { driver.option_str("mc_marginal_density", "modifiedharmonicmean"); } - ; -o_print : PRINT { driver.option_num("noprint", "0"); }; -o_noprint : NOPRINT { driver.option_num("noprint", "1"); }; -o_xls_sheet : XLS_SHEET EQUAL symbol { driver.option_str("xls_sheet", $3); }; -o_xls_range : XLS_RANGE EQUAL range { driver.option_str("xls_range", $3); }; -o_filter_step_ahead : FILTER_STEP_AHEAD EQUAL vec_int { driver.option_vec_int("filter_step_ahead", $3); }; -o_taper_steps : TAPER_STEPS EQUAL vec_int { driver.option_vec_int("convergence.geweke.taper_steps", $3); }; -o_geweke_interval : GEWEKE_INTERVAL EQUAL vec_value { driver.option_num("convergence.geweke.geweke_interval",$3); }; -o_raftery_lewis_diagnostics : RAFTERY_LEWIS_DIAGNOSTICS { driver.option_num("convergence.rafterylewis.indicator", "1"); }; -o_raftery_lewis_qrs : RAFTERY_LEWIS_QRS EQUAL vec_value { driver.option_num("convergence.rafterylewis.qrs",$3); }; -o_constant : CONSTANT { driver.option_num("noconstant", "0"); }; -o_noconstant : NOCONSTANT { driver.option_num("noconstant", "1"); }; -o_mh_recover : MH_RECOVER { driver.option_num("mh_recover", "1"); }; -o_diffuse_filter: DIFFUSE_FILTER {driver.option_num("diffuse_filter", "1"); }; -o_plot_priors: PLOT_PRIORS EQUAL INT_NUMBER {driver.option_num("plot_priors", $3); }; -o_aim_solver: AIM_SOLVER {driver.option_num("aim_solver", "1"); }; -o_partial_information : PARTIAL_INFORMATION {driver.option_num("partial_information", "1"); }; -o_sub_draws: SUB_DRAWS EQUAL INT_NUMBER {driver.option_num("sub_draws",$3);}; -o_planner_discount : PLANNER_DISCOUNT EQUAL expression { driver.declare_optimal_policy_discount_factor_parameter($3); }; -o_sylvester : SYLVESTER EQUAL FIXED_POINT {driver.option_num("sylvester_fp", "1"); } - | SYLVESTER EQUAL DEFAULT {driver.option_num("sylvester_fp", "0"); }; -o_sylvester_fixed_point_tol : SYLVESTER_FIXED_POINT_TOL EQUAL non_negative_number {driver.option_num("sylvester_fixed_point_tol",$3);}; -o_lyapunov : LYAPUNOV EQUAL FIXED_POINT {driver.option_num("lyapunov_fp", "1"); } - | LYAPUNOV EQUAL DOUBLING {driver.option_num("lyapunov_db", "1"); } - | LYAPUNOV EQUAL SQUARE_ROOT_SOLVER {driver.option_num("lyapunov_srs", "1"); } - | LYAPUNOV EQUAL DEFAULT {driver.option_num("lyapunov_fp", "0");driver.option_num("lyapunov_db", "0"); driver.option_num("lyapunov_srs", "0");}; -o_lyapunov_fixed_point_tol : LYAPUNOV_FIXED_POINT_TOL EQUAL non_negative_number {driver.option_num("lyapunov_fixed_point_tol",$3);}; -o_lyapunov_doubling_tol : LYAPUNOV_DOUBLING_TOL EQUAL non_negative_number {driver.option_num("lyapunov_doubling_tol",$3);}; -o_dr : DR EQUAL CYCLE_REDUCTION {driver.option_num("dr_cycle_reduction", "1"); } - | DR EQUAL LOGARITHMIC_REDUCTION {driver.option_num("dr_logarithmic_reduction", "1"); } - | DR EQUAL DEFAULT {driver.option_num("dr_cycle_reduction", "0"); driver.option_num("dr_logarithmic_reduction", "0");}; -o_dr_cycle_reduction_tol : DR_CYCLE_REDUCTION_TOL EQUAL non_negative_number {driver.option_num("dr_cycle_reduction_tol",$3);}; -o_dr_logarithmic_reduction_tol : DR_LOGARITHMIC_REDUCTION_TOL EQUAL non_negative_number {driver.option_num("dr_logarithmic_reduction_tol",$3);}; -o_dr_logarithmic_reduction_maxiter : DR_LOGARITHMIC_REDUCTION_MAXITER EQUAL INT_NUMBER {driver.option_num("dr_logarithmic_reduction_maxiter",$3);}; -o_psd_detail_plot : DETAIL_PLOT { driver.option_num("plot_shock_decomp.detail_plot", "1"); }; -o_icd_detail_plot : DETAIL_PLOT { driver.option_num("initial_condition_decomp.detail_plot", "1"); }; -o_psd_interactive : INTERACTIVE { driver.option_num("plot_shock_decomp.interactive", "1"); }; -o_psd_screen_shocks : SCREEN_SHOCKS { driver.option_num("plot_shock_decomp.screen_shocks", "1"); }; -o_psd_steadystate : STEADYSTATE { driver.option_num("plot_shock_decomp.steadystate", "1"); }; -o_icd_steadystate : STEADYSTATE { driver.option_num("initial_condition_decomp.steadystate", "1"); }; -o_psd_fig_name : FIG_NAME EQUAL filename { driver.option_str("plot_shock_decomp.fig_name", $3); }; -o_psd_type : TYPE EQUAL QOQ - { driver.option_str("plot_shock_decomp.type", "qoq"); } - | TYPE EQUAL YOY - { driver.option_str("plot_shock_decomp.type", "yoy"); } - | TYPE EQUAL AOA - { driver.option_str("plot_shock_decomp.type", "aoa"); } - ; -o_icd_type : TYPE EQUAL QOQ - { driver.option_str("initial_condition_decomp.type", "qoq"); } - | TYPE EQUAL YOY - { driver.option_str("initial_condition_decomp.type", "yoy"); } - | TYPE EQUAL AOA - { driver.option_str("initial_condition_decomp.type", "aoa"); } - ; -o_icd_plot_init_date : PLOT_INIT_DATE EQUAL date_expr { driver.option_date("initial_condition_decomp.plot_init_date", $3); } ; -o_icd_plot_end_date : PLOT_END_DATE EQUAL date_expr { driver.option_date("initial_condition_decomp.plot_end_date", $3); } ; -o_psd_plot_init_date : PLOT_INIT_DATE EQUAL date_expr { driver.option_date("plot_shock_decomp.plot_init_date", $3); } ; -o_psd_plot_end_date : PLOT_END_DATE EQUAL date_expr { driver.option_date("plot_shock_decomp.plot_end_date", $3); } ; -o_icd_write_xls : WRITE_XLS { driver.option_num("initial_condition_decomp.write_xls", "1"); }; -o_psd_write_xls : WRITE_XLS { driver.option_num("plot_shock_decomp.write_xls", "1"); }; -o_psd_realtime : REALTIME EQUAL INT_NUMBER { driver.option_num("plot_shock_decomp.realtime", $3); }; -o_psd_vintage : VINTAGE EQUAL INT_NUMBER { driver.option_num("plot_shock_decomp.vintage", $3); }; -o_bvar_prior_tau : BVAR_PRIOR_TAU EQUAL signed_number { driver.option_num("bvar_prior_tau", $3); }; -o_bvar_prior_decay : BVAR_PRIOR_DECAY EQUAL non_negative_number { driver.option_num("bvar_prior_decay", $3); }; -o_bvar_prior_lambda : BVAR_PRIOR_LAMBDA EQUAL signed_number { driver.option_num("bvar_prior_lambda", $3); }; -o_bvar_prior_mu : BVAR_PRIOR_MU EQUAL non_negative_number { driver.option_num("bvar_prior_mu", $3); }; -o_bvar_prior_omega : BVAR_PRIOR_OMEGA EQUAL INT_NUMBER { driver.option_num("bvar_prior_omega", $3); }; -o_bvar_prior_flat : BVAR_PRIOR_FLAT { driver.option_num("bvar_prior_flat", "1"); }; -o_bvar_prior_train : BVAR_PRIOR_TRAIN EQUAL INT_NUMBER { driver.option_num("bvar_prior_train", $3); }; -o_bvar_replic : BVAR_REPLIC EQUAL INT_NUMBER { driver.option_num("bvar_replic", $3); }; -o_stderr_multiples : STDERR_MULTIPLES { driver.option_num("irf_opt.stderr_multiples", "1"); }; -o_diagonal_only : DIAGONAL_ONLY { driver.option_num("irf_opt.diagonal_only", "1"); }; -o_number_of_particles : NUMBER_OF_PARTICLES EQUAL INT_NUMBER { driver.option_num("particle.number_of_particles", $3); }; -o_resampling : RESAMPLING EQUAL SYSTEMATIC - | RESAMPLING EQUAL NONE {driver.option_num("particle.resampling.status.systematic", "0"); driver.option_num("particle.resampling.status.none", "1"); } - | RESAMPLING EQUAL GENERIC {driver.option_num("particle.resampling.status.systematic", "0"); driver.option_num("particle.resampling.status.generic", "1"); }; -o_resampling_threshold : RESAMPLING_THRESHOLD EQUAL non_negative_number { driver.option_num("particle.resampling.threshold", $3); }; -o_resampling_method : RESAMPLING_METHOD EQUAL KITAGAWA {driver.option_num("particle.resampling.method.kitagawa", "1"); driver.option_num("particle.resampling.method.smooth", "0"); driver.option_num("particle.resampling.smethod.stratified", "0"); } - | RESAMPLING_METHOD EQUAL SMOOTH {driver.option_num("particle.resampling.method.kitagawa", "0"); driver.option_num("particle.resampling.method.smooth", "1"); driver.option_num("particle.resampling.smethod.stratified", "0"); } - | RESAMPLING_METHOD EQUAL STRATIFIED {driver.option_num("particle.resampling.method.kitagawa", "0"); driver.option_num("particle.resampling.method.smooth", "0"); driver.option_num("particle.resampling.method.stratified", "1"); }; -o_cpf_weights : CPF_WEIGHTS EQUAL AMISANOTRISTANI {driver.option_num("particle.cpf_weights_method.amisanotristani", "1"); driver.option_num("particle.cpf_weights_method.murrayjonesparslow", "0"); } - | CPF_WEIGHTS EQUAL MURRAYJONESPARSLOW {driver.option_num("particle.cpf_weights_method.amisanotristani", "0"); driver.option_num("particle.cpf_weights_method.murrayjonesparslow", "1"); }; -o_filter_algorithm : FILTER_ALGORITHM EQUAL symbol { driver.option_str("particle.filter_algorithm", $3); }; -o_nonlinear_filter_initialization : NONLINEAR_FILTER_INITIALIZATION EQUAL INT_NUMBER { driver.option_num("particle.initialization", $3); }; -o_proposal_approximation : PROPOSAL_APPROXIMATION EQUAL CUBATURE {driver.option_num("particle.proposal_approximation.cubature", "1"); driver.option_num("particle.proposal_approximation.unscented", "0"); driver.option_num("particle.proposal_approximation.montecarlo", "0");} - | PROPOSAL_APPROXIMATION EQUAL UNSCENTED {driver.option_num("particle.proposal_approximation.cubature", "0"); driver.option_num("particle.proposal_approximation.unscented", "1"); driver.option_num("particle.proposal_approximation.montecarlo", "0");} - | PROPOSAL_APPROXIMATION EQUAL MONTECARLO {driver.option_num("particle.proposal_approximation.cubature", "0"); driver.option_num("particle.proposal_approximation.unscented", "0"); driver.option_num("particle.proposal_approximation.montecarlo", "1");} ; -o_distribution_approximation : DISTRIBUTION_APPROXIMATION EQUAL CUBATURE {driver.option_num("particle.distribution_approximation.cubature", "1"); driver.option_num("particle.distribution_approximation.unscented", "0"); driver.option_num("particle.distribution_approximation.montecarlo", "0");} - | DISTRIBUTION_APPROXIMATION EQUAL UNSCENTED {driver.option_num("particle.distribution_approximation.cubature", "0"); driver.option_num("particle.distribution_approximation.unscented", "1"); driver.option_num("particle.distribution_approximation.montecarlo", "0");} - | DISTRIBUTION_APPROXIMATION EQUAL MONTECARLO {driver.option_num("particle.distribution_approximation.cubature", "0"); driver.option_num("particle.distribution_approximation.unscented", "0"); driver.option_num("particle.distribution_approximation.montecarlo", "1");} ; - - -o_gsa_identification : IDENTIFICATION EQUAL INT_NUMBER { driver.option_num("identification", $3); }; /*not in doc */ -o_gsa_morris : MORRIS EQUAL INT_NUMBER { driver.option_num("morris", $3); }; -o_gsa_stab : STAB EQUAL INT_NUMBER { driver.option_num("stab", $3); }; -o_gsa_redform : REDFORM EQUAL INT_NUMBER { driver.option_num("redform", $3); }; -o_gsa_pprior : PPRIOR EQUAL INT_NUMBER { driver.option_num("pprior", $3); }; -o_gsa_prior_range : PRIOR_RANGE EQUAL INT_NUMBER { driver.option_num("prior_range", $3); }; -o_gsa_ppost : PPOST EQUAL INT_NUMBER { driver.option_num("ppost", $3); }; -o_gsa_ilptau : ILPTAU EQUAL INT_NUMBER { driver.option_num("ilptau", $3); }; -o_gsa_morris_nliv : MORRIS_NLIV EQUAL INT_NUMBER { driver.option_num("morris_nliv", $3); }; -o_gsa_morris_ntra : MORRIS_NTRA EQUAL INT_NUMBER { driver.option_num("morris_ntra", $3); }; -o_gsa_nsam : NSAM EQUAL INT_NUMBER { driver.option_num("Nsam", $3); }; /* not in doc ??*/ -o_gsa_load_redform : LOAD_REDFORM EQUAL INT_NUMBER { driver.option_num("load_redform", $3); }; -o_gsa_load_rmse : LOAD_RMSE EQUAL INT_NUMBER { driver.option_num("load_rmse", $3); }; -o_gsa_load_stab : LOAD_STAB EQUAL INT_NUMBER { driver.option_num("load_stab", $3); }; -o_gsa_alpha2_stab : ALPHA2_STAB EQUAL non_negative_number { driver.option_num("alpha2_stab", $3); }; -o_gsa_logtrans_redform : LOGTRANS_REDFORM EQUAL INT_NUMBER { driver.option_num("logtrans_redform", $3); }; -o_gsa_threshold_redform : THRESHOLD_REDFORM EQUAL vec_value_w_inf { driver.option_num("threshold_redform",$3); }; -o_gsa_ksstat_redform : KSSTAT_REDFORM EQUAL non_negative_number { driver.option_num("ksstat_redform", $3); }; -o_gsa_alpha2_redform : ALPHA2_REDFORM EQUAL non_negative_number { driver.option_num("alpha2_redform", $3); }; -o_gsa_namendo : NAMENDO EQUAL '(' symbol_list_ext ')' { driver.option_symbol_list("namendo"); }; -o_gsa_namlagendo : NAMLAGENDO EQUAL '(' symbol_list_ext ')' { driver.option_symbol_list("namlagendo"); }; -o_gsa_namexo : NAMEXO EQUAL '(' symbol_list_ext ')' { driver.option_symbol_list("namexo"); }; -o_gsa_rmse : RMSE EQUAL INT_NUMBER { driver.option_num("rmse", $3); }; -o_gsa_lik_only : LIK_ONLY EQUAL INT_NUMBER { driver.option_num("lik_only", $3); }; -o_gsa_var_rmse : VAR_RMSE EQUAL '(' symbol_list_ext ')' { driver.option_symbol_list("var_rmse"); }; -o_gsa_pfilt_rmse : PFILT_RMSE EQUAL non_negative_number { driver.option_num("pfilt_rmse", $3); }; -o_gsa_istart_rmse : ISTART_RMSE EQUAL INT_NUMBER { driver.option_num("istart_rmse", $3); }; -o_gsa_alpha_rmse : ALPHA_RMSE EQUAL non_negative_number { driver.option_num("alpha_rmse", $3); }; -o_gsa_alpha2_rmse : ALPHA2_RMSE EQUAL non_negative_number { driver.option_num("alpha2_rmse", $3); }; -o_gsa_sample_file : GSA_SAMPLE_FILE EQUAL INT_NUMBER - { driver.option_num("gsa_sample_file", $3); } - | GSA_SAMPLE_FILE EQUAL filename - { driver.option_str("gsa_sample_file", $3); } - ; -o_gsa_neighborhood_width : NEIGHBORHOOD_WIDTH EQUAL non_negative_number { driver.option_num("neighborhood_width", $3); }; -o_gsa_pvalue_ks : PVALUE_KS EQUAL non_negative_number { driver.option_num("pvalue_ks", $3); }; -o_gsa_pvalue_corr : PVALUE_CORR EQUAL non_negative_number { driver.option_num("pvalue_corr", $3); }; -o_load_ident_files : LOAD_IDENT_FILES EQUAL INT_NUMBER { driver.option_num("load_ident_files", $3); } -o_useautocorr : USEAUTOCORR EQUAL INT_NUMBER { driver.option_num("useautocorr", $3); } -o_prior_mc : PRIOR_MC EQUAL INT_NUMBER { driver.option_num("prior_mc", $3); } -o_advanced : ADVANCED EQUAL signed_integer { driver.option_num("advanced", $3); } -o_max_dim_cova_group : MAX_DIM_COVA_GROUP EQUAL INT_NUMBER { driver.option_num("max_dim_cova_group", $3); } - -o_homotopy_mode : HOMOTOPY_MODE EQUAL INT_NUMBER {driver.option_num("homotopy_mode",$3); }; -o_homotopy_steps : HOMOTOPY_STEPS EQUAL INT_NUMBER {driver.option_num("homotopy_steps",$3); }; -o_homotopy_force_continue: HOMOTOPY_FORCE_CONTINUE EQUAL INT_NUMBER { driver.option_num("homotopy_force_continue",$3); }; -o_nocheck : NOCHECK {driver.option_num("steadystate.nocheck","1"); }; - -o_controlled_varexo : CONTROLLED_VAREXO EQUAL '(' symbol_list ')' { driver.option_symbol_list("controlled_varexo"); }; -o_parameter_set : PARAMETER_SET EQUAL PRIOR_MODE - { driver.option_str("parameter_set", "prior_mode"); } - | PARAMETER_SET EQUAL PRIOR_MEAN - { driver.option_str("parameter_set", "prior_mean"); } - | PARAMETER_SET EQUAL POSTERIOR_MEAN - { driver.option_str("parameter_set", "posterior_mean"); } - | PARAMETER_SET EQUAL POSTERIOR_MODE - { driver.option_str("parameter_set", "posterior_mode"); } - | PARAMETER_SET EQUAL POSTERIOR_MEDIAN - { driver.option_str("parameter_set", "posterior_median"); } - | PARAMETER_SET EQUAL MLE_MODE - { driver.option_str("parameter_set", "mle_mode"); } - | PARAMETER_SET EQUAL CALIBRATION - { driver.option_str("parameter_set", "calibration"); } - ; -o_nodecomposition : NODECOMPOSITION { driver.option_num("nodecomposition", "1"); }; -o_spectral_density : SPECTRAL_DENSITY { driver.option_num("SpectralDensity.trigger", "1"); }; -o_ms_drop : DROP EQUAL INT_NUMBER { driver.option_num("ms.drop", $3); }; -o_ms_mh_replic : MH_REPLIC EQUAL INT_NUMBER { driver.option_num("ms.mh_replic", $3); }; -o_freq : FREQ EQUAL INT_NUMBER - { driver.option_num("ms.freq",$3); } - | FREQ EQUAL MONTHLY - { driver.option_num("ms.freq","12"); } - | FREQ EQUAL QUARTERLY - { driver.option_num("ms.freq","4"); } - ; -o_initial_year : INITIAL_YEAR EQUAL INT_NUMBER {driver.option_num("ms.initial_year",$3); }; -o_initial_subperiod : INITIAL_SUBPERIOD EQUAL INT_NUMBER {driver.option_num("ms.initial_subperiod",$3); }; -o_final_year : FINAL_YEAR EQUAL INT_NUMBER {driver.option_num("ms.final_year",$3); }; -o_final_subperiod : FINAL_SUBPERIOD EQUAL INT_NUMBER {driver.option_num("ms.final_subperiod",$3); }; -o_data : DATA EQUAL filename { driver.option_str("ms.data", $3); }; -o_vlist : VLIST EQUAL INT_NUMBER {driver.option_num("ms.vlist",$3); }; -o_vlistlog : VLISTLOG EQUAL '(' symbol_list ')' {driver.option_symbol_list("ms.vlistlog"); }; -o_vlistper : VLISTPER EQUAL INT_NUMBER {driver.option_num("ms.vlistper",$3); }; -o_restriction_fname : RESTRICTION_FNAME EQUAL NAME - { - driver.warning("restriction_fname is now deprecated, and may be removed in a future version of Dynare. Use svar_identification instead."); - driver.option_str("ms.restriction_fname",$3); - } - | RESTRICTION_FNAME EQUAL UPPER_CHOLESKY - { - driver.warning("restriction_fname is now deprecated, and may be removed in a future version of Dynare. Use svar_identification instead."); - driver.option_str("ms.restriction_fname","upper_cholesky"); - } - | RESTRICTION_FNAME EQUAL LOWER_CHOLESKY - { - driver.warning("restriction_fname is now deprecated, and may be removed in a future version of Dynare. Use svar_identification instead."); - driver.option_str("ms.restriction_fname","lower_cholesky"); - } - ; -o_nlags : NLAGS EQUAL INT_NUMBER {driver.option_num("ms.nlags",$3); }; -o_cross_restrictions : CROSS_RESTRICTIONS {driver.option_num("ms.cross_restrictions","1"); }; -o_contemp_reduced_form : CONTEMP_REDUCED_FORM {driver.option_num("ms.contemp_reduced_form","1"); }; -o_real_pseudo_forecast : REAL_PSEUDO_FORECAST EQUAL INT_NUMBER {driver.option_num("ms.real_pseudo_forecast",$3); }; -o_no_bayesian_prior : NO_BAYESIAN_PRIOR {driver.option_num("ms.bayesian_prior","0"); }; -o_dummy_obs : DUMMY_OBS EQUAL INT_NUMBER {driver.option_num("ms.dummy_obs",$3); }; -o_nstates : NSTATES EQUAL INT_NUMBER {driver.option_num("ms.nstates",$3); }; -o_indxscalesstates : INDXSCALESSTATES EQUAL INT_NUMBER {driver.option_num("ms.indxscalesstates",$3); }; -o_alpha : ALPHA EQUAL non_negative_number {driver.option_num("ms.alpha",$3); }; -o_beta : BETA EQUAL non_negative_number {driver.option_num("ms.beta",$3); }; -o_gsig2_lmdm : GSIG2_LMDM EQUAL INT_NUMBER {driver.option_num("ms.gsig2_lmdm",$3); }; -o_specification : SPECIFICATION EQUAL SIMS_ZHA - {driver.option_num("ms.specification","1"); } - | SPECIFICATION EQUAL NONE - {driver.option_num("ms.specification","0"); } - ; -o_q_diag : Q_DIAG EQUAL non_negative_number {driver.option_num("ms.q_diag",$3); }; -o_flat_prior : FLAT_PRIOR EQUAL INT_NUMBER {driver.option_num("ms.flat_prior",$3); }; -o_ncsk : NCSK EQUAL INT_NUMBER {driver.option_num("ms.ncsk",$3); }; -o_nstd : NSTD EQUAL INT_NUMBER {driver.option_num("ms.nstd",$3); }; -o_ninv : NINV EQUAL INT_NUMBER {driver.option_num("ms.ninv",$3); }; -o_indxparr : INDXPARR EQUAL INT_NUMBER {driver.option_num("ms.indxparr",$3); }; -o_indxovr : INDXOVR EQUAL INT_NUMBER {driver.option_num("ms.indxovr",$3); }; -o_aband : ABAND EQUAL INT_NUMBER {driver.option_num("ms.aband",$3); }; -o_indxap : INDXAP EQUAL INT_NUMBER {driver.option_num("ms.indxap",$3); }; -o_apband : APBAND EQUAL INT_NUMBER {driver.option_num("ms.apband",$3); }; -o_indximf : INDXIMF EQUAL INT_NUMBER {driver.option_num("ms.indximf",$3); }; -o_indxfore : INDXFORE EQUAL INT_NUMBER {driver.option_num("ms.indxfore",$3); }; -o_foreband : FOREBAND EQUAL INT_NUMBER {driver.option_num("ms.foreband",$3); }; -o_indxgforhat : INDXGFOREHAT EQUAL INT_NUMBER {driver.option_num("ms.indxgforehat",$3); }; -o_indxgimfhat : INDXGIMFHAT EQUAL INT_NUMBER {driver.option_num("ms.indxgimfhat",$3); }; -o_indxestima : INDXESTIMA EQUAL INT_NUMBER {driver.option_num("ms.indxestima",$3); }; -o_indxgdls : INDXGDLS EQUAL INT_NUMBER {driver.option_num("ms.indxgdls",$3); }; -o_eq_ms : EQ_MS EQUAL INT_NUMBER {driver.option_num("ms.eq_ms",$3); }; -o_cms : CMS EQUAL INT_NUMBER {driver.option_num("ms.cms",$3); }; -o_ncms : NCMS EQUAL INT_NUMBER {driver.option_num("ms.ncms",$3); }; -o_eq_cms : EQ_CMS EQUAL INT_NUMBER {driver.option_num("ms.eq_cms",$3); }; -o_tlindx : TLINDX EQUAL INT_NUMBER {driver.option_num("ms.tlindx",$3); }; -o_tlnumber : TLNUMBER EQUAL INT_NUMBER {driver.option_num("ms.tlnumber",$3); }; -o_cnum : CNUM EQUAL INT_NUMBER {driver.option_num("ms.cnum",$3); }; -o_k_order_solver : K_ORDER_SOLVER {driver.option_num("k_order_solver","1"); }; -o_pruning : PRUNING { driver.option_num("pruning", "1"); }; -o_chain : CHAIN EQUAL INT_NUMBER { driver.option_num("ms.chain",$3); }; -o_restrictions : RESTRICTIONS EQUAL vec_of_vec_value - { driver.option_num("ms.restrictions",$3); } - ; -o_duration : DURATION EQUAL non_negative_number - { driver.option_num("ms.duration",$3); } - | DURATION EQUAL vec_value_w_inf - { driver.option_num("ms.duration",$3); } - ; -o_number_of_regimes : NUMBER_OF_REGIMES EQUAL INT_NUMBER { driver.option_num("ms.number_of_regimes",$3); }; -o_number_of_lags : NUMBER_OF_LAGS EQUAL INT_NUMBER { driver.option_num("ms.number_of_lags",$3); }; -o_parameters : PARAMETERS EQUAL '[' symbol_list ']' { driver.option_symbol_list("ms.parameters"); }; -o_coefficients : COEFFICIENTS { driver.option_str("ms.coefficients","svar_coefficients"); }; -o_variances : VARIANCES { driver.option_str("ms.variances","svar_variances"); }; -o_equations : EQUATIONS EQUAL vec_int - { driver.option_vec_int("ms.equations",$3); } - | EQUATIONS EQUAL vec_int_number - { driver.option_vec_int("ms.equations",$3); } - ; -o_silent_optimizer : SILENT_OPTIMIZER { driver.option_num("silent_optimizer", "1"); }; -o_instruments : INSTRUMENTS EQUAL '(' symbol_list ')' {driver.option_symbol_list("instruments"); }; - -o_ext_func_name : EXT_FUNC_NAME EQUAL filename { driver.external_function_option("name", $3); }; -o_ext_func_nargs : EXT_FUNC_NARGS EQUAL INT_NUMBER { driver.external_function_option("nargs",$3); }; -o_first_deriv_provided : FIRST_DERIV_PROVIDED EQUAL filename - { driver.external_function_option("first_deriv_provided", $3); } - | FIRST_DERIV_PROVIDED - { driver.external_function_option("first_deriv_provided", ""); } - ; -o_second_deriv_provided : SECOND_DERIV_PROVIDED EQUAL filename - { driver.external_function_option("second_deriv_provided", $3); } - | SECOND_DERIV_PROVIDED - { driver.external_function_option("second_deriv_provided", ""); } - ; -o_filter_covariance : FILTER_COVARIANCE - { driver.option_num("filter_covariance","1");} - ; -o_filter_decomposition : FILTER_DECOMPOSITION - { driver.option_num("filter_decomposition","1");} - ; -o_smoothed_state_uncertainty : SMOOTHED_STATE_UNCERTAINTY - { driver.option_num("smoothed_state_uncertainty","1");} - ; -o_selected_variables_only : SELECTED_VARIABLES_ONLY - { driver.option_num("selected_variables_only","1");} - ; -o_cova_compute : COVA_COMPUTE EQUAL INT_NUMBER - { driver.option_num("cova_compute",$3);} - ; -o_output_file_tag : OUTPUT_FILE_TAG EQUAL filename {driver.option_str("ms.output_file_tag", $3); }; -o_file_tag : FILE_TAG EQUAL filename { driver.option_str("ms.file_tag", $3); }; -o_no_create_init : NO_CREATE_INIT { driver.option_num("ms.create_init", "0"); }; -o_simulation_file_tag : SIMULATION_FILE_TAG EQUAL filename { driver.option_str("ms.simulation_file_tag", $3); }; -o_coefficients_prior_hyperparameters : COEFFICIENTS_PRIOR_HYPERPARAMETERS EQUAL vec_value - { driver.option_num("ms.coefficients_prior_hyperparameters",$3); }; -o_convergence_starting_value : CONVERGENCE_STARTING_VALUE EQUAL non_negative_number - { driver.option_num("ms.convergence_starting_value",$3); }; -o_convergence_ending_value : CONVERGENCE_ENDING_VALUE EQUAL non_negative_number - { driver.option_num("ms.convergence_ending_value",$3); }; -o_convergence_increment_value : CONVERGENCE_INCREMENT_VALUE EQUAL non_negative_number - { driver.option_num("ms.convergence_increment_value",$3); }; -o_max_iterations_starting_value : MAX_ITERATIONS_STARTING_VALUE EQUAL INT_NUMBER - { driver.option_num("ms.max_iterations_starting_value",$3); }; -o_max_iterations_increment_value : MAX_ITERATIONS_INCREMENT_VALUE EQUAL non_negative_number - { driver.option_num("ms.max_iterations_increment_value",$3); }; -o_max_block_iterations : MAX_BLOCK_ITERATIONS EQUAL INT_NUMBER - { driver.option_num("ms.max_block_iterations",$3); }; -o_max_repeated_optimization_runs : MAX_REPEATED_OPTIMIZATION_RUNS EQUAL INT_NUMBER - { driver.option_num("ms.max_repeated_optimization_runs",$3); }; -o_function_convergence_criterion : FUNCTION_CONVERGENCE_CRITERION EQUAL non_negative_number - { driver.option_num("ms.function_convergence_criterion",$3); }; -o_parameter_convergence_criterion : PARAMETER_CONVERGENCE_CRITERION EQUAL non_negative_number - { driver.option_num("ms.parameter_convergence_criterion",$3); }; -o_number_of_large_perturbations : NUMBER_OF_LARGE_PERTURBATIONS EQUAL INT_NUMBER - { driver.option_num("ms.number_of_large_perturbations",$3); }; -o_number_of_small_perturbations : NUMBER_OF_SMALL_PERTURBATIONS EQUAL INT_NUMBER - { driver.option_num("ms.number_of_small_perturbations",$3); }; -o_number_of_posterior_draws_after_perturbation : NUMBER_OF_POSTERIOR_DRAWS_AFTER_PERTURBATION EQUAL INT_NUMBER - { driver.option_num("ms.number_of_posterior_draws_after_perturbation",$3); }; -o_max_number_of_stages : MAX_NUMBER_OF_STAGES EQUAL INT_NUMBER - { driver.option_num("ms.max_number_of_stages",$3); }; -o_random_function_convergence_criterion : RANDOM_FUNCTION_CONVERGENCE_CRITERION EQUAL non_negative_number - { driver.option_num("ms.random_function_convergence_criterion",$3); }; -o_random_parameter_convergence_criterion : RANDOM_PARAMETER_CONVERGENCE_CRITERION EQUAL non_negative_number - { driver.option_num("ms.random_parameter_convergence_criterion",$3); }; -o_thinning_factor : THINNING_FACTOR EQUAL INT_NUMBER { driver.option_num("ms.thinning_factor",$3); }; -o_adaptive_mh_draws : ADAPTIVE_MH_DRAWS EQUAL INT_NUMBER { driver.option_num("ms.adaptive_mh_draws",$3); }; -o_save_draws : SAVE_DRAWS { driver.option_num("ms.save_draws","1"); }; -o_proposal_draws : PROPOSAL_DRAWS EQUAL INT_NUMBER { driver.option_num("ms.proposal_draws",$3); }; -o_use_mean_center : USE_MEAN_CENTER { driver.option_num("ms.use_mean_center","1"); }; -o_proposal_type : PROPOSAL_TYPE EQUAL INT_NUMBER { driver.option_num("ms.proposal_type",$3); } -o_proposal_lower_bound : PROPOSAL_LOWER_BOUND EQUAL signed_number { driver.option_num("ms.proposal_lower_bound",$3); } -o_proposal_upper_bound : PROPOSAL_UPPER_BOUND EQUAL signed_number { driver.option_num("ms.proposal_upper_bound",$3); } -o_parameter_uncertainty : PARAMETER_UNCERTAINTY { driver.option_num("ms.parameter_uncertainty","1"); }; -o_horizon : HORIZON EQUAL INT_NUMBER { driver.option_num("ms.horizon",$3); }; -o_filtered_probabilities : FILTERED_PROBABILITIES { driver.option_num("ms.filtered_probabilities","1"); }; -o_real_time_smoothed : REAL_TIME_SMOOTHED { driver.option_num("ms.real_time_smoothed_probabilities","1"); }; -o_no_error_bands : NO_ERROR_BANDS { driver.option_num("ms.error_bands","0"); }; -o_error_band_percentiles : ERROR_BAND_PERCENTILES EQUAL vec_value { driver.option_num("ms.percentiles",$3); }; -o_shock_draws : SHOCK_DRAWS EQUAL INT_NUMBER { driver.option_num("ms.shock_draws",$3); }; -o_shocks_per_parameter : SHOCKS_PER_PARAMETER EQUAL INT_NUMBER { driver.option_num("ms.shocks_per_parameter",$3); }; -o_free_parameters : FREE_PARAMETERS EQUAL vec_value { driver.option_num("ms.free_parameters",$3); }; -o_median : MEDIAN { driver.option_num("ms.median","1"); } - | MEDIAN EQUAL signed_number { driver.option_num("median", $3); }; -o_regimes : REGIMES { driver.option_num("ms.regimes","1"); }; -o_regime : REGIME EQUAL INT_NUMBER { driver.option_num("ms.regime",$3); }; -o_data_obs_nbr : DATA_OBS_NBR EQUAL INT_NUMBER { driver.option_num("ms.forecast_data_obs",$3); }; -o_discretionary_tol: DISCRETIONARY_TOL EQUAL non_negative_number { driver.option_num("discretionary_tol",$3); }; -o_analytic_derivation : ANALYTIC_DERIVATION { driver.option_num("analytic_derivation", "1"); } -o_analytic_derivation_mode : ANALYTIC_DERIVATION_MODE EQUAL signed_number { driver.option_num("analytic_derivation_mode", $3); } -o_endogenous_prior : ENDOGENOUS_PRIOR { driver.option_num("endogenous_prior", "1"); } -o_use_univariate_filters_if_singularity_is_detected : USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED EQUAL INT_NUMBER { driver.option_num("use_univariate_filters_if_singularity_is_detected", $3); } -o_mcmc_jumping_covariance : MCMC_JUMPING_COVARIANCE EQUAL HESSIAN - { driver.option_str("MCMC_jumping_covariance", $3); } | MCMC_JUMPING_COVARIANCE EQUAL PRIOR_VARIANCE - { driver.option_str("MCMC_jumping_covariance", $3); } - | MCMC_JUMPING_COVARIANCE EQUAL IDENTITY_MATRIX - { driver.option_str("MCMC_jumping_covariance", $3); } - | MCMC_JUMPING_COVARIANCE EQUAL filename - { driver.option_str("MCMC_jumping_covariance", $3); } - ; -o_rescale_prediction_error_covariance : RESCALE_PREDICTION_ERROR_COVARIANCE { driver.option_num("rescale_prediction_error_covariance", "true"); }; -o_use_penalized_objective_for_hessian : USE_PENALIZED_OBJECTIVE_FOR_HESSIAN { driver.option_num("hessian.use_penalized_objective","true"); }; -o_irf_plot_threshold : IRF_PLOT_THRESHOLD EQUAL non_negative_number { driver.option_num("impulse_responses.plot_threshold", $3); }; -o_dr_display_tol : DR_DISPLAY_TOL EQUAL non_negative_number { driver.option_num("dr_display_tol", $3); }; -o_consider_all_endogenous : CONSIDER_ALL_ENDOGENOUS { driver.option_str("endo_vars_for_moment_computations_in_estimation", "all_endogenous_variables"); }; -o_consider_only_observed : CONSIDER_ONLY_OBSERVED { driver.option_str("endo_vars_for_moment_computations_in_estimation", "only_observed_variables"); }; -o_no_homotopy : NO_HOMOTOPY { driver.option_num("no_homotopy", "1"); }; - -o_infile : INFILE EQUAL filename { driver.option_str("infile", $3); }; -o_invars : INVARS EQUAL '(' symbol_list ')' { driver.option_symbol_list("invars"); }; -o_period : PERIOD EQUAL INT_NUMBER { driver.option_num("period", $3); }; -o_outfile : OUTFILE EQUAL filename { driver.option_str("outfile", $3); }; -o_outvars : OUTVARS EQUAL '(' symbol_list ')' { driver.option_symbol_list("outvars"); }; -o_lmmcp : LMMCP {driver.option_num("lmmcp.status", "1"); }; -o_occbin : OCCBIN {driver.option_num("occbin", "1"); }; -o_function : FUNCTION EQUAL filename { driver.option_str("function", $3); }; -o_sampling_draws : SAMPLING_DRAWS EQUAL INT_NUMBER { driver.option_num("sampling_draws",$3); }; -o_use_shock_groups : USE_SHOCK_GROUPS { driver.option_str("plot_shock_decomp.use_shock_groups","default"); } - | USE_SHOCK_GROUPS EQUAL symbol { driver.option_str("plot_shock_decomp.use_shock_groups", $3); } - ; -o_colormap : COLORMAP EQUAL symbol { driver.option_num("plot_shock_decomp.colormap",$3); }; - -o_gmm_order : ORDER EQUAL INT_NUMBER { driver.option_num("gmm.order", $3); }; -o_smm_order : ORDER EQUAL INT_NUMBER { driver.option_num("smm.order", $3); }; -o_gmm_centered_moments : CENTERED_MOMENTS { driver.option_num("gmm.centered_moments", "1"); }; -o_smm_centered_moments : CENTERED_MOMENTS { driver.option_num("smm.centered_moments", "1"); }; -o_gmm_autolag : AUTOLAG EQUAL vec_int - { driver.option_vec_int("gmm.autolag", $3); } - | AUTOLAG EQUAL vec_int_number - { driver.option_vec_int("gmm.autolag", $3); } - ; -o_smm_autolag : AUTOLAG EQUAL vec_int - { driver.option_vec_int("smm.autolag", $3); } - | AUTOLAG EQUAL vec_int_number - { driver.option_vec_int("smm.autolag", $3); } - ; -o_gmm_recursive_order_estimation : RECURSIVE_ORDER_ESTIMATION { driver.option_num("gmm.recursive_estimation", "1"); }; -o_smm_recursive_order_estimation : RECURSIVE_ORDER_ESTIMATION { driver.option_num("smm.recursive_estimation", "1"); }; -o_gmm_bartlett_kernel_lag : BARTLETT_KERNEL_LAG EQUAL INT_NUMBER { driver.option_num("gmm.qLag", $3); }; -o_smm_bartlett_kernel_lag : BARTLETT_KERNEL_LAG EQUAL INT_NUMBER { driver.option_num("smm.qLag", $3); }; -o_gmm_weighting_matrix : WEIGHTING_MATRIX EQUAL OPTIMAL - { driver.option_str("gmm.weighting_matrix", $3); } - | WEIGHTING_MATRIX EQUAL IDENTITY_MATRIX - { driver.option_str("gmm.weighting_matrix", $3); } - | WEIGHTING_MATRIX EQUAL DIAGONAL - { driver.option_str("gmm.weighting_matrix", $3); } - | WEIGHTING_MATRIX EQUAL filename - { driver.option_str("gmm.weighting_matrix", $3); } - ; -o_smm_weighting_matrix : WEIGHTING_MATRIX EQUAL OPTIMAL - { driver.option_str("smm.weighting_matrix", $3); } - | WEIGHTING_MATRIX EQUAL IDENTITY_MATRIX - { driver.option_str("smm.weighting_matrix", $3); } - | WEIGHTING_MATRIX EQUAL DIAGONAL - { driver.option_str("smm.weighting_matrix", $3); } - | WEIGHTING_MATRIX EQUAL filename - { driver.option_str("smm.weighting_matrix", $3); } - ; -o_gmm_penalized_estimator : PENALIZED_ESTIMATOR { driver.option_num("gmm.penalized_estimator", "1"); }; -o_smm_penalized_estimator : PENALIZED_ESTIMATOR { driver.option_num("smm.penalized_estimator", "1"); }; -o_gmm_verbose : VERBOSE { driver.option_num("gmm.verbose", "1"); }; -o_smm_verbose : VERBOSE { driver.option_num("smm.verbose", "1"); }; - -o_smm_simulation_multiple : SIMULATION_MULTIPLE EQUAL INT_NUMBER { driver.option_num("smm.simulation_multiple", $3); }; -o_smm_drop : DROP EQUAL INT_NUMBER { driver.option_num("smm.drop", $3); }; -o_smm_seed : SEED EQUAL INT_NUMBER { driver.option_num("smm.seed", $3); }; -o_smm_bounded_shock_support : BOUNDED_SHOCK_SUPPORT { driver.option_num("smm.bounded_support", "1"); }; - -o_analytical_girf : ANALYTICAL_GIRF { driver.option_num("irf_opt.analytical_GIRF", "1"); }; -o_irf_in_percent : IRF_IN_PERCENT { driver.option_num("irf_opt.percent", "1"); }; -o_emas_girf : EMAS_GIRF { driver.option_num("irf_opt.ergodic_mean_irf", "1"); }; -o_emas_drop : EMAS_DROP EQUAL INT_NUMBER { driver.option_num("irf_opt.EM.drop", $3); }; -o_emas_tolf : EMAS_TOLF EQUAL non_negative_number { driver.option_num("irf_opt.EM.tolf", $3); }; -o_emas_max_iter : EMAS_MAX_ITER EQUAL INT_NUMBER { driver.option_num("irf_opt.EM.iter", $3); }; - -range : symbol ':' symbol - { - $1->append(":"); - $1->append(*$3); - delete $3; - $$ = $1; - }; - -integer_range : INT_NUMBER ':' INT_NUMBER - { - $1->append(":"); - $1->append(*$3); - delete $3; - $$ = $1; - }; - -signed_integer_range : signed_integer ':' signed_integer - { - $1->append(":"); - $1->append(*$3); - delete $3; - $$ = $1; - } - | MINUS '(' signed_integer ':' signed_integer ')' - { - $3->insert(0, "-("); - $3->append(":"); - $3->append(*$5); - delete $5; - $3->append(")"); - $$ = $3; - }; - -vec_int_number : INT_NUMBER { $$ = new vector(); $$->push_back(atoi((*$1).c_str())); delete $1; }; - -vec_int_elem : vec_int_number - | INT_NUMBER ':' INT_NUMBER - { - $$ = new vector(); - for(int i=atoi((*$1).c_str()); i<=atoi((*$3).c_str()); i++) - $$->push_back(i); - delete $1; - delete $3; - } - ; - -vec_int_1 : '[' vec_int_elem - { $$ = $2;} - | '[' COMMA vec_int_elem - { $$ = $3;} - | vec_int_1 vec_int_elem - { - $$ = $1; - for (vector::const_iterator it=$2->begin(); - it!=$2->end(); it++) - $1->push_back(*it); - delete $2; - } - | vec_int_1 COMMA vec_int_elem - { - $$ = $1; - for (vector::const_iterator it=$3->begin(); - it!=$3->end(); it++) - $1->push_back(*it); - delete $3; - } - ; - -vec_int : vec_int_1 ']' - { $$ = $1; } - | vec_int_1 COMMA ']' - { $$ = $1; } - ; - -vec_value_1 : '[' signed_number { $2->insert(0,"["); $$ = $2; } - | '[' COMMA signed_number { $3->insert(0,"["); $$ = $3; } - | vec_value_1 signed_number - { - $1->append(" "); - $1->append(*$2); - delete $2; - $$ = $1; - } - | vec_value_1 COMMA signed_number - { - $1->append(" "); - $1->append(*$3); - delete $3; - $$ = $1; - } - ; - -vec_value : vec_value_1 ']' { $1->append("]"); $$ = $1; } - | vec_value_1 COMMA ']' { $1->append("]"); $$ = $1; } - ; - -vec_value_list : vec_value_list COMMA vec_value - { - $1->append(","); - $1->append(*$3); - delete $3; - $$ = $1; - } - | vec_value - { $$ = $1; } - ; - -vec_of_vec_value : '[' vec_value_list ']' { $$ = $2; } - | vec_value { $$ = $1; }; - -vec_value_1_w_inf : '[' signed_number_w_inf - { $2->insert(0, "["); $$ = $2;} - | vec_value_1_w_inf signed_number_w_inf - { - $1->append(" "); - $1->append(*$2); - delete $2; - $$ = $1; - } - ; - -vec_value_w_inf : vec_value_1_w_inf ']' { $1->append("]"); $$ = $1; }; - -symbol : NAME - | ALPHA - | BETA - | NINV - | ABAND - | CMS - | NCMS - | CNUM - | GAMMA - | INV_GAMMA - | INV_GAMMA1 - | INV_GAMMA2 - | NORMAL - | UNIFORM - | EPS - | PDF - | FIG - | NONE - | DR - | PRIOR - ; -%% - -void -Dynare::parser::error(const Dynare::parser::location_type &l, - const string &m) -{ - driver.error(l, m); -} diff --git a/preprocessor/DynareFlex.ll b/preprocessor/DynareFlex.ll deleted file mode 100644 index db43397d6..000000000 --- a/preprocessor/DynareFlex.ll +++ /dev/null @@ -1,1051 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - - -%{ -using namespace std; - -#include -#include "ParsingDriver.hh" - -// Announce to Flex the prototype we want for lexing function -#define YY_DECL \ - Dynare::parser::token_type \ - DynareFlex::lex(Dynare::parser::semantic_type *yylval, \ - Dynare::parser::location_type *yylloc, \ - ParsingDriver &driver) - -// Shortcut to access tokens defined by Bison -typedef Dynare::parser::token token; - -/* By default yylex returns int, we use token_type. - Unfortunately yyterminate by default returns 0, which is - not of token_type. */ -#define yyterminate() return Dynare::parser::token_type (0); - -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; -%} - -%option c++ - -%option prefix="Dynare" - -%option case-insensitive noyywrap nounput batch debug never-interactive - - /* NB: if new start conditions are defined, add them in the line for <> */ -%x COMMENT -%x DYNARE_STATEMENT -%x DYNARE_BLOCK -%x VERBATIM_BLOCK -%x NATIVE -%x NATIVE_COMMENT -%x DATES_STATEMENT -%x LINE1 -%x LINE2 -%x LINE3 - -%{ -// Increments location counter for every token read -#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])) - -%% - /* Code put at the beginning of yylex() */ -%{ - // Reset location before reading token - yylloc->step(); -%} - - /* Rules for matching $line directives */ -<*>^@#line\ \" { line_caller = YYSTATE; BEGIN(LINE1); } -[^\"]* { - filename = string(yytext); - BEGIN(LINE2); - } -\" BEGIN(LINE3); -[0-9]+ { - yylloc->begin.line = yylloc->end.line = atoi(yytext) - 1; - BEGIN(line_caller); - } - - /* spaces, tabs and carriage returns are ignored */ -[ \t\r\f]+ { yylloc->step(); } -[\n]+ { yylloc->step(); } - - /* Comments */ -["%"].* -["/"]["/"].* -"/*" {comment_caller = YY_START; BEGIN COMMENT;} - -"*/" {BEGIN comment_caller;} -. - - /* Begin of a Dynare statement */ -var {BEGIN DYNARE_STATEMENT; return token::VAR;} -varexo {BEGIN DYNARE_STATEMENT; return token::VAREXO;} -varexo_det {BEGIN DYNARE_STATEMENT; return token::VAREXO_DET;} -trend_var {BEGIN DYNARE_STATEMENT; return token::TREND_VAR;} -log_trend_var {BEGIN DYNARE_STATEMENT; return token::LOG_TREND_VAR;} -predetermined_variables {BEGIN DYNARE_STATEMENT; return token::PREDETERMINED_VARIABLES;} -parameters {BEGIN DYNARE_STATEMENT; return token::PARAMETERS;} -model_local_variable {BEGIN DYNARE_STATEMENT; return token::MODEL_LOCAL_VARIABLE;} -periods {BEGIN DYNARE_STATEMENT; return token::PERIODS;} -model_info {BEGIN DYNARE_STATEMENT; return token::MODEL_INFO;} -estimation {BEGIN DYNARE_STATEMENT; return token::ESTIMATION;} -set_time {BEGIN DYNARE_STATEMENT; return token::SET_TIME;} -data {BEGIN DYNARE_STATEMENT; return token::DATA;} -varobs {BEGIN DYNARE_STATEMENT; return token::VAROBS;} -unit_root_vars {BEGIN DYNARE_STATEMENT; return token::UNIT_ROOT_VARS;} -rplot {BEGIN DYNARE_STATEMENT; return token::RPLOT;} -osr_params {BEGIN DYNARE_STATEMENT; return token::OSR_PARAMS;} -osr {BEGIN DYNARE_STATEMENT; return token::OSR;} -dynatype {BEGIN DYNARE_STATEMENT; return token::DYNATYPE;} -dynasave {BEGIN DYNARE_STATEMENT; return token::DYNASAVE;} -model_comparison {BEGIN DYNARE_STATEMENT; return token::MODEL_COMPARISON;} -change_type {BEGIN DYNARE_STATEMENT; return token::CHANGE_TYPE;} -load_params_and_steady_state {BEGIN DYNARE_STATEMENT; return token::LOAD_PARAMS_AND_STEADY_STATE;} -save_params_and_steady_state {BEGIN DYNARE_STATEMENT; return token::SAVE_PARAMS_AND_STEADY_STATE;} -write_latex_dynamic_model {BEGIN DYNARE_STATEMENT; return token::WRITE_LATEX_DYNAMIC_MODEL;} -write_latex_static_model {BEGIN DYNARE_STATEMENT; return token::WRITE_LATEX_STATIC_MODEL;} -write_latex_original_model {BEGIN DYNARE_STATEMENT; return token::WRITE_LATEX_ORIGINAL_MODEL;} -write_latex_steady_state_model {BEGIN DYNARE_STATEMENT; return token::WRITE_LATEX_STEADY_STATE_MODEL;} - -steady {BEGIN DYNARE_STATEMENT; return token::STEADY;} -check {BEGIN DYNARE_STATEMENT; return token::CHECK;} -simul {BEGIN DYNARE_STATEMENT; return token::SIMUL;} -stoch_simul {BEGIN DYNARE_STATEMENT; return token::STOCH_SIMUL;} -dsample {BEGIN DYNARE_STATEMENT; return token::DSAMPLE;} -Sigma_e {BEGIN DYNARE_STATEMENT; sigma_e = 1; return token::SIGMA_E;} -planner_objective {BEGIN DYNARE_STATEMENT; return token::PLANNER_OBJECTIVE;} -ramsey_model {BEGIN DYNARE_STATEMENT; return token::RAMSEY_MODEL;} -ramsey_policy {BEGIN DYNARE_STATEMENT; return token::RAMSEY_POLICY;} -discretionary_policy {BEGIN DYNARE_STATEMENT; return token::DISCRETIONARY_POLICY;} -identification {BEGIN DYNARE_STATEMENT; return token::IDENTIFICATION;} - -bvar_density {BEGIN DYNARE_STATEMENT; return token::BVAR_DENSITY; } -bvar_forecast {BEGIN DYNARE_STATEMENT; return token::BVAR_FORECAST; } -dynare_sensitivity {BEGIN DYNARE_STATEMENT; return token::DYNARE_SENSITIVITY;} -initval_file {BEGIN DYNARE_STATEMENT; return token::INITVAL_FILE;} -histval_file {BEGIN DYNARE_STATEMENT; return token::HISTVAL_FILE;} -forecast {BEGIN DYNARE_STATEMENT; return token::FORECAST;} -shock_decomposition {BEGIN DYNARE_STATEMENT; return token::SHOCK_DECOMPOSITION;} -realtime_shock_decomposition {BEGIN DYNARE_STATEMENT; return token::REALTIME_SHOCK_DECOMPOSITION;} -plot_shock_decomposition {BEGIN DYNARE_STATEMENT; return token::PLOT_SHOCK_DECOMPOSITION;} -initial_condition_decomposition {BEGIN DYNARE_STATEMENT; return token::INITIAL_CONDITION_DECOMPOSITION;} -sbvar {BEGIN DYNARE_STATEMENT; return token::SBVAR;} -ms_estimation {BEGIN DYNARE_STATEMENT; return token::MS_ESTIMATION;} -ms_simulation {BEGIN DYNARE_STATEMENT; return token::MS_SIMULATION;} -ms_compute_mdd {BEGIN DYNARE_STATEMENT; return token::MS_COMPUTE_MDD;} -ms_compute_probabilities {BEGIN DYNARE_STATEMENT; return token::MS_COMPUTE_PROBABILITIES;} -ms_forecast {BEGIN DYNARE_STATEMENT; return token::MS_FORECAST;} -ms_irf {BEGIN DYNARE_STATEMENT; return token::MS_IRF;} -ms_variance_decomposition {BEGIN DYNARE_STATEMENT; return token::MS_VARIANCE_DECOMPOSITION;} -conditional_forecast {BEGIN DYNARE_STATEMENT; return token::CONDITIONAL_FORECAST;} -plot_conditional_forecast {BEGIN DYNARE_STATEMENT; return token::PLOT_CONDITIONAL_FORECAST;} -gmm_estimation {BEGIN DYNARE_STATEMENT; return token::GMM_ESTIMATION;} -smm_estimation {BEGIN DYNARE_STATEMENT; return token::SMM_ESTIMATION;} - -markov_switching {BEGIN DYNARE_STATEMENT; return token::MARKOV_SWITCHING;} -svar {BEGIN DYNARE_STATEMENT; return token::SVAR;} -svar_global_identification_check {BEGIN DYNARE_STATEMENT; return token::SVAR_GLOBAL_IDENTIFICATION_CHECK;} -external_function {BEGIN DYNARE_STATEMENT; return token::EXTERNAL_FUNCTION;} - /* End of a Dynare statement */ -calib_smoother { BEGIN DYNARE_STATEMENT; return token::CALIB_SMOOTHER; } -model_diagnostics {BEGIN DYNARE_STATEMENT; return token::MODEL_DIAGNOSTICS;} -extended_path {BEGIN DYNARE_STATEMENT; return token::EXTENDED_PATH;} -smoother2histval {BEGIN DYNARE_STATEMENT; return token::SMOOTHER2HISTVAL;} -perfect_foresight_setup {BEGIN DYNARE_STATEMENT; return token::PERFECT_FORESIGHT_SETUP;} -perfect_foresight_solver {BEGIN DYNARE_STATEMENT; return token::PERFECT_FORESIGHT_SOLVER;} - -; { - if (!sigma_e) - BEGIN INITIAL; - return Dynare::parser::token_type (yytext[0]); -} - - - /* Begin of a Dynare block */ -model {BEGIN DYNARE_BLOCK; return token::MODEL;} -steady_state_model {BEGIN DYNARE_BLOCK; return token::STEADY_STATE_MODEL;} -initval {BEGIN DYNARE_BLOCK; return token::INITVAL;} -endval {BEGIN DYNARE_BLOCK; return token::ENDVAL;} -histval {BEGIN DYNARE_BLOCK; return token::HISTVAL;} -shocks {BEGIN DYNARE_BLOCK; return token::SHOCKS;} -shock_groups {BEGIN DYNARE_BLOCK; return token::SHOCK_GROUPS;} -mshocks {BEGIN DYNARE_BLOCK; return token::MSHOCKS;} -estimated_params {BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS;} - /* priors is an alias for estimated_params */ -priors {BEGIN DYNARE_BLOCK;return token::ESTIMATED_PARAMS;} -estimated_params_init {BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS_INIT;} -estimated_params_bounds {BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS_BOUNDS;} -osr_params_bounds {BEGIN DYNARE_BLOCK; return token::OSR_PARAMS_BOUNDS;} -observation_trends {BEGIN DYNARE_BLOCK; return token::OBSERVATION_TRENDS;} -optim_weights {BEGIN DYNARE_BLOCK; return token::OPTIM_WEIGHTS;} -homotopy_setup {BEGIN DYNARE_BLOCK; return token::HOMOTOPY_SETUP;} -conditional_forecast_paths {BEGIN DYNARE_BLOCK; return token::CONDITIONAL_FORECAST_PATHS;} -svar_identification {BEGIN DYNARE_BLOCK; return token::SVAR_IDENTIFICATION;} -moment_calibration {BEGIN DYNARE_BLOCK; return token::MOMENT_CALIBRATION;} -irf_calibration {BEGIN DYNARE_BLOCK; return token::IRF_CALIBRATION;} -ramsey_constraints {BEGIN DYNARE_BLOCK; return token::RAMSEY_CONSTRAINTS;} -generate_irfs {BEGIN DYNARE_BLOCK; return token::GENERATE_IRFS;} - - /* For the semicolon after an "end" keyword */ -; {return Dynare::parser::token_type (yytext[0]);} - - /* End of a Dynare block */ -end {BEGIN INITIAL; return token::END;} - -subsamples {return token::SUBSAMPLES;} -options {return token::OPTIONS;} -prior { - yylval->string_val = new string(yytext); - return token::PRIOR; -} -std {BEGIN DYNARE_STATEMENT; return token::STD;} -corr {BEGIN DYNARE_STATEMENT; return token::CORR;} -function {return token::FUNCTION;} -sampling_draws {return token::SAMPLING_DRAWS;} -prior_function {BEGIN DYNARE_STATEMENT; return token::PRIOR_FUNCTION;} -posterior_function {BEGIN DYNARE_STATEMENT; return token::POSTERIOR_FUNCTION;} - - /* Inside of a Dynare statement */ -{DATE} { - char *yycopy = strdup(yytext); - 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 ); - } -${DATE} { yylloc->step(); -#if (YY_FLEX_MAJOR_VERSION > 2) || (YY_FLEX_MAJOR_VERSION == 2 && YY_FLEX_MINOR_VERSION >= 6) - yyout << yytext + 1; -#else - *yyout << yytext + 1; -#endif - } -dates {dates_parens_nb=0; BEGIN DATES_STATEMENT; yylval->string_val = new string("dates");} -file {return token::FILE;} -datafile {return token::DATAFILE;} -dirname {return token::DIRNAME;} -nobs {return token::NOBS;} -last_obs {return token::LAST_OBS;} -first_obs {return token::FIRST_OBS;} -mean {return token::MEAN;} -stdev {return token::STDEV;} -truncate {return token::TRUNCATE;} -domain {return token::DOMAINN;} -variance {return token::VARIANCE;} -mode {return token::MODE;} -interval {return token::INTERVAL;} -shape {return token::SHAPE;} -shift {return token::SHIFT;} -bounds {return token::BOUNDS;} -init {return token::INIT;} -jscale {return token::JSCALE;} -prefilter {return token::PREFILTER;} -presample {return token::PRESAMPLE;} -lik_algo {return token::LIK_ALGO;} -lik_init {return token::LIK_INIT;} -taper_steps {return token::TAPER_STEPS;} -geweke_interval {return token::GEWEKE_INTERVAL;} -raftery_lewis_qrs {return token::RAFTERY_LEWIS_QRS;} -raftery_lewis_diagnostics {return token::RAFTERY_LEWIS_DIAGNOSTICS;} -graph {return token::GRAPH;} -nograph {return token::NOGRAPH;} -posterior_graph {return token::POSTERIOR_GRAPH;} -posterior_nograph {return token::POSTERIOR_NOGRAPH;} -nodisplay {return token::NODISPLAY;} -graph_format {return token::GRAPH_FORMAT;} -eps {yylval->string_val = new string(yytext); return token::EPS;} -pdf {yylval->string_val = new string(yytext); return token::PDF;} -fig {yylval->string_val = new string(yytext); return token::FIG;} -none {yylval->string_val = new string(yytext); return token::NONE;} -print {return token::PRINT;} -noprint {return token::NOPRINT;} -conf_sig {return token::CONF_SIG;} -mh_conf_sig {return token::MH_CONF_SIG;} -mh_replic {return token::MH_REPLIC;} -mh_drop {return token::MH_DROP;} -mh_jscale {return token::MH_JSCALE;} -mh_init_scale {return token::MH_INIT_SCALE;} -mode_file {return token::MODE_FILE;} -mode_compute {return token::MODE_COMPUTE;} -mode_check {return token::MODE_CHECK;} -mode_check_neighbourhood_size {return token::MODE_CHECK_NEIGHBOURHOOD_SIZE;} -mode_check_symmetric_plots {return token::MODE_CHECK_SYMMETRIC_PLOTS;} -mode_check_number_of_points {return token::MODE_CHECK_NUMBER_OF_POINTS;} -prior_trunc {return token::PRIOR_TRUNC;} -mh_mode {return token::MH_MODE;} -mh_nblocks {return token::MH_NBLOCKS;} -load_mh_file {return token::LOAD_MH_FILE;} -load_results_after_load_mh {return token::LOAD_RESULTS_AFTER_LOAD_MH;} -loglinear {return token::LOGLINEAR;} -linear_approximation {return token::LINEAR_APPROXIMATION;} -logdata {return token::LOGDATA;} -nodiagnostic {return token::NODIAGNOSTIC;} -kalman_algo {return token::KALMAN_ALGO;} -fast_kalman_filter {return token::FAST_KALMAN_FILTER;} -kalman_tol {return token::KALMAN_TOL;} -diffuse_kalman_tol {return token::DIFFUSE_KALMAN_TOL;} -forecast {return token::FORECAST;} -smoother {return token::SMOOTHER;} -bayesian_irf {return token::BAYESIAN_IRF;} -dsge_var {return token::DSGE_VAR;} -dsge_varlag {return token::DSGE_VARLAG;} -moments_varendo {return token::MOMENTS_VARENDO;} -contemporaneous_correlation {return token::CONTEMPORANEOUS_CORRELATION;} -posterior_max_subsample_draws {return token::POSTERIOR_MAX_SUBSAMPLE_DRAWS;} -filtered_vars {return token::FILTERED_VARS;} -filter_step_ahead {return token::FILTER_STEP_AHEAD;} -relative_irf {return token::RELATIVE_IRF;} -tex {return token::TEX;} -nomoments {return token::NOMOMENTS;} -std {return token::STD;} -corr {return token::CORR;} -nocorr {return token::NOCORR;} -optim {return token::OPTIM;} -periods {return token::PERIODS;} -endogenous_terminal_period {return token::ENDOGENOUS_TERMINAL_PERIOD;} -sub_draws {return token::SUB_DRAWS;} -minimal_solving_periods {return token::MINIMAL_SOLVING_PERIODS;} -markowitz {return token::MARKOWITZ;} -marginal_density {return token::MARGINAL_DENSITY;} -laplace {return token::LAPLACE;} -modifiedharmonicmean {return token::MODIFIEDHARMONICMEAN;} -constant {return token::CONSTANT;} -noconstant {return token::NOCONSTANT;} -covar {return token::COVAR;} -filename {return token::FILENAME;} -diffuse_filter {return token::DIFFUSE_FILTER;} -plot_priors {return token::PLOT_PRIORS;} -aim_solver {return token::AIM_SOLVER;} -partial_information {return token::PARTIAL_INFORMATION;} -conditional_variance_decomposition {return token::CONDITIONAL_VARIANCE_DECOMPOSITION;} -name {return token::EXT_FUNC_NAME;} -nargs {return token::EXT_FUNC_NARGS;} -first_deriv_provided {return token::FIRST_DERIV_PROVIDED;} -second_deriv_provided {return token::SECOND_DERIV_PROVIDED;} -freq {return token::FREQ;} -monthly {return token::MONTHLY; } -quarterly {return token::QUARTERLY; } -initial_year {return token::INITIAL_YEAR;} -initial_subperiod {return token::INITIAL_SUBPERIOD;} -final_year {return token::FINAL_YEAR;} -final_subperiod {return token::FINAL_SUBPERIOD;} -vlist {return token::VLIST;} -vlistlog {return token::VLISTLOG;} -vlistper {return token::VLISTPER;} -keep_kalman_algo_if_singularity_is_detected {return token::KEEP_KALMAN_ALGO_IF_SINGULARITY_IS_DETECTED;} -restriction_fname {return token::RESTRICTION_FNAME;} -nlags {return token::NLAGS;} -restrictions {return token::RESTRICTIONS;} -cross_restrictions {return token::CROSS_RESTRICTIONS;} -contemp_reduced_form {return token::CONTEMP_REDUCED_FORM;} -real_pseudo_forecast {return token::REAL_PSEUDO_FORECAST;} -no_bayesian_prior {return token::NO_BAYESIAN_PRIOR;} -dummy_obs {return token::DUMMY_OBS;} -spectral_density {return token::SPECTRAL_DENSITY;} -nstates {return token::NSTATES;} -indxscalesstates {return token::INDXSCALESSTATES;} -fixed_point {return token::FIXED_POINT;} -doubling {return token::DOUBLING;} -plot_init_date {return token::PLOT_INIT_DATE;} -plot_end_date {return token::PLOT_END_DATE;} -square_root_solver {return token::SQUARE_ROOT_SOLVER;} -cycle_reduction {return token::CYCLE_REDUCTION;} -logarithmic_reduction {return token::LOGARITHMIC_REDUCTION;} -use_univariate_filters_if_singularity_is_detected {return token::USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED;} -hybrid {return token::HYBRID;} -default {return token::DEFAULT;} - -number_of_particles {return token::NUMBER_OF_PARTICLES;} -resampling {return token::RESAMPLING;} -systematic {return token::SYSTEMATIC;} -generic {return token::GENERIC;} -resampling_threshold {return token::RESAMPLING_THRESHOLD;} -resampling_method {return token::RESAMPLING_METHOD;} -kitagawa {return token::KITAGAWA;} -smooth {return token::SMOOTH;} -stratified {return token::STRATIFIED;} -cpf_weights {return token::CPF_WEIGHTS;} -amisanotristani {return token::AMISANOTRISTANI;} -murrayjonesparslow {return token::MURRAYJONESPARSLOW;} -filter_algorithm {return token::FILTER_ALGORITHM;} -nonlinear_filter_initialization {return token::NONLINEAR_FILTER_INITIALIZATION;} -proposal_approximation {return token::PROPOSAL_APPROXIMATION;} -cubature {return token::CUBATURE;} -unscented {return token::UNSCENTED;} -montecarlo {return token::MONTECARLO;} -distribution_approximation {return token::DISTRIBUTION_APPROXIMATION;} -proposal_distribution {return token::PROPOSAL_DISTRIBUTION;} -no_posterior_kernel_density {return token::NO_POSTERIOR_KERNEL_DENSITY;} -rescale_prediction_error_covariance {return token::RESCALE_PREDICTION_ERROR_COVARIANCE;} -use_penalized_objective_for_hessian {return token::USE_PENALIZED_OBJECTIVE_FOR_HESSIAN;} - -alpha { - yylval->string_val = new string(yytext); - return token::ALPHA; -} -beta { - yylval->string_val = new string(yytext); - return token::BETA; -} -gamma { - yylval->string_val = new string(yytext); - return token::GAMMA; -} -inv_gamma { - yylval->string_val = new string(yytext); - return token::INV_GAMMA; -} -inv_gamma1 { - yylval->string_val = new string(yytext); - return token::INV_GAMMA1; -} -inv_gamma2 { - yylval->string_val = new string(yytext); - return token::INV_GAMMA2; -} -dirichlet { - yylval->string_val = new string(yytext); - return token::DIRICHLET; -} -weibull { - yylval->string_val = new string(yytext); - return token::WEIBULL; -} -normal { - yylval->string_val = new string(yytext); - return token::NORMAL; -} -uniform { - yylval->string_val = new string(yytext); - return token::UNIFORM; -} -gsig2_lmdm {return token::GSIG2_LMDM;} -specification {return token::SPECIFICATION;} -sims_zha {return token::SIMS_ZHA;} -q_diag {return token::Q_DIAG;} -flat_prior {return token::FLAT_PRIOR;} -ncsk {return token::NCSK;} -nstd {return token::NSTD;} -ninv { - yylval->string_val = new string(yytext); - return token::NINV; -} -indxparr {return token::INDXPARR;} -indxovr {return token::INDXOVR;} -aband { - yylval->string_val = new string(yytext); - return token::ABAND; -} -write_equation_tags {return token::WRITE_EQUATION_TAGS;} -indxap {return token::INDXAP;} -apband {return token::APBAND;} -indximf {return token::INDXIMF;} -imfband {return token::IMFBAND;} -indxfore {return token::INDXFORE;} -foreband {return token::FOREBAND;} -indxgforehat {return token::INDXGFOREHAT;} -indxgimfhat {return token::INDXGIMFHAT;} -indxestima {return token::INDXESTIMA;} -indxgdls {return token::INDXGDLS;} -eq_ms {return token::EQ_MS;} -cms { - yylval->string_val = new string(yytext); - return token::CMS; -} -ncms { - yylval->string_val = new string(yytext); - return token::NCMS; -} -eq_cms {return token::EQ_CMS;} -tlindx {return token::TLINDX;} -tlnumber {return token::TLNUMBER;} -cnum { - yylval->string_val = new string(yytext); - return token::CNUM; -} -nodecomposition {return token::NODECOMPOSITION;}; -banact {return token::BANACT;} -use_calibration {return token::USE_CALIBRATION;} -output_file_tag {return token::OUTPUT_FILE_TAG;} -file_tag {return token::FILE_TAG;}; -no_create_init {return token::NO_CREATE_INIT;}; -simulation_file_tag {return token::SIMULATION_FILE_TAG;}; -horizon {return token::HORIZON;} -parameter_uncertainty {return token::PARAMETER_UNCERTAINTY;} -no_error_bands {return token::NO_ERROR_BANDS;} -error_band_percentiles {return token::ERROR_BAND_PERCENTILES;} -shock_draws {return token::SHOCK_DRAWS;} -shocks_per_parameter {return token::SHOCKS_PER_PARAMETER;} -thinning_factor {return token::THINNING_FACTOR;} -free_parameters {return token::FREE_PARAMETERS;} -median {return token::MEDIAN;} -regime {return token::REGIME;} -regimes {return token::REGIMES;} -data_obs_nbr {return token::DATA_OBS_NBR;} -filtered_probabilities {return token::FILTERED_PROBABILITIES;} -real_time_smoothed {return token::REAL_TIME_SMOOTHED;} -proposal_type {return token::PROPOSAL_TYPE;} -proposal_lower_bound {return token::PROPOSAL_LOWER_BOUND;} -proposal_upper_bound {return token::PROPOSAL_UPPER_BOUND;} -proposal_draws {return token::PROPOSAL_DRAWS;} -use_mean_center {return token::USE_MEAN_CENTER;} -adaptive_mh_draws {return token::ADAPTIVE_MH_DRAWS;} -coefficients_prior_hyperparameters {return token::COEFFICIENTS_PRIOR_HYPERPARAMETERS;} -convergence_starting_value {return token::CONVERGENCE_STARTING_VALUE;} -convergence_ending_value {return token::CONVERGENCE_ENDING_VALUE;} -convergence_increment_value {return token::CONVERGENCE_INCREMENT_VALUE;} -max_iterations_starting_value {return token::MAX_ITERATIONS_STARTING_VALUE;} -max_iterations_increment_value {return token::MAX_ITERATIONS_INCREMENT_VALUE;} -max_block_iterations {return token::MAX_BLOCK_ITERATIONS;} -max_repeated_optimization_runs {return token::MAX_REPEATED_OPTIMIZATION_RUNS;} -maxit {return token::MAXIT;} -function_convergence_criterion {return token::FUNCTION_CONVERGENCE_CRITERION;} -parameter_convergence_criterion {return token::PARAMETER_CONVERGENCE_CRITERION;} -number_of_large_perturbations {return token::NUMBER_OF_LARGE_PERTURBATIONS;} -number_of_small_perturbations {return token::NUMBER_OF_SMALL_PERTURBATIONS;} -number_of_posterior_draws_after_perturbation {return token::NUMBER_OF_POSTERIOR_DRAWS_AFTER_PERTURBATION;} -max_number_of_stages {return token::MAX_NUMBER_OF_STAGES;} -random_function_convergence_criterion {return token::RANDOM_FUNCTION_CONVERGENCE_CRITERION;} -random_parameter_convergence_criterion {return token::RANDOM_PARAMETER_CONVERGENCE_CRITERION;} -tolf {return token::TOLF;} -tolx {return token::TOLX;} -opt_algo {return token::OPT_ALGO;} -instruments {return token::INSTRUMENTS;} -hessian { - yylval->string_val = new string(yytext); - return token::HESSIAN; -} -prior_variance { - yylval->string_val = new string(yytext); - return token::PRIOR_VARIANCE; -} -identity_matrix { - yylval->string_val = new string(yytext); - return token::IDENTITY_MATRIX; -} -mcmc_jumping_covariance {return token::MCMC_JUMPING_COVARIANCE;} - - /* These four (var, varexo, varexo_det, parameters) are for change_type */ -var { return token::VAR; } -varexo { return token::VAREXO; } -varexo_det { return token::VAREXO_DET; } -parameters { return token::PARAMETERS; } -predetermined_variables { return token::PREDETERMINED_VARIABLES; } - -bvar_prior_tau { return token::BVAR_PRIOR_TAU; } -bvar_prior_decay { return token::BVAR_PRIOR_DECAY; } -bvar_prior_lambda { return token::BVAR_PRIOR_LAMBDA; } -bvar_prior_mu { return token::BVAR_PRIOR_MU; } -bvar_prior_omega { return token::BVAR_PRIOR_OMEGA; } -bvar_prior_flat { return token::BVAR_PRIOR_FLAT; } -bvar_prior_train { return token::BVAR_PRIOR_TRAIN; } -bvar_replic { return token::BVAR_REPLIC; } - -homotopy_mode {return token::HOMOTOPY_MODE; } -homotopy_steps {return token::HOMOTOPY_STEPS; } -homotopy_force_continue {return token::HOMOTOPY_FORCE_CONTINUE;} -nocheck {return token::NOCHECK; } - -controlled_varexo {return token::CONTROLLED_VAREXO; } -parameter_set {return token::PARAMETER_SET; } -init_state {return token::INIT_STATE; } -fast_realtime {return token::FAST_REALTIME; } -save_realtime {return token::SAVE_REALTIME;} -detail_plot {return token::DETAIL_PLOT;} -interactive {return token::INTERACTIVE;} -screen_shocks {return token::SCREEN_SHOCKS;} -steadystate {return token::STEADYSTATE;} -type {return token::TYPE;} -qoq {return token::QOQ; } -yoy {return token::YOY; } -aoa {return token::AOA; } -fig_name {return token::FIG_NAME;} -write_xls {return token::WRITE_XLS;} -realtime {return token::REALTIME;} -vintage {return token::VINTAGE;} -prior_mode {return token::PRIOR_MODE; } -prior_mean {return token::PRIOR_MEAN; } -posterior_mode {return token::POSTERIOR_MODE; } -posterior_mean {return token::POSTERIOR_MEAN; } -posterior_median {return token::POSTERIOR_MEDIAN; } -mle_mode {return token::MLE_MODE; } -k_order_solver {return token::K_ORDER_SOLVER; } -filter_covariance {return token::FILTER_COVARIANCE; } -filter_decomposition {return token::FILTER_DECOMPOSITION; } -smoothed_state_uncertainty {return token::SMOOTHED_STATE_UNCERTAINTY; } -selected_variables_only {return token::SELECTED_VARIABLES_ONLY; } -pruning {return token::PRUNING; } -save_draws {return token::SAVE_DRAWS; } -deflator {return token::DEFLATOR;} -log_deflator {return token::LOG_DEFLATOR;} -growth_factor {return token::GROWTH_FACTOR;} -log_growth_factor {return token::LOG_GROWTH_FACTOR;} -cova_compute {return token::COVA_COMPUTE;} -discretionary_tol {return token::DISCRETIONARY_TOL;} -analytic_derivation {return token::ANALYTIC_DERIVATION;} -analytic_derivation_mode {return token::ANALYTIC_DERIVATION_MODE;} -solver_periods {return token::SOLVER_PERIODS;} -endogenous_prior {return token::ENDOGENOUS_PRIOR;} -consider_all_endogenous {return token::CONSIDER_ALL_ENDOGENOUS;} -consider_only_observed {return token::CONSIDER_ONLY_OBSERVED;} -infile {return token::INFILE;} -invars {return token::INVARS;} -period {return token::PERIOD;} -outfile {return token::OUTFILE;} -outvars {return token::OUTVARS;} -huge_number {return token::HUGE_NUMBER;} -dr_display_tol {return token::DR_DISPLAY_TOL;} -posterior_sampling_method {return token::POSTERIOR_SAMPLING_METHOD;} -posterior_sampler_options {return token::POSTERIOR_SAMPLER_OPTIONS;} -silent_optimizer {return token::SILENT_OPTIMIZER;} -lmmcp {return token::LMMCP;} -occbin {return token::OCCBIN;} -centered_moments {return token::CENTERED_MOMENTS; } -autolag {return token::AUTOLAG; } -recursive_order_estimation {return token::RECURSIVE_ORDER_ESTIMATION; } -bartlett_kernel_lag {return token::BARTLETT_KERNEL_LAG; } -optimal { - yylval->string_val = new string(yytext); - return token::OPTIMAL; -} -diagonal { - yylval->string_val = new string(yytext); - return token::DIAGONAL; -} -weighting_matrix {return token::WEIGHTING_MATRIX; } -penalized_estimator {return token::PENALIZED_ESTIMATOR; } -verbose {return token::VERBOSE; } -simulation_multiple {return token::SIMULATION_MULTIPLE; } -seed {return token::SEED; } -bounded_shock_support {return token::BOUNDED_SHOCK_SUPPORT; } -analytical_girf {return token::ANALYTICAL_GIRF; } -irf_in_percent {return token::IRF_IN_PERCENT; } -emas_girf {return token::EMAS_GIRF; } -emas_drop {return token::EMAS_DROP; } -emas_tolf {return token::EMAS_TOLF; } -emas_max_iter {return token::EMAS_MAX_ITER; } - -[\$][^$]*[\$] { - strtok(yytext+1, "$"); - yylval->string_val = new string(yytext + 1); - return token::TEX_NAME; -} - - /* Inside a Dynare block */ -var {return token::VAR;} -stderr {return token::STDERR;} -values {return token::VALUES;} -corr {return token::CORR;} -periods {return token::PERIODS;} -cutoff {return token::CUTOFF;} -mfs {return token::MFS;} -gamma_pdf {return token::GAMMA_PDF;} -beta_pdf {return token::BETA_PDF;} -normal_pdf {return token::NORMAL_PDF;} -inv_gamma_pdf {return token::INV_GAMMA_PDF;} -inv_gamma1_pdf {return token::INV_GAMMA1_PDF;} -inv_gamma2_pdf {return token::INV_GAMMA2_PDF;} -uniform_pdf {return token::UNIFORM_PDF;} -weibull_pdf {return token::WEIBULL_PDF;} -dsge_prior_weight {return token::DSGE_PRIOR_WEIGHT;} - -; {return Dynare::parser::token_type (yytext[0]);} -# {return Dynare::parser::token_type (yytext[0]);} - -autocorr {return token::AUTOCORR;} -restriction {return token::RESTRICTION;} - - /* Inside Dynare statement */ -solve_algo {return token::SOLVE_ALGO;} -dr_algo {return token::DR_ALGO;} -simul_algo {return token::SIMUL_ALGO;} -stack_solve_algo {return token::STACK_SOLVE_ALGO;} -robust_lin_solve {return token::ROBUST_LIN_SOLVE;} -drop {return token::DROP;} -order {return token::ORDER;} -sylvester {return token::SYLVESTER;} -lyapunov {return token::LYAPUNOV;} -dr { - yylval->string_val = new string(yytext); - return token::DR; - } -sylvester_fixed_point_tol {return token::SYLVESTER_FIXED_POINT_TOL;} -lyapunov_fixed_point_tol {return token::LYAPUNOV_FIXED_POINT_TOL;} -lyapunov_doubling_tol {return token::LYAPUNOV_DOUBLING_TOL;} -dr_cycle_reduction_tol {return token::DR_CYCLE_REDUCTION_TOL;} -dr_logarithmic_reduction_tol {return token::DR_LOGARITHMIC_REDUCTION_TOL;} -dr_logarithmic_reduction_maxiter {return token::DR_LOGARITHMIC_REDUCTION_MAXITER;} -replic {return token::REPLIC;} -ar {return token::AR;} -nofunctions {return token::NOFUNCTIONS;} -irf {return token::IRF;} -irf_shocks {return token::IRF_SHOCKS;} -hp_filter {return token::HP_FILTER;} -one_sided_hp_filter {return token::ONE_SIDED_HP_FILTER;} -bandpass_filter {return token::BANDPASS_FILTER;} -hp_ngrid {return token::HP_NGRID;} -simul_seed {return token::SIMUL_SEED;} -qz_criterium {return token::QZ_CRITERIUM;} -qz_zero_threshold {return token::QZ_ZERO_THRESHOLD;} -simul {return token::SIMUL;} -simul_replic {return token::SIMUL_REPLIC;} -xls_sheet {return token::XLS_SHEET;} -xls_range {return token::XLS_RANGE;} -series {return token::SERIES;} -mh_recover {return token::MH_RECOVER;} -planner_discount {return token::PLANNER_DISCOUNT;} -calibration {return token::CALIBRATION;} -irf_plot_threshold {return token::IRF_PLOT_THRESHOLD;} -no_homotopy {return token::NO_HOMOTOPY;} - -stderr_multiples {return token::STDERR_MULTIPLES;} -diagonal_only {return token::DIAGONAL_ONLY;} -equation {return token::EQUATION;} -exclusion {return token::EXCLUSION;} -lag {return token::LAG;} -coeff {return token::COEFF;} -overwrite {return token::OVERWRITE;} -upper_cholesky {return token::UPPER_CHOLESKY;} -lower_cholesky {return token::LOWER_CHOLESKY;} -chain {return token::CHAIN;} -number_of_lags {return token::NUMBER_OF_LAGS;} -number_of_regimes {return token::NUMBER_OF_REGIMES;} -duration {return token::DURATION;} -coefficients {return token::COEFFICIENTS;} -variances {return token::VARIANCES;} -equations {return token::EQUATIONS;} - -[\.] {return Dynare::parser::token_type (yytext[0]);} -[\\] {return Dynare::parser::token_type (yytext[0]);} -[\'] {return Dynare::parser::token_type (yytext[0]);} - -use_dll {return token::USE_DLL;} -block {return token::BLOCK;} -bytecode {return token::BYTECODE;} -all_values_required {return token::ALL_VALUES_REQUIRED;} -no_static {return token::NO_STATIC;} -differentiate_forward_vars {return token::DIFFERENTIATE_FORWARD_VARS;} -parallel_local_files {return token::PARALLEL_LOCAL_FILES;} - -linear {return token::LINEAR;} - -[,] {return token::COMMA;} -[:] {return Dynare::parser::token_type (yytext[0]);} -[\(\)] {return Dynare::parser::token_type (yytext[0]);} -[\[] {return Dynare::parser::token_type (yytext[0]);} -[\]] { - if (sigma_e) - sigma_e = 0; - return Dynare::parser::token_type (yytext[0]); -} -[+] {return token::PLUS;} -[-] {return token::MINUS;} -[*] {return token::TIMES;} -[/] {return token::DIVIDE;} -[=] {return token::EQUAL;} -[<] {return token::LESS;} -[>] {return token::GREATER;} -">=" {return token::GREATER_EQUAL;} -"<=" {return token::LESS_EQUAL;} -"==" {return token::EQUAL_EQUAL;} -"!=" {return token::EXCLAMATION_EQUAL;} -[\^] {return token::POWER;} -exp {return token::EXP;} -log {return token::LOG;} -log10 {return token::LOG10;} -ln {return token::LN;} -sin {return token::SIN;} -cos {return token::COS;} -tan {return token::TAN;} -asin {return token::ASIN;} -acos {return token::ACOS;} -atan {return token::ATAN;} -sinh {return token::SINH;} -cosh {return token::COSH;} -tanh {return token::TANH;} -asinh {return token::ASINH;} -acosh {return token::ACOSH;} -atanh {return token::ATANH;} -sqrt {return token::SQRT;} -max {return token::MAX;} -min {return token::MIN;} -abs {return token::ABS;} -sign {return token::SIGN;} -normcdf {return token::NORMCDF;} -normpdf {return token::NORMPDF;} -erf {return token::ERF;} -steady_state {return token::STEADY_STATE;} -expectation {return token::EXPECTATION;} -varobs {return token::VAROBS;} -full {return token::FULL;} -nan {return token::NAN_CONSTANT;} -inf {return token::INF_CONSTANT;} -constants {return token::CONSTANTS;} - - /* options for GSA module by Marco Ratto */ -identification {return token::IDENTIFICATION;} -morris {return token::MORRIS;} -stab {return token::STAB;} -redform {return token::REDFORM;} -pprior {return token::PPRIOR;} -prior_range {return token::PRIOR_RANGE;} -ppost {return token::PPOST;} -ilptau {return token::ILPTAU;} -morris_nliv {return token::MORRIS_NLIV;} -morris_ntra {return token::MORRIS_NTRA;} -Nsam {return token::NSAM;} -load_redform {return token::LOAD_REDFORM;} -load_rmse {return token::LOAD_RMSE;} -load_stab {return token::LOAD_STAB;} -alpha2_stab {return token::ALPHA2_STAB;} -logtrans_redform {return token::LOGTRANS_REDFORM;} -threshold_redform {return token::THRESHOLD_REDFORM;} -ksstat_redform {return token::KSSTAT_REDFORM;} -alpha2_redform {return token::ALPHA2_REDFORM;} -namendo {return token::NAMENDO;} -namlagendo {return token::NAMLAGENDO;} -namexo {return token::NAMEXO;} -rmse {return token::RMSE;} -lik_only {return token::LIK_ONLY;} -var_rmse {return token::VAR_RMSE;} -pfilt_rmse {return token::PFILT_RMSE;} -istart_rmse {return token::ISTART_RMSE;} -alpha_rmse {return token::ALPHA_RMSE;} -alpha2_rmse {return token::ALPHA2_RMSE;} -load_ident_files {return token::LOAD_IDENT_FILES;} -useautocorr {return token::USEAUTOCORR;} -neighborhood_width {return token::NEIGHBORHOOD_WIDTH;} -pvalue_ks {return token::PVALUE_KS;} -pvalue_corr {return token::PVALUE_CORR;} - /* end of GSA options */ - - /* For identification() statement */ -prior_mc {return token::PRIOR_MC;} -advanced {return token::ADVANCED;} -max_dim_cova_group {return token::MAX_DIM_COVA_GROUP;} -gsa_sample_file {return token::GSA_SAMPLE_FILE;} - -use_shock_groups {return token::USE_SHOCK_GROUPS;} -colormap {return token::COLORMAP;} - -[A-Za-z_][A-Za-z0-9_]* { - yylval->string_val = new string(yytext); - return token::NAME; -} - -((([0-9]*\.[0-9]+)|([0-9]+\.))([edED][-+]?[0-9]+)?)|([0-9]+[edED][-+]?[0-9]+) { - yylval->string_val = new string(yytext); - return token::FLOAT_NUMBER; -} - -[0-9]+ { - yylval->string_val = new string(yytext); - return token::INT_NUMBER; -} - -\( { yylval->string_val->append(yytext); dates_parens_nb++; } -\) { - yylval->string_val->append(yytext); - if (--dates_parens_nb == 0) - { - BEGIN DYNARE_STATEMENT; - return token::DATES; - } - } -. { yylval->string_val->append(yytext); } - -\'[^\']+\' { - yylval->string_val = new string(yytext + 1); - yylval->string_val->resize(yylval->string_val->length() - 1); - return token::QUOTED_STRING; -} - - - /* Verbatim Block */ -verbatim[[:space:]]*; { - BEGIN VERBATIM_BLOCK; - yylval->string_val = new string(); - } -end[[:space:]]*; { - BEGIN INITIAL; - yylval->string_val = new string(); - } -\n { - if (strlen(yytext) > 1) - driver.add_verbatim_remove_charset(yytext, "\n"); - } -. { yymore(); } -<> { - driver.add_verbatim(eofbuff); - yyterminate(); - } - - - /* An instruction starting with a recognized symbol (which is not a modfile local - or an external function) is passed as NAME, otherwise it is a native statement - until the end of the line. - We exclude modfile local vars because the user may want to modify their value - using a Matlab assignment statement. - We also exclude external functions because the user may have used a Matlab matrix - 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. - */ -[A-Za-z_][A-Za-z0-9_]* { - if (driver.symbol_exists_and_is_not_modfile_local_or_external_function(yytext)) - { - BEGIN DYNARE_STATEMENT; - yylval->string_val = new string(yytext); - return token::NAME; - } - else - { - /* Enter a native block */ - BEGIN NATIVE; - yyless(0); - } -} - - /* For joint prior statement, match [symbol, symbol, ...] - If no match, begin native and push everything back on stack - */ -\[([[:space:]]*[A-Za-z_][A-Za-z0-9_]*[[:space:]]*,{1}[[:space:]]*)*([[:space:]]*[A-Za-z_][A-Za-z0-9_]*[[:space:]]*){1}\] { - string yytextcpy = string(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()); - istringstream ss(yytextcpy); - string token; - yylval->vector_string_val = new vector; - - bool dynare_statement = true; - - while(getline(ss, token, ',')) - if (driver.symbol_exists_and_is_not_modfile_local_or_external_function(token.c_str())) - yylval->vector_string_val->push_back(new string(token)); - else - { - for (vector::iterator it=yylval->vector_string_val->begin(); - it != yylval->vector_string_val->end(); it++) - delete *it; - delete yylval->vector_string_val; - BEGIN NATIVE; - yyless(0); - dynare_statement = false; - break; - } - if (dynare_statement) - { - BEGIN DYNARE_STATEMENT; - return token::SYMBOL_VEC; - } -} - - /* Enter a native block */ -. { BEGIN NATIVE; yyless(0); } - - /* Add the native statement */ -{ - [^/%*\n\.\'\"]* | - \' | - \'[^\'\n]*\' | - \"[^\"\n]*\" | - \.{1,2} | - "*" | - "/" { yymore(); eofbuff = string(yytext); } - \.{3,}[[:space:]]*\n { driver.add_native_remove_charset(yytext, "\n"); } - \n { - if (strlen(yytext) > 1) - driver.add_native_remove_charset(yytext, "\n"); - BEGIN INITIAL; - } - <> { - driver.add_native(eofbuff); - yyterminate(); - } - \.{3,}[[:space:]]*"%".*\n | - "%"[^\n]* { driver.add_native_remove_charset(yytext, "%"); } - \.{3,}[[:space:]]*"//".*\n | - "//"[^\n]* { driver.add_native_remove_charset(yytext, "//"); } - \.{3,}[[:space:]]*"/*" { - driver.add_native_remove_charset(yytext, "/*"); - BEGIN NATIVE_COMMENT; - } - "/*" { - driver.add_native_remove_charset(yytext, "/*"); - comment_caller = NATIVE; - BEGIN COMMENT; - } -} - -"*/"[[:space:]]*\n { BEGIN NATIVE; } -. - -<> { yyterminate(); } - -<*>. { driver.error(*yylloc, "character unrecognized by lexer"); } -%% - -DynareFlex::DynareFlex(istream* in, ostream* out) - : DynareFlexLexer(in, out) -{ -} - -void -DynareFlex::location_increment(Dynare::parser::location_type *yylloc, const char *yytext) -{ - while (*yytext != 0) - if (*yytext++ == '\n') - yylloc->lines(1); - else - yylloc->columns(1); -} - -/* This implementation of DynareFlexLexer::yylex() is required to fill the - * vtable of the class DynareFlexLexer. We define the scanner's main yylex - * function via YY_DECL to reside in the DynareFlex class instead. */ - -#ifdef yylex -# undef yylex -#endif - -int -DynareFlexLexer::yylex() -{ - cerr << "DynareFlexLexer::yylex() has been called, that should never happen!" << endl; - exit(EXIT_FAILURE); -} diff --git a/preprocessor/DynareMain.cc b/preprocessor/DynareMain.cc deleted file mode 100644 index 16183842c..000000000 --- a/preprocessor/DynareMain.cc +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#include -#include -#include - -#include -#include -#ifndef PACKAGE_VERSION -# define PACKAGE_VERSION 4. -#endif - -#include -#include "ParsingDriver.hh" -#include "ExtendedPreprocessorTypes.hh" -#include "ConfigFile.hh" - -/* Prototype for second part of main function - Splitting main() in two parts was necessary because ParsingDriver.h and MacroDriver.h can't be - included simultaneously (because of Bison limitations). -*/ -void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear_global, - bool no_tmp_terms, bool no_log, bool no_warn, bool warn_uninit, bool console, - bool nograph, bool nointeractive, bool parallel, ConfigFile &config_file, - WarningConsolidation &warnings_arg, bool nostrict, bool stochastic, bool check_model_changes, - bool minimal_workspace, bool compute_xrefs, FileOutputType output_mode, - LanguageOutputType lang, int params_derivs_order -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - , bool cygwin, bool msvc, bool mingw -#endif - , JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple - , bool nopreprocessoroutput - ); - -void main1(string &modfile, string &basename, string &modfiletxt, bool debug, bool save_macro, string &save_macro_file, - bool no_line_macro, bool no_empty_line_macro, map &defines, vector &path, stringstream ¯o_output); - -void -usage() -{ - cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [onlyclearglobals] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [noemptylinemacro] [notmpterms] [nolog] [warn_uninit]" - << " [console] [nograph] [nointeractive] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test]" - << " [-D[=]] [-I/path] [nostrict] [stochastic] [fast] [minimal_workspace] [compute_xrefs] [output=dynamic|first|second|third] [language=C|C++|julia]" - << " [params_derivs_order=0|1|2]" -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - << " [cygwin] [msvc] [mingw]" -#endif - << " [json=parse|check|transform|compute] [jsonstdout] [onlyjson] [jsonderivsimple] [nopathchange] [nopreprocessoroutput]" - << endl; - exit(EXIT_FAILURE); -} - -int -main(int argc, char **argv) -{ - /* - Redirect stderr to stdout. - Made necessary because MATLAB/Octave can only capture stdout (but not - stderr), in order to put it in the logfile (see issue #306) - */ - dup2(STDOUT_FILENO, STDERR_FILENO); - - if (argc < 2) - { - cerr << "Missing model file!" << endl; - usage(); - } - - bool clear_all = true; - bool clear_global = false; - bool save_macro = false; - string save_macro_file; - bool debug = false; - bool no_tmp_terms = false; - bool only_macro = false; - bool no_line_macro = false; - bool no_empty_line_macro = false; - bool no_log = false; - bool no_warn = false; - int params_derivs_order = 2; - bool warn_uninit = false; - bool console = false; - bool nograph = false; - bool nointeractive = false; -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - bool cygwin = false; - bool msvc = false; - bool mingw = false; -#endif - string parallel_config_file; - bool parallel = false; - string cluster_name; - bool parallel_slave_open_mode = false; - bool parallel_test = false; - bool nostrict = false; - bool stochastic = false; - bool check_model_changes = false; - bool minimal_workspace = false; - bool compute_xrefs = false; - map defines; - vector path; - FileOutputType output_mode = none; - JsonOutputPointType json = nojson; - JsonFileOutputType json_output_mode = file; - bool onlyjson = false; - bool jsonderivsimple = false; - LanguageOutputType language = matlab; - bool nopreprocessoroutput = false; - - // Parse options - for (int arg = 2; arg < argc; arg++) - { - if (!strcmp(argv[arg], "debug")) - debug = true; - else if (!strcmp(argv[arg], "noclearall")) - clear_all = false; - else if (strlen(argv[arg]) >= 19 && !strncmp(argv[arg], "params_derivs_order", 19)) - { - if (strlen(argv[arg]) >= 22 || argv[arg][19] != '=' - || !(argv[arg][20] == '0' || argv[arg][20] == '1' || argv[arg][20] == '2')) - { - cerr << "Incorrect syntax for params_derivs_order option" << endl; - usage(); - } - params_derivs_order = atoi(argv[arg] + 20); - } - else if (!strcmp(argv[arg], "onlyclearglobals")) - { - clear_all = false; - clear_global = true; - } - else if (!strcmp(argv[arg], "onlymacro")) - only_macro = true; - else if (strlen(argv[arg]) >= 9 && !strncmp(argv[arg], "savemacro", 9)) - { - save_macro = true; - if (strlen(argv[arg]) > 9) - { - if (strlen(argv[arg]) == 10 || argv[arg][9] != '=') - { - cerr << "Incorrect syntax for savemacro option" << endl; - usage(); - } - save_macro_file = string(argv[arg] + 10); - } - } - else if (!strcmp(argv[arg], "nolinemacro")) - no_line_macro = true; - else if (!strcmp(argv[arg], "noemptylinemacro")) - no_empty_line_macro = true; - else if (!strcmp(argv[arg], "notmpterms")) - no_tmp_terms = true; - else if (!strcmp(argv[arg], "nolog")) - no_log = true; - else if (!strcmp(argv[arg], "nowarn")) - no_warn = true; - else if (!strcmp(argv[arg], "warn_uninit")) - warn_uninit = true; - else if (!strcmp(argv[arg], "console")) - console = true; - else if (!strcmp(argv[arg], "nograph")) - nograph = true; - else if (!strcmp(argv[arg], "nointeractive")) - nointeractive = true; -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - else if (!strcmp(argv[arg], "cygwin")) - cygwin = true; - else if (!strcmp(argv[arg], "msvc")) - msvc = true; - else if (!strcmp(argv[arg], "mingw")) - mingw = true; -#endif - else if (strlen(argv[arg]) >= 8 && !strncmp(argv[arg], "conffile", 8)) - { - if (strlen(argv[arg]) <= 9 || argv[arg][8] != '=') - { - cerr << "Incorrect syntax for conffile option" << endl; - usage(); - } - parallel_config_file = string(argv[arg] + 9); - } - else if (!strcmp(argv[arg], "parallel_slave_open_mode")) - parallel_slave_open_mode = true; - else if (!strcmp(argv[arg], "parallel_test")) - parallel_test = true; - else if (!strcmp(argv[arg], "nostrict")) - nostrict = true; - else if (!strcmp(argv[arg], "stochastic")) - stochastic = true; - else if (!strcmp(argv[arg], "fast")) - check_model_changes = true; - else if (!strcmp(argv[arg], "minimal_workspace")) - minimal_workspace = true; - else if (!strcmp(argv[arg], "compute_xrefs")) - compute_xrefs = true; - else if (strlen(argv[arg]) >= 8 && !strncmp(argv[arg], "parallel", 8)) - { - parallel = true; - if (strlen(argv[arg]) > 8) - { - if (strlen(argv[arg]) == 9 || argv[arg][8] != '=') - { - cerr << "Incorrect syntax for parallel option" << endl; - usage(); - } - cluster_name = string(argv[arg] + 9); - } - } - else if (strlen(argv[arg]) >= 2 && !strncmp(argv[arg], "-D", 2)) - { - if (strlen(argv[arg]) == 2) - { - cerr << "Incorrect syntax for command line define: the defined variable " - << "must not be separated from -D by whitespace." << endl; - usage(); - } - - size_t equal_index = string(argv[arg]).find('='); - if (equal_index != string::npos) - { - string key = string(argv[arg]).erase(equal_index).erase(0, 2); - defines[key] = string(argv[arg]).erase(0, equal_index+1); - } - else - { - string key = string(argv[arg]).erase(0, 2); - defines[key] = "1"; - } - } - else if (strlen(argv[arg]) >= 2 && !strncmp(argv[arg], "-I", 2)) - { - if (strlen(argv[arg]) == 2) - { - cerr << "Incorrect syntax for command line define: the defined variable " - << "must not be separated from -I by whitespace." << endl; - usage(); - } - path.push_back(string(argv[arg]).erase(0, 2)); - } - else if (strlen(argv[arg]) >= 6 && !strncmp(argv[arg], "output", 6)) - { - if (strlen(argv[arg]) <= 7 || argv[arg][6] != '=') - { - cerr << "Incorrect syntax for output option" << endl; - usage(); - } - if (strlen(argv[arg]) == 14 && !strncmp(argv[arg] + 7, "dynamic", 7)) - output_mode = dynamic; - else if (strlen(argv[arg]) == 12 && !strncmp(argv[arg] + 7, "first", 5)) - output_mode = first; - else if (strlen(argv[arg]) == 13 && !strncmp(argv[arg] + 7, "second", 6)) - output_mode = second; - else if (strlen(argv[arg]) == 12 && !strncmp(argv[arg] + 7, "third", 5)) - output_mode = third; - else - { - cerr << "Incorrect syntax for output option" << endl; - usage(); - } - } - else if (strlen(argv[arg]) >= 8 && !strncmp(argv[arg], "language", 8)) - { - if (strlen(argv[arg]) <= 9 || argv[arg][8] != '=') - { - cerr << "Incorrect syntax for language option" << endl; - usage(); - } - - if (strlen(argv[arg]) == 14 && !strncmp(argv[arg] + 9, "julia", 5)) - language = julia; - else - { - // we don't want temp terms in external functions (except Julia) - no_tmp_terms = true; - if (strlen(argv[arg]) == 10 && !strncmp(argv[arg] + 9, "C", 1)) - language = c; - else if (strlen(argv[arg]) == 12 && !strncmp(argv[arg] + 9, "C++", 3)) - language = cpp; - else if (strlen(argv[arg]) == 13 && !strncmp(argv[arg] + 9, "cuda", 4)) - language = cuda; - else if (strlen(argv[arg]) == 15 && !strncmp(argv[arg] + 9, "python", 6)) - language = python; - else - { - cerr << "Incorrect syntax for language option" << endl; - usage(); - } - } - } - else if (!strcmp(argv[arg], "jsonstdout")) - json_output_mode = standardout; - else if (!strcmp(argv[arg], "onlyjson")) - onlyjson = true; - else if (!strcmp(argv[arg], "nopreprocessoroutput")) - nopreprocessoroutput = true; - else if (!strcmp(argv[arg], "jsonderivsimple")) - jsonderivsimple = true; - else if (strlen(argv[arg]) >= 4 && !strncmp(argv[arg], "json", 4)) - { - if (strlen(argv[arg]) <= 5 || argv[arg][4] != '=') - { - cerr << "Incorrect syntax for json option" << endl; - usage(); - } - if (strlen(argv[arg]) == 10 && !strncmp(argv[arg] + 5, "parse", 5)) - json = parsing; - else if (strlen(argv[arg]) == 10 && !strncmp(argv[arg] + 5, "check", 5)) - json = checkpass; - else if (strlen(argv[arg]) == 14 && !strncmp(argv[arg] + 5, "transform", 9)) - json = transformpass; - else if (strlen(argv[arg]) == 12 && !strncmp(argv[arg] + 5, "compute", 7)) - json = computingpass; - else - { - cerr << "Incorrect syntax for json option" << endl; - usage(); - } - } - else - { - cerr << "Unknown option: " << argv[arg] << endl; - usage(); - } - } - - if (!nopreprocessoroutput) - cout << "Starting Dynare (version " << PACKAGE_VERSION << ")." << endl - << "Starting preprocessing of the model file ..." << endl; - - // Construct basename (i.e. remove file extension if there is one) - string basename = argv[1]; - string modfile, modfiletxt; - size_t fsc = basename.find_first_of(';'); - if (fsc != string::npos) - { - // If a semicolon is found in argv[1], treat it as the text of the modfile - modfile = "mod_file_passed_as_string.mod"; - basename = "mod_file_passed_as_string"; - modfiletxt = argv[1]; - } - else - { - // If a semicolon is NOT found in argv[1], treat it as the name of the modfile - modfile = argv[1]; - size_t pos = basename.find_last_of('.'); - if (pos != string::npos) - basename.erase(pos); - - ifstream modfile(argv[1], ios::binary); - if (modfile.fail()) - { - cerr << "ERROR: Could not open file: " << argv[1] << endl; - exit(EXIT_FAILURE); - } - - stringstream buffer; - buffer << modfile.rdbuf(); - modfiletxt = buffer.str(); - } - - WarningConsolidation warnings(no_warn); - - // Process config file - ConfigFile config_file(parallel, parallel_test, parallel_slave_open_mode, cluster_name); - config_file.getConfigFileInfo(parallel_config_file); - config_file.checkPass(warnings); - config_file.transformPass(); - - // If Include option was passed to the [paths] block of the config file, add - // it to paths before macroprocessing - vector config_include_paths = config_file.getIncludePaths(); - for (vector::const_iterator it = config_include_paths.begin(); - it != config_include_paths.end(); it++) - path.push_back(*it); - - // Do macro processing - stringstream macro_output; - main1(modfile, basename, modfiletxt, debug, save_macro, save_macro_file, no_line_macro, no_empty_line_macro, - defines, path, macro_output); - - if (only_macro) - return EXIT_SUCCESS; - - // Do the rest - main2(macro_output, basename, debug, clear_all, clear_global, - no_tmp_terms, no_log, no_warn, warn_uninit, console, nograph, nointeractive, - parallel, config_file, warnings, nostrict, stochastic, check_model_changes, minimal_workspace, - compute_xrefs, output_mode, language, params_derivs_order -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - , cygwin, msvc, mingw -#endif - , json, json_output_mode, onlyjson, jsonderivsimple, nopreprocessoroutput - ); - - return EXIT_SUCCESS; -} diff --git a/preprocessor/DynareMain1.cc b/preprocessor/DynareMain1.cc deleted file mode 100644 index c801fd86d..000000000 --- a/preprocessor/DynareMain1.cc +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2015-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 . - */ - -#include -#include - -#include "macro/MacroDriver.hh" - -bool compareNewline (int i, int j) { - return i == '\n' && j == '\n'; -} - -void -main1(string &modfile, string &basename, string &modfiletxt, bool debug, bool save_macro, string &save_macro_file, - bool no_line_macro, bool no_empty_line_macro, map &defines, vector &path, stringstream ¯o_output) -{ - // Do macro processing - MacroDriver m; - - m.parse(modfile, basename, modfiletxt, macro_output, debug, no_line_macro, defines, path); - if (save_macro) - { - if (save_macro_file.empty()) - save_macro_file = basename + "-macroexp.mod"; - ofstream macro_output_file(save_macro_file.c_str()); - if (macro_output_file.fail()) - { - cerr << "Cannot open " << save_macro_file << " for macro output" << endl; - exit(EXIT_FAILURE); - } - - string str (macro_output.str()); - if (no_empty_line_macro) - str.erase(unique(str.begin(), str.end(), compareNewline), str.end()); - macro_output_file << str; - macro_output_file.close(); - } -} diff --git a/preprocessor/DynareMain2.cc b/preprocessor/DynareMain2.cc deleted file mode 100644 index d61df45b5..000000000 --- a/preprocessor/DynareMain2.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2008-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 . - */ - -#include - -#include "ParsingDriver.hh" -#include "ModFile.hh" -#include "ConfigFile.hh" -#include "ExtendedPreprocessorTypes.hh" - -void -main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear_global, - bool no_tmp_terms, bool no_log, bool no_warn, bool warn_uninit, bool console, - bool nograph, bool nointeractive, bool parallel, ConfigFile &config_file, - WarningConsolidation &warnings, bool nostrict, bool stochastic, bool check_model_changes, - bool minimal_workspace, bool compute_xrefs, FileOutputType output_mode, - LanguageOutputType language, int params_derivs_order -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - , bool cygwin, bool msvc, bool mingw -#endif - , JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple - , bool nopreprocessoroutput - ) -{ - ParsingDriver p(warnings, nostrict); - - // Do parsing and construct internal representation of mod file - ModFile *mod_file = p.parse(in, debug); - if (json == parsing) - mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson, nopreprocessoroutput); - - // Run checking pass - mod_file->checkPass(nostrict, stochastic); - if (json == checkpass) - mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson, nopreprocessoroutput); - - // Perform transformations on the model (creation of auxiliary vars and equations) - mod_file->transformPass(nostrict, stochastic, compute_xrefs || json == transformpass, nopreprocessoroutput); - if (json == transformpass) - mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson, nopreprocessoroutput); - - // Evaluate parameters initialization, initval, endval and pounds - mod_file->evalAllExpressions(warn_uninit, nopreprocessoroutput); - - // Do computations - mod_file->computingPass(no_tmp_terms, output_mode, params_derivs_order, nopreprocessoroutput); - if (json == computingpass) - mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson, nopreprocessoroutput, jsonderivsimple); - - // Write outputs - if (output_mode != none) - mod_file->writeExternalFiles(basename, output_mode, language, nopreprocessoroutput); - else - mod_file->writeOutputFiles(basename, clear_all, clear_global, no_log, no_warn, console, nograph, - nointeractive, config_file, check_model_changes, minimal_workspace, compute_xrefs -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - , cygwin, msvc, mingw -#endif - , nopreprocessoroutput - ); - - delete mod_file; - - if (!nopreprocessoroutput) - cout << "Preprocessing completed." << endl; -} diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc deleted file mode 100644 index ba04540cc..000000000 --- a/preprocessor/ExprNode.cc +++ /dev/null @@ -1,6406 +0,0 @@ -/* - * 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 . - */ - -#include -#include -#include - -#include -#include - -#include - -#include "ExprNode.hh" -#include "DataTree.hh" -#include "ModFile.hh" - -ExprNode::ExprNode(DataTree &datatree_arg) : datatree(datatree_arg), preparedForDerivation(false) -{ - // Add myself to datatree - datatree.node_list.push_back(this); - - // Set my index and increment counter - idx = datatree.node_counter++; -} - -ExprNode::~ExprNode() -{ -} - -expr_t -ExprNode::getDerivative(int deriv_id) -{ - if (!preparedForDerivation) - prepareForDerivation(); - - // Return zero if derivative is necessarily null (using symbolic a priori) - set::const_iterator it = non_null_derivatives.find(deriv_id); - if (it == non_null_derivatives.end()) - return datatree.Zero; - - // If derivative is stored in cache, use the cached value, otherwise compute it (and cache it) - map::const_iterator it2 = derivatives.find(deriv_id); - if (it2 != derivatives.end()) - return it2->second; - else - { - expr_t d = computeDerivative(deriv_id); - derivatives[deriv_id] = d; - return d; - } -} - -int -ExprNode::precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const -{ - // For a constant, a variable, or a unary op, the precedence is maximal - return 100; -} - -int -ExprNode::precedenceJson(const temporary_terms_t &temporary_terms) const -{ - // For a constant, a variable, or a unary op, the precedence is maximal - return 100; -} - -int -ExprNode::cost(int cost, bool is_matlab) const -{ - // For a terminal node, the cost is null - return 0; -} - -int -ExprNode::cost(const temporary_terms_t &temp_terms_map, bool is_matlab) const -{ - // For a terminal node, the cost is null - return 0; -} - -int -ExprNode::cost(const map &temp_terms_map, bool is_matlab) const -{ - // For a terminal node, the cost is null - return 0; -} - -void -ExprNode::collectVariables(SymbolType type, set &result) const -{ - set > symbs_lags; - collectDynamicVariables(type, symbs_lags); - transform(symbs_lags.begin(), symbs_lags.end(), inserter(result, result.begin()), - boost::bind(&pair::first, _1)); -} - -void -ExprNode::collectEndogenous(set > &result) const -{ - set > symb_ids; - collectDynamicVariables(eEndogenous, symb_ids); - for (set >::const_iterator it = symb_ids.begin(); - it != symb_ids.end(); it++) - result.insert(make_pair(datatree.symbol_table.getTypeSpecificID(it->first), it->second)); -} - -void -ExprNode::collectExogenous(set > &result) const -{ - set > symb_ids; - collectDynamicVariables(eExogenous, symb_ids); - for (set >::const_iterator it = symb_ids.begin(); - it != symb_ids.end(); it++) - result.insert(make_pair(datatree.symbol_table.getTypeSpecificID(it->first), it->second)); -} - -void -ExprNode::computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const -{ - // Nothing to do for a terminal node -} - -void -ExprNode::computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector > &v_temporary_terms, - int equation) const -{ - // Nothing to do for a terminal node -} - -pair -ExprNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const -{ - /* nothing to do */ - return (make_pair(0, (expr_t) NULL)); -} - -void -ExprNode::writeOutput(ostream &output) const -{ - writeOutput(output, oMatlabOutsideModel, temporary_terms_t()); -} - -void -ExprNode::writeOutput(ostream &output, ExprNodeOutputType output_type) const -{ - writeOutput(output, output_type, temporary_terms_t()); -} - -void -ExprNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const -{ - deriv_node_temp_terms_t tef_terms; - writeOutput(output, output_type, temporary_terms, tef_terms); -} - -void -ExprNode::compile(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const -{ - deriv_node_temp_terms_t tef_terms; - compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms); -} - -void -ExprNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - // Nothing to do -} - -void -ExprNode::writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - // Nothing to do -} - -void -ExprNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - // Nothing to do -} - -VariableNode * -ExprNode::createEndoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector &neweqs) const -{ - int n = maxEndoLead(); - assert(n >= 2); - - subst_table_t::const_iterator it = subst_table.find(this); - if (it != subst_table.end()) - return const_cast(it->second); - - expr_t substexpr = decreaseLeadsLags(n-1); - int lag = n-2; - - // Each iteration tries to create an auxvar such that auxvar(+1)=expr(-lag) - // At the beginning (resp. end) of each iteration, substexpr is an expression (possibly an auxvar) equivalent to expr(-lag-1) (resp. expr(-lag)) - while (lag >= 0) - { - expr_t orig_expr = decreaseLeadsLags(lag); - it = subst_table.find(orig_expr); - if (it == subst_table.end()) - { - int symb_id = datatree.symbol_table.addEndoLeadAuxiliaryVar(orig_expr->idx, substexpr); - neweqs.push_back(dynamic_cast(datatree.AddEqual(datatree.AddVariable(symb_id, 0), substexpr))); - substexpr = datatree.AddVariable(symb_id, +1); - assert(dynamic_cast(substexpr) != NULL); - subst_table[orig_expr] = dynamic_cast(substexpr); - } - else - substexpr = const_cast(it->second); - - lag--; - } - - return dynamic_cast(substexpr); -} - -VariableNode * -ExprNode::createExoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector &neweqs) const -{ - int n = maxExoLead(); - assert(n >= 1); - - subst_table_t::const_iterator it = subst_table.find(this); - if (it != subst_table.end()) - return const_cast(it->second); - - expr_t substexpr = decreaseLeadsLags(n); - int lag = n-1; - - // Each iteration tries to create an auxvar such that auxvar(+1)=expr(-lag) - // At the beginning (resp. end) of each iteration, substexpr is an expression (possibly an auxvar) equivalent to expr(-lag-1) (resp. expr(-lag)) - while (lag >= 0) - { - expr_t orig_expr = decreaseLeadsLags(lag); - it = subst_table.find(orig_expr); - if (it == subst_table.end()) - { - int symb_id = datatree.symbol_table.addExoLeadAuxiliaryVar(orig_expr->idx, substexpr); - neweqs.push_back(dynamic_cast(datatree.AddEqual(datatree.AddVariable(symb_id, 0), substexpr))); - substexpr = datatree.AddVariable(symb_id, +1); - assert(dynamic_cast(substexpr) != NULL); - subst_table[orig_expr] = dynamic_cast(substexpr); - } - else - substexpr = const_cast(it->second); - - lag--; - } - - return dynamic_cast(substexpr); -} - -bool -ExprNode::isNumConstNodeEqualTo(double value) const -{ - return false; -} - -bool -ExprNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const -{ - return false; -} - -NumConstNode::NumConstNode(DataTree &datatree_arg, int id_arg) : - ExprNode(datatree_arg), - id(id_arg) -{ - // Add myself to the num const map - datatree.num_const_node_map[id] = this; -} - -void -NumConstNode::prepareForDerivation() -{ - preparedForDerivation = true; - // All derivatives are null, so non_null_derivatives is left empty -} - -expr_t -NumConstNode::computeDerivative(int deriv_id) -{ - return datatree.Zero; -} - -void -NumConstNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - temporary_terms_inuse.insert(idx); -} - -void -NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - if (output_type == oMatlabDynamicModelSparse) - output << "T" << idx << "(it_)"; - else - output << "T" << idx; - else - output << datatree.num_constants.get(id); -} - -void -NumConstNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - output << datatree.num_constants.get(id); -} - -bool -NumConstNode::containsExternalFunction() const -{ - return false; -} - -double -NumConstNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) -{ - return (datatree.num_constants.getDouble(id)); -} - -void -NumConstNode::compile(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - FLDC_ fldc(datatree.num_constants.getDouble(id)); - fldc.write(CompileCode, instruction_number); -} - -void -NumConstNode::collectDynamicVariables(SymbolType type_arg, set > &result) const -{ -} - -pair -NumConstNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const -{ - /* return the numercial constant */ - return (make_pair(0, datatree.AddNonNegativeConstant(datatree.num_constants.get(id)))); -} - -expr_t -NumConstNode::getChainRuleDerivative(int deriv_id, const map &recursive_variables) -{ - return datatree.Zero; -} - -expr_t -NumConstNode::toStatic(DataTree &static_datatree) const -{ - return static_datatree.AddNonNegativeConstant(datatree.num_constants.get(id)); -} - -void -NumConstNode::computeXrefs(EquationInfo &ei) const -{ -} - -expr_t -NumConstNode::cloneDynamic(DataTree &dynamic_datatree) const -{ - return dynamic_datatree.AddNonNegativeConstant(datatree.num_constants.get(id)); -} - -int -NumConstNode::maxEndoLead() const -{ - return 0; -} - -int -NumConstNode::maxExoLead() const -{ - return 0; -} - -int -NumConstNode::maxEndoLag() const -{ - return 0; -} - -int -NumConstNode::maxExoLag() const -{ - return 0; -} - -int -NumConstNode::maxLead() const -{ - return 0; -} - -expr_t -NumConstNode::decreaseLeadsLags(int n) const -{ - return const_cast(this); -} - -expr_t -NumConstNode::decreaseLeadsLagsPredeterminedVariables() const -{ - return const_cast(this); -} - -expr_t -NumConstNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const -{ - return const_cast(this); -} - -expr_t -NumConstNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const -{ - return const_cast(this); -} - -expr_t -NumConstNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const -{ - return const_cast(this); -} - -expr_t -NumConstNode::substituteExoLag(subst_table_t &subst_table, vector &neweqs) const -{ - return const_cast(this); -} - -expr_t -NumConstNode::substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const -{ - return const_cast(this); -} - -expr_t -NumConstNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const -{ - return const_cast(this); -} - -bool -NumConstNode::isNumConstNodeEqualTo(double value) const -{ - if (datatree.num_constants.getDouble(id) == value) - return true; - else - return false; -} - -bool -NumConstNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const -{ - return false; -} - -bool -NumConstNode::containsEndogenous(void) const -{ - return false; -} - -bool -NumConstNode::containsExogenous() const -{ - return false; -} - -expr_t -NumConstNode::replaceTrendVar() const -{ - return const_cast(this); -} - -expr_t -NumConstNode::detrend(int symb_id, bool log_trend, expr_t trend) const -{ - return const_cast(this); -} - -expr_t -NumConstNode::removeTrendLeadLag(map trend_symbols_map) const -{ - return const_cast(this); -} - -bool -NumConstNode::isInStaticForm() const -{ - return true; -} - -expr_t -NumConstNode::substituteStaticAuxiliaryVariable() const -{ - return const_cast(this); -} - -VariableNode::VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg) : - ExprNode(datatree_arg), - symb_id(symb_id_arg), - type(datatree.symbol_table.getType(symb_id_arg)), - lag(lag_arg) -{ - // Add myself to the variable map - datatree.variable_node_map[make_pair(symb_id, lag)] = this; - - // It makes sense to allow a lead/lag on parameters: during steady state calibration, endogenous and parameters can be swapped - assert(type != eExternalFunction - && (lag == 0 || (type != eModelLocalVariable && type != eModFileLocalVariable))); -} - -void -VariableNode::prepareForDerivation() -{ - if (preparedForDerivation) - return; - - preparedForDerivation = true; - - // Fill in non_null_derivatives - switch (type) - { - case eEndogenous: - case eExogenous: - case eExogenousDet: - case eParameter: - case eTrend: - case eLogTrend: - // For a variable or a parameter, the only non-null derivative is with respect to itself - non_null_derivatives.insert(datatree.getDerivID(symb_id, lag)); - break; - case eModelLocalVariable: - datatree.local_variables_table[symb_id]->prepareForDerivation(); - // Non null derivatives are those of the value of the local parameter - non_null_derivatives = datatree.local_variables_table[symb_id]->non_null_derivatives; - break; - case eModFileLocalVariable: - case eStatementDeclaredVariable: - case eUnusedEndogenous: - // Such a variable is never derived - break; - case eExternalFunction: - cerr << "VariableNode::prepareForDerivation: impossible case" << endl; - exit(EXIT_FAILURE); - } -} - -expr_t -VariableNode::computeDerivative(int deriv_id) -{ - switch (type) - { - case eEndogenous: - case eExogenous: - case eExogenousDet: - case eParameter: - case eTrend: - case eLogTrend: - if (deriv_id == datatree.getDerivID(symb_id, lag)) - return datatree.One; - else - return datatree.Zero; - case eModelLocalVariable: - return datatree.local_variables_table[symb_id]->getDerivative(deriv_id); - case eModFileLocalVariable: - cerr << "ModFileLocalVariable is not derivable" << endl; - exit(EXIT_FAILURE); - case eStatementDeclaredVariable: - cerr << "eStatementDeclaredVariable is not derivable" << endl; - exit(EXIT_FAILURE); - case eUnusedEndogenous: - cerr << "eUnusedEndogenous is not derivable" << endl; - exit(EXIT_FAILURE); - case eExternalFunction: - cerr << "Impossible case!" << endl; - exit(EXIT_FAILURE); - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -void -VariableNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - temporary_terms_inuse.insert(idx); - if (type == eModelLocalVariable) - datatree.local_variables_table[symb_id]->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block); -} - -bool -VariableNode::containsExternalFunction() const -{ - return false; -} - -void -VariableNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - output << "T" << idx; - return; - } - - output << datatree.symbol_table.getName(symb_id); - if (isdynamic && lag != 0) - output << "(" << lag << ")"; -} - -void -VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - // If node is a temporary term - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (output_type == oMatlabDynamicModelSparse) - output << "T" << idx << "(it_)"; - else - output << "T" << idx; - return; - } - - if (IS_LATEX(output_type)) - { - if (output_type == oLatexDynamicSteadyStateOperator) - output << "\\bar"; - output << "{" << datatree.symbol_table.getTeXName(symb_id); - if (output_type == oLatexDynamicModel - && (type == eEndogenous || type == eExogenous || type == eExogenousDet || type == eModelLocalVariable || type == eTrend || type == eLogTrend)) - { - output << "_{t"; - if (lag != 0) - { - if (lag > 0) - output << "+"; - output << lag; - } - output << "}"; - } - output << "}"; - return; - } - - int i; - int tsid = datatree.symbol_table.getTypeSpecificID(symb_id); - switch (type) - { - case eParameter: - if (output_type == oMatlabOutsideModel) - output << "M_.params" << "(" << tsid + 1 << ")"; - else - output << "params" << LEFT_ARRAY_SUBSCRIPT(output_type) << tsid + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - - case eModelLocalVariable: - if (output_type == oMatlabDynamicModelSparse || output_type == oMatlabStaticModelSparse - || output_type == oMatlabDynamicSteadyStateOperator || output_type == oMatlabDynamicSparseSteadyStateOperator - || output_type == oCDynamicSteadyStateOperator) - { - output << "("; - datatree.local_variables_table[symb_id]->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ")"; - } - else - /* We append underscores to avoid name clashes with "g1" or "oo_" (see - also ModelTree::writeModelLocalVariables) */ - output << datatree.symbol_table.getName(symb_id) << "__"; - break; - - case eModFileLocalVariable: - output << datatree.symbol_table.getName(symb_id); - break; - - case eEndogenous: - switch (output_type) - { - case oJuliaDynamicModel: - case oMatlabDynamicModel: - case oCDynamicModel: - i = datatree.getDynJacobianCol(datatree.getDerivID(symb_id, lag)) + ARRAY_SUBSCRIPT_OFFSET(output_type); - output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oCDynamic2Model: - i = tsid + (lag+1)*datatree.symbol_table.endo_nbr() + ARRAY_SUBSCRIPT_OFFSET(output_type); - output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oCStaticModel: - case oJuliaStaticModel: - case oMatlabStaticModel: - case oMatlabStaticModelSparse: - i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type); - output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oMatlabDynamicModelSparse: - i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type); - if (lag > 0) - output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_+" << lag << ", " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - else if (lag < 0) - output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_" << lag << ", " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - else - output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_, " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oMatlabOutsideModel: - output << "oo_.steady_state(" << tsid + 1 << ")"; - break; - case oJuliaDynamicSteadyStateOperator: - case oMatlabDynamicSteadyStateOperator: - case oMatlabDynamicSparseSteadyStateOperator: - output << "steady_state" << LEFT_ARRAY_SUBSCRIPT(output_type) << tsid + 1 << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oCDynamicSteadyStateOperator: - output << "steady_state[" << tsid << "]"; - break; - case oJuliaSteadyStateFile: - case oSteadyStateFile: - output << "ys_" << LEFT_ARRAY_SUBSCRIPT(output_type) << tsid + 1 << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oCSteadyStateFile: - output << "ys_[" << tsid << "]"; - break; - default: - cerr << "VariableNode::writeOutput: should not reach this point" << endl; - exit(EXIT_FAILURE); - } - break; - - case eExogenous: - i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type); - switch (output_type) - { - case oJuliaDynamicModel: - case oMatlabDynamicModel: - case oMatlabDynamicModelSparse: - if (lag > 0) - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_+" << lag << ", " << i - << RIGHT_ARRAY_SUBSCRIPT(output_type); - else if (lag < 0) - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_" << lag << ", " << i - << RIGHT_ARRAY_SUBSCRIPT(output_type); - else - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_, " << i - << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oCDynamicModel: - case oCDynamic2Model: - if (lag == 0) - output << "x[it_+" << i << "*nb_row_x]"; - else if (lag > 0) - output << "x[it_+" << lag << "+" << i << "*nb_row_x]"; - else - output << "x[it_" << lag << "+" << i << "*nb_row_x]"; - break; - case oCStaticModel: - case oJuliaStaticModel: - case oMatlabStaticModel: - case oMatlabStaticModelSparse: - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oMatlabOutsideModel: - assert(lag == 0); - output << "oo_.exo_steady_state(" << i << ")"; - break; - case oMatlabDynamicSteadyStateOperator: - output << "oo_.exo_steady_state(" << i << ")"; - break; - case oJuliaSteadyStateFile: - case oSteadyStateFile: - output << "exo_" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oCSteadyStateFile: - output << "exo_[" << i - 1 << "]"; - break; - default: - cerr << "VariableNode::writeOutput: should not reach this point" << endl; - exit(EXIT_FAILURE); - } - break; - - case eExogenousDet: - i = tsid + datatree.symbol_table.exo_nbr() + ARRAY_SUBSCRIPT_OFFSET(output_type); - switch (output_type) - { - case oJuliaDynamicModel: - case oMatlabDynamicModel: - case oMatlabDynamicModelSparse: - if (lag > 0) - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_+" << lag << ", " << i - << RIGHT_ARRAY_SUBSCRIPT(output_type); - else if (lag < 0) - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_" << lag << ", " << i - << RIGHT_ARRAY_SUBSCRIPT(output_type); - else - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_, " << i - << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oCDynamicModel: - case oCDynamic2Model: - if (lag == 0) - output << "x[it_+" << i << "*nb_row_x]"; - else if (lag > 0) - output << "x[it_+" << lag << "+" << i << "*nb_row_x]"; - else - output << "x[it_" << lag << "+" << i << "*nb_row_x]"; - break; - case oCStaticModel: - case oJuliaStaticModel: - case oMatlabStaticModel: - case oMatlabStaticModelSparse: - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oMatlabOutsideModel: - assert(lag == 0); - output << "oo_.exo_det_steady_state(" << tsid + 1 << ")"; - break; - case oMatlabDynamicSteadyStateOperator: - output << "oo_.exo_det_steady_state(" << tsid + 1 << ")"; - break; - case oJuliaSteadyStateFile: - case oSteadyStateFile: - output << "exo_" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); - break; - case oCSteadyStateFile: - output << "exo_[" << i - 1 << "]"; - break; - default: - cerr << "VariableNode::writeOutput: should not reach this point" << endl; - exit(EXIT_FAILURE); - } - break; - - case eExternalFunction: - case eTrend: - case eLogTrend: - case eStatementDeclaredVariable: - case eUnusedEndogenous: - cerr << "Impossible case" << endl; - exit(EXIT_FAILURE); - } -} - -expr_t -VariableNode::substituteStaticAuxiliaryVariable() const -{ - if (type == eEndogenous) - { - try - { - return datatree.symbol_table.getAuxiliaryVarsExprNode(symb_id)->substituteStaticAuxiliaryVariable(); - } - catch (SymbolTable::SearchFailedException &e) - { - } - } - return const_cast(this); -} - -double -VariableNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) -{ - eval_context_t::const_iterator it = eval_context.find(symb_id); - if (it == eval_context.end()) - throw EvalException(); - - return it->second; -} - -void -VariableNode::compile(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - if (type == eModelLocalVariable || type == eModFileLocalVariable) - datatree.local_variables_table[symb_id]->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms); - else - { - int tsid = datatree.symbol_table.getTypeSpecificID(symb_id); - if (type == eExogenousDet) - tsid += datatree.symbol_table.exo_nbr(); - if (!lhs_rhs) - { - if (dynamic) - { - if (steady_dynamic) // steady state values in a dynamic model - { - FLDVS_ fldvs(type, tsid); - fldvs.write(CompileCode, instruction_number); - } - else - { - if (type == eParameter) - { - FLDV_ fldv(type, tsid); - fldv.write(CompileCode, instruction_number); - } - else - { - FLDV_ fldv(type, tsid, lag); - fldv.write(CompileCode, instruction_number); - } - } - } - else - { - FLDSV_ fldsv(type, tsid); - fldsv.write(CompileCode, instruction_number); - } - } - else - { - if (dynamic) - { - if (steady_dynamic) // steady state values in a dynamic model - { - cerr << "Impossible case: steady_state in rhs of equation" << endl; - exit(EXIT_FAILURE); - } - else - { - if (type == eParameter) - { - FSTPV_ fstpv(type, tsid); - fstpv.write(CompileCode, instruction_number); - } - else - { - FSTPV_ fstpv(type, tsid, lag); - fstpv.write(CompileCode, instruction_number); - } - } - } - else - { - FSTPSV_ fstpsv(type, tsid); - fstpsv.write(CompileCode, instruction_number); - } - } - } -} - -void -VariableNode::computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector > &v_temporary_terms, - int equation) const -{ - if (type == eModelLocalVariable) - datatree.local_variables_table[symb_id]->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation); -} - -void -VariableNode::collectDynamicVariables(SymbolType type_arg, set > &result) const -{ - if (type == type_arg) - result.insert(make_pair(symb_id, lag)); - if (type == eModelLocalVariable) - datatree.local_variables_table[symb_id]->collectDynamicVariables(type_arg, result); -} - -pair -VariableNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const -{ - /* The equation has to be normalized with respect to the current endogenous variable ascribed to it. - The two input arguments are : - - The ID of the endogenous variable associated to the equation. - - The list of operators and operands needed to normalize the equation* - - The pair returned by NormalizeEquation is composed of - - a flag indicating if the expression returned contains (flag = 1) or not (flag = 0) - the endogenous variable related to the equation. - If the expression contains more than one occurence of the associated endogenous variable, - the flag is equal to 2. - - an expression equal to the RHS if flag = 0 and equal to NULL elsewhere - */ - if (type == eEndogenous) - { - if (datatree.symbol_table.getTypeSpecificID(symb_id) == var_endo && lag == 0) - /* the endogenous variable */ - return (make_pair(1, (expr_t) NULL)); - else - return (make_pair(0, datatree.AddVariableInternal(symb_id, lag))); - } - else - { - if (type == eParameter) - return (make_pair(0, datatree.AddVariableInternal(symb_id, 0))); - else - return (make_pair(0, datatree.AddVariableInternal(symb_id, lag))); - } -} - -expr_t -VariableNode::getChainRuleDerivative(int deriv_id, const map &recursive_variables) -{ - switch (type) - { - case eEndogenous: - case eExogenous: - case eExogenousDet: - case eParameter: - case eTrend: - case eLogTrend: - if (deriv_id == datatree.getDerivID(symb_id, lag)) - return datatree.One; - else - { - //if there is in the equation a recursive variable we could use a chaine rule derivation - map::const_iterator it = recursive_variables.find(datatree.getDerivID(symb_id, lag)); - if (it != recursive_variables.end()) - { - map::const_iterator it2 = derivatives.find(deriv_id); - if (it2 != derivatives.end()) - return it2->second; - else - { - map recursive_vars2(recursive_variables); - recursive_vars2.erase(it->first); - //expr_t c = datatree.AddNonNegativeConstant("1"); - expr_t d = datatree.AddUMinus(it->second->getChainRuleDerivative(deriv_id, recursive_vars2)); - //d = datatree.AddTimes(c, d); - derivatives[deriv_id] = d; - return d; - } - } - else - return datatree.Zero; - } - case eModelLocalVariable: - return datatree.local_variables_table[symb_id]->getChainRuleDerivative(deriv_id, recursive_variables); - case eModFileLocalVariable: - cerr << "ModFileLocalVariable is not derivable" << endl; - exit(EXIT_FAILURE); - case eStatementDeclaredVariable: - cerr << "eStatementDeclaredVariable is not derivable" << endl; - exit(EXIT_FAILURE); - case eUnusedEndogenous: - cerr << "eUnusedEndogenous is not derivable" << endl; - exit(EXIT_FAILURE); - case eExternalFunction: - cerr << "Impossible case!" << endl; - exit(EXIT_FAILURE); - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -expr_t -VariableNode::toStatic(DataTree &static_datatree) const -{ - return static_datatree.AddVariable(symb_id); -} - -void -VariableNode::computeXrefs(EquationInfo &ei) const -{ - switch (type) - { - case eEndogenous: - ei.endo.insert(make_pair(symb_id, lag)); - break; - case eExogenous: - ei.exo.insert(make_pair(symb_id, lag)); - break; - case eExogenousDet: - ei.exo_det.insert(make_pair(symb_id, lag)); - break; - case eParameter: - ei.param.insert(make_pair(symb_id, 0)); - break; - case eTrend: - case eLogTrend: - case eModelLocalVariable: - case eModFileLocalVariable: - case eStatementDeclaredVariable: - case eUnusedEndogenous: - case eExternalFunction: - break; - } -} - -expr_t -VariableNode::cloneDynamic(DataTree &dynamic_datatree) const -{ - return dynamic_datatree.AddVariable(symb_id, lag); -} - -int -VariableNode::maxEndoLead() const -{ - switch (type) - { - case eEndogenous: - return max(lag, 0); - case eModelLocalVariable: - return datatree.local_variables_table[symb_id]->maxEndoLead(); - default: - return 0; - } -} - -int -VariableNode::maxExoLead() const -{ - switch (type) - { - case eExogenous: - return max(lag, 0); - case eModelLocalVariable: - return datatree.local_variables_table[symb_id]->maxExoLead(); - default: - return 0; - } -} - -int -VariableNode::maxEndoLag() const -{ - switch (type) - { - case eEndogenous: - return max(-lag, 0); - case eModelLocalVariable: - return datatree.local_variables_table[symb_id]->maxEndoLag(); - default: - return 0; - } -} - -int -VariableNode::maxExoLag() const -{ - switch (type) - { - case eExogenous: - return max(-lag, 0); - case eModelLocalVariable: - return datatree.local_variables_table[symb_id]->maxExoLag(); - default: - return 0; - } -} - -int -VariableNode::maxLead() const -{ - switch (type) - { - case eEndogenous: - return lag; - case eExogenous: - return lag; - case eModelLocalVariable: - return datatree.local_variables_table[symb_id]->maxLead(); - default: - return 0; - } -} - -expr_t -VariableNode::decreaseLeadsLags(int n) const -{ - switch (type) - { - case eEndogenous: - case eExogenous: - case eExogenousDet: - case eTrend: - case eLogTrend: - return datatree.AddVariable(symb_id, lag-n); - case eModelLocalVariable: - return datatree.local_variables_table[symb_id]->decreaseLeadsLags(n); - default: - return const_cast(this); - } -} - -expr_t -VariableNode::decreaseLeadsLagsPredeterminedVariables() const -{ - if (datatree.symbol_table.isPredetermined(symb_id)) - return decreaseLeadsLags(1); - else - return const_cast(this); -} - -expr_t -VariableNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const -{ - expr_t value; - switch (type) - { - case eEndogenous: - if (lag <= 1) - return const_cast(this); - else - return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs); - case eModelLocalVariable: - value = datatree.local_variables_table[symb_id]; - if (value->maxEndoLead() <= 1) - return const_cast(this); - else - return value->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); - default: - return const_cast(this); - } -} - -expr_t -VariableNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const -{ - VariableNode *substexpr; - expr_t value; - subst_table_t::const_iterator it; - int cur_lag; - switch (type) - { - case eEndogenous: - if (lag >= -1) - return const_cast(this); - - it = subst_table.find(this); - if (it != subst_table.end()) - return const_cast(it->second); - - substexpr = datatree.AddVariable(symb_id, -1); - cur_lag = -2; - - // Each iteration tries to create an auxvar such that auxvar(-1)=curvar(cur_lag) - // At the beginning (resp. end) of each iteration, substexpr is an expression (possibly an auxvar) equivalent to curvar(cur_lag+1) (resp. curvar(cur_lag)) - while (cur_lag >= lag) - { - VariableNode *orig_expr = datatree.AddVariable(symb_id, cur_lag); - it = subst_table.find(orig_expr); - if (it == subst_table.end()) - { - int aux_symb_id = datatree.symbol_table.addEndoLagAuxiliaryVar(symb_id, cur_lag+1, substexpr); - neweqs.push_back(dynamic_cast(datatree.AddEqual(datatree.AddVariable(aux_symb_id, 0), substexpr))); - substexpr = datatree.AddVariable(aux_symb_id, -1); - subst_table[orig_expr] = substexpr; - } - else - substexpr = const_cast(it->second); - - cur_lag--; - } - return substexpr; - - case eModelLocalVariable: - value = datatree.local_variables_table[symb_id]; - if (value->maxEndoLag() <= 1) - return const_cast(this); - else - return value->substituteEndoLagGreaterThanTwo(subst_table, neweqs); - default: - return const_cast(this); - } -} - -expr_t -VariableNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const -{ - expr_t value; - switch (type) - { - case eExogenous: - if (lag <= 0) - return const_cast(this); - else - return createExoLeadAuxiliaryVarForMyself(subst_table, neweqs); - case eModelLocalVariable: - value = datatree.local_variables_table[symb_id]; - if (value->maxExoLead() == 0) - return const_cast(this); - else - return value->substituteExoLead(subst_table, neweqs, deterministic_model); - default: - return const_cast(this); - } -} - -expr_t -VariableNode::substituteExoLag(subst_table_t &subst_table, vector &neweqs) const -{ - VariableNode *substexpr; - expr_t value; - subst_table_t::const_iterator it; - int cur_lag; - switch (type) - { - case eExogenous: - if (lag >= 0) - return const_cast(this); - - it = subst_table.find(this); - if (it != subst_table.end()) - return const_cast(it->second); - - substexpr = datatree.AddVariable(symb_id, 0); - cur_lag = -1; - - // Each iteration tries to create an auxvar such that auxvar(-1)=curvar(cur_lag) - // At the beginning (resp. end) of each iteration, substexpr is an expression (possibly an auxvar) equivalent to curvar(cur_lag+1) (resp. curvar(cur_lag)) - while (cur_lag >= lag) - { - VariableNode *orig_expr = datatree.AddVariable(symb_id, cur_lag); - it = subst_table.find(orig_expr); - if (it == subst_table.end()) - { - int aux_symb_id = datatree.symbol_table.addExoLagAuxiliaryVar(symb_id, cur_lag+1, substexpr); - neweqs.push_back(dynamic_cast(datatree.AddEqual(datatree.AddVariable(aux_symb_id, 0), substexpr))); - substexpr = datatree.AddVariable(aux_symb_id, -1); - subst_table[orig_expr] = substexpr; - } - else - substexpr = const_cast(it->second); - - cur_lag--; - } - return substexpr; - - case eModelLocalVariable: - value = datatree.local_variables_table[symb_id]; - if (value->maxExoLag() == 0) - return const_cast(this); - else - return value->substituteExoLag(subst_table, neweqs); - default: - return const_cast(this); - } -} - -expr_t -VariableNode::substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const -{ - return const_cast(this); -} - -expr_t -VariableNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const -{ - expr_t value; - switch (type) - { - case eEndogenous: - assert(lag <= 1); - if (lag <= 0 - || (subset.size() > 0 - && find(subset.begin(), subset.end(), datatree.symbol_table.getName(symb_id)) == subset.end())) - return const_cast(this); - else - { - subst_table_t::iterator it = subst_table.find(this); - VariableNode *diffvar; - if (it != subst_table.end()) - diffvar = const_cast(it->second); - else - { - int aux_symb_id = datatree.symbol_table.addDiffForwardAuxiliaryVar(symb_id, datatree.AddMinus(datatree.AddVariable(symb_id, 0), - datatree.AddVariable(symb_id, -1))); - neweqs.push_back(dynamic_cast(datatree.AddEqual(datatree.AddVariable(aux_symb_id, 0), datatree.AddMinus(datatree.AddVariable(symb_id, 0), - datatree.AddVariable(symb_id, -1))))); - diffvar = datatree.AddVariable(aux_symb_id, 1); - subst_table[this] = diffvar; - } - return datatree.AddPlus(datatree.AddVariable(symb_id, 0), diffvar); - } - case eModelLocalVariable: - value = datatree.local_variables_table[symb_id]; - if (value->maxEndoLead() <= 0) - return const_cast(this); - else - return value->differentiateForwardVars(subset, subst_table, neweqs); - default: - return const_cast(this); - } -} - -bool -VariableNode::isNumConstNodeEqualTo(double value) const -{ - return false; -} - -bool -VariableNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const -{ - if (type == type_arg && datatree.symbol_table.getTypeSpecificID(symb_id) == variable_id && lag == lag_arg) - return true; - else - return false; -} - -bool -VariableNode::containsEndogenous(void) const -{ - if (type == eEndogenous) - return true; - else - return false; -} - -bool -VariableNode::containsExogenous() const -{ - return (type == eExogenous || type == eExogenousDet); -} - -expr_t -VariableNode::replaceTrendVar() const -{ - if (get_type() == eTrend) - return datatree.One; - else if (get_type() == eLogTrend) - return datatree.Zero; - else - return const_cast(this); -} - -expr_t -VariableNode::detrend(int symb_id, bool log_trend, expr_t trend) const -{ - if (get_symb_id() != symb_id) - return const_cast(this); - - if (log_trend) - { - if (get_lag() == 0) - return datatree.AddPlus(const_cast(this), trend); - else - return datatree.AddPlus(const_cast(this), trend->decreaseLeadsLags(-1*get_lag())); - } - else - { - if (get_lag() == 0) - return datatree.AddTimes(const_cast(this), trend); - else - return datatree.AddTimes(const_cast(this), trend->decreaseLeadsLags(-1*get_lag())); - } -} - -expr_t -VariableNode::removeTrendLeadLag(map trend_symbols_map) const -{ - if ((get_type() != eTrend && get_type() != eLogTrend) || get_lag() == 0) - return const_cast(this); - - map::const_iterator it = trend_symbols_map.find(symb_id); - expr_t noTrendLeadLagNode = new VariableNode(datatree, it->first, 0); - bool log_trend = get_type() == eLogTrend; - expr_t trend = it->second; - - if (get_lag() > 0) - { - expr_t growthFactorSequence = trend->decreaseLeadsLags(-1); - if (log_trend) - { - for (int i = 1; i < get_lag(); i++) - growthFactorSequence = datatree.AddPlus(growthFactorSequence, trend->decreaseLeadsLags(-1*(i+1))); - return datatree.AddPlus(noTrendLeadLagNode, growthFactorSequence); - } - else - { - for (int i = 1; i < get_lag(); i++) - growthFactorSequence = datatree.AddTimes(growthFactorSequence, trend->decreaseLeadsLags(-1*(i+1))); - return datatree.AddTimes(noTrendLeadLagNode, growthFactorSequence); - } - } - else //get_lag < 0 - { - expr_t growthFactorSequence = trend; - if (log_trend) - { - for (int i = 1; i < abs(get_lag()); i++) - growthFactorSequence = datatree.AddPlus(growthFactorSequence, trend->decreaseLeadsLags(i)); - return datatree.AddMinus(noTrendLeadLagNode, growthFactorSequence); - } - else - { - for (int i = 1; i < abs(get_lag()); i++) - growthFactorSequence = datatree.AddTimes(growthFactorSequence, trend->decreaseLeadsLags(i)); - return datatree.AddDivide(noTrendLeadLagNode, growthFactorSequence); - } - } -} - -bool -VariableNode::isInStaticForm() const -{ - return lag == 0; -} - -UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg) : - ExprNode(datatree_arg), - arg(arg_arg), - expectation_information_set(expectation_information_set_arg), - param1_symb_id(param1_symb_id_arg), - param2_symb_id(param2_symb_id_arg), - op_code(op_code_arg) -{ - // Add myself to the unary op map - datatree.unary_op_node_map[make_pair(make_pair(arg, op_code), - make_pair(expectation_information_set, - make_pair(param1_symb_id, param2_symb_id)))] = this; -} - -void -UnaryOpNode::prepareForDerivation() -{ - if (preparedForDerivation) - return; - - preparedForDerivation = true; - - arg->prepareForDerivation(); - - // Non-null derivatives are those of the argument (except for STEADY_STATE) - non_null_derivatives = arg->non_null_derivatives; - if (op_code == oSteadyState || op_code == oSteadyStateParamDeriv - || op_code == oSteadyStateParam2ndDeriv) - datatree.addAllParamDerivId(non_null_derivatives); -} - -expr_t -UnaryOpNode::composeDerivatives(expr_t darg, int deriv_id) -{ - expr_t t11, t12, t13, t14; - - switch (op_code) - { - case oUminus: - return datatree.AddUMinus(darg); - case oExp: - return datatree.AddTimes(darg, this); - case oLog: - return datatree.AddDivide(darg, arg); - case oLog10: - t11 = datatree.AddExp(datatree.One); - t12 = datatree.AddLog10(t11); - t13 = datatree.AddDivide(darg, arg); - return datatree.AddTimes(t12, t13); - case oCos: - t11 = datatree.AddSin(arg); - t12 = datatree.AddUMinus(t11); - return datatree.AddTimes(darg, t12); - case oSin: - t11 = datatree.AddCos(arg); - return datatree.AddTimes(darg, t11); - case oTan: - t11 = datatree.AddTimes(this, this); - t12 = datatree.AddPlus(t11, datatree.One); - return datatree.AddTimes(darg, t12); - case oAcos: - t11 = datatree.AddSin(this); - t12 = datatree.AddDivide(darg, t11); - return datatree.AddUMinus(t12); - case oAsin: - t11 = datatree.AddCos(this); - return datatree.AddDivide(darg, t11); - case oAtan: - t11 = datatree.AddTimes(arg, arg); - t12 = datatree.AddPlus(datatree.One, t11); - return datatree.AddDivide(darg, t12); - case oCosh: - t11 = datatree.AddSinh(arg); - return datatree.AddTimes(darg, t11); - case oSinh: - t11 = datatree.AddCosh(arg); - return datatree.AddTimes(darg, t11); - case oTanh: - t11 = datatree.AddTimes(this, this); - t12 = datatree.AddMinus(datatree.One, t11); - return datatree.AddTimes(darg, t12); - case oAcosh: - t11 = datatree.AddSinh(this); - return datatree.AddDivide(darg, t11); - case oAsinh: - t11 = datatree.AddCosh(this); - return datatree.AddDivide(darg, t11); - case oAtanh: - t11 = datatree.AddTimes(arg, arg); - t12 = datatree.AddMinus(datatree.One, t11); - return datatree.AddTimes(darg, t12); - case oSqrt: - t11 = datatree.AddPlus(this, this); - return datatree.AddDivide(darg, t11); - case oAbs: - t11 = datatree.AddSign(arg); - return datatree.AddTimes(t11, darg); - case oSign: - return datatree.Zero; - case oSteadyState: - if (datatree.isDynamic()) - { - if (datatree.getTypeByDerivID(deriv_id) == eParameter) - { - VariableNode *varg = dynamic_cast(arg); - if (varg == NULL) - { - cerr << "UnaryOpNode::composeDerivatives: STEADY_STATE() should only be used on " - << "standalone variables (like STEADY_STATE(y)) to be derivable w.r.t. parameters" << endl; - exit(EXIT_FAILURE); - } - if (datatree.symbol_table.getType(varg->symb_id) == eEndogenous) - return datatree.AddSteadyStateParamDeriv(arg, datatree.getSymbIDByDerivID(deriv_id)); - else - return datatree.Zero; - } - else - return datatree.Zero; - } - else - return darg; - case oSteadyStateParamDeriv: - assert(datatree.isDynamic()); - if (datatree.getTypeByDerivID(deriv_id) == eParameter) - { - VariableNode *varg = dynamic_cast(arg); - assert(varg != NULL); - assert(datatree.symbol_table.getType(varg->symb_id) == eEndogenous); - return datatree.AddSteadyStateParam2ndDeriv(arg, param1_symb_id, datatree.getSymbIDByDerivID(deriv_id)); - } - else - return datatree.Zero; - case oSteadyStateParam2ndDeriv: - assert(datatree.isDynamic()); - if (datatree.getTypeByDerivID(deriv_id) == eParameter) - { - cerr << "3rd derivative of STEADY_STATE node w.r.t. three parameters not implemented" << endl; - exit(EXIT_FAILURE); - } - else - return datatree.Zero; - case oExpectation: - cerr << "UnaryOpNode::composeDerivatives: not implemented on oExpectation" << endl; - exit(EXIT_FAILURE); - case oErf: - // x^2 - t11 = datatree.AddPower(arg, datatree.Two); - // exp(x^2) - t12 = datatree.AddExp(t11); - // sqrt(pi) - t11 = datatree.AddSqrt(datatree.Pi); - // sqrt(pi)*exp(x^2) - t13 = datatree.AddTimes(t11, t12); - // 2/(sqrt(pi)*exp(x^2)); - t14 = datatree.AddDivide(datatree.Two, t13); - // (2/(sqrt(pi)*exp(x^2)))*dx; - return datatree.AddTimes(t14, darg); - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -expr_t -UnaryOpNode::computeDerivative(int deriv_id) -{ - expr_t darg = arg->getDerivative(deriv_id); - return composeDerivatives(darg, deriv_id); -} - -int -UnaryOpNode::cost(const map &temp_terms_map, bool is_matlab) const -{ - // For a temporary term, the cost is null - for (map::const_iterator it = temp_terms_map.begin(); - it != temp_terms_map.end(); it++) - if (it->second.find(const_cast(this)) != it->second.end()) - return 0; - - return cost(arg->cost(temp_terms_map, is_matlab), is_matlab); -} - -int -UnaryOpNode::cost(const temporary_terms_t &temporary_terms, bool is_matlab) const -{ - // For a temporary term, the cost is null - if (temporary_terms.find(const_cast(this)) != temporary_terms.end()) - return 0; - - return cost(arg->cost(temporary_terms, is_matlab), is_matlab); -} - -int -UnaryOpNode::cost(int cost, bool is_matlab) const -{ - if (is_matlab) - // Cost for Matlab files - switch (op_code) - { - case oUminus: - case oSign: - return cost + 70; - case oExp: - return cost + 160; - case oLog: - return cost + 300; - case oLog10: - case oErf: - return cost + 16000; - case oCos: - case oSin: - case oCosh: - return cost + 210; - case oTan: - return cost + 230; - case oAcos: - return cost + 300; - case oAsin: - return cost + 310; - case oAtan: - return cost + 140; - case oSinh: - return cost + 240; - case oTanh: - return cost + 190; - case oAcosh: - return cost + 770; - case oAsinh: - return cost + 460; - case oAtanh: - return cost + 350; - case oSqrt: - case oAbs: - return cost + 570; - case oSteadyState: - case oSteadyStateParamDeriv: - case oSteadyStateParam2ndDeriv: - case oExpectation: - return cost; - } - else - // Cost for C files - switch (op_code) - { - case oUminus: - case oSign: - return cost + 3; - case oExp: - case oAcosh: - return cost + 210; - case oLog: - return cost + 137; - case oLog10: - return cost + 139; - case oCos: - case oSin: - return cost + 160; - case oTan: - return cost + 170; - case oAcos: - case oAtan: - return cost + 190; - case oAsin: - return cost + 180; - case oCosh: - case oSinh: - case oTanh: - case oErf: - return cost + 240; - case oAsinh: - return cost + 220; - case oAtanh: - return cost + 150; - case oSqrt: - case oAbs: - return cost + 90; - case oSteadyState: - case oSteadyStateParamDeriv: - case oSteadyStateParam2ndDeriv: - case oExpectation: - return cost; - } - exit(EXIT_FAILURE); -} - -void -UnaryOpNode::computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const -{ - expr_t this2 = const_cast(this); - - map >::iterator it = reference_count.find(this2); - if (it == reference_count.end()) - { - reference_count[this2] = make_pair(1, tr); - arg->computeTemporaryTerms(reference_count, temp_terms_map, is_matlab, tr); - } - else - { - reference_count[this2] = make_pair(it->second.first + 1, it->second.second); - if (reference_count[this2].first * cost(temp_terms_map, is_matlab) > MIN_COST(is_matlab)) - temp_terms_map[reference_count[this2].second].insert(this2); - } -} - -void -UnaryOpNode::computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const -{ - expr_t this2 = const_cast(this); - map::iterator it = reference_count.find(this2); - if (it == reference_count.end()) - { - reference_count[this2] = 1; - first_occurence[this2] = make_pair(Curr_block, equation); - arg->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation); - } - else - { - reference_count[this2]++; - if (reference_count[this2] * cost(temporary_terms, false) > MIN_COST_C) - { - temporary_terms.insert(this2); - v_temporary_terms[first_occurence[this2].first][first_occurence[this2].second].insert(this2); - } - } -} - -void -UnaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - temporary_terms_inuse.insert(idx); - else - arg->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block); -} - -bool -UnaryOpNode::containsExternalFunction() const -{ - return arg->containsExternalFunction(); -} - -void -UnaryOpNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - output << "T" << idx; - return; - } - - // Always put parenthesis around uminus nodes - if (op_code == oUminus) - output << "("; - - switch (op_code) - { - case oUminus: - output << "-"; - break; - case oExp: - output << "exp"; - break; - case oLog: - output << "log"; - break; - case oLog10: - output << "log10"; - break; - case oCos: - output << "cos"; - break; - case oSin: - output << "sin"; - break; - case oTan: - output << "tan"; - break; - case oAcos: - output << "acos"; - break; - case oAsin: - output << "asin"; - break; - case oAtan: - output << "atan"; - break; - case oCosh: - output << "cosh"; - break; - case oSinh: - output << "sinh"; - break; - case oTanh: - output << "tanh"; - break; - case oAcosh: - output << "acosh"; - break; - case oAsinh: - output << "asinh"; - break; - case oAtanh: - output << "atanh"; - break; - case oSqrt: - output << "sqrt"; - break; - case oAbs: - output << "abs"; - break; - case oSign: - output << "sign"; - break; - case oSteadyState: - output << "("; - arg->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); - output << ")"; - return; - case oSteadyStateParamDeriv: - { - VariableNode *varg = dynamic_cast(arg); - assert(varg != NULL); - assert(datatree.symbol_table.getType(varg->symb_id) == eEndogenous); - assert(datatree.symbol_table.getType(param1_symb_id) == eParameter); - int tsid_endo = datatree.symbol_table.getTypeSpecificID(varg->symb_id); - int tsid_param = datatree.symbol_table.getTypeSpecificID(param1_symb_id); - output << "ss_param_deriv(" << tsid_endo+1 << "," << tsid_param+1 << ")"; - } - return; - case oSteadyStateParam2ndDeriv: - { - VariableNode *varg = dynamic_cast(arg); - assert(varg != NULL); - assert(datatree.symbol_table.getType(varg->symb_id) == eEndogenous); - assert(datatree.symbol_table.getType(param1_symb_id) == eParameter); - assert(datatree.symbol_table.getType(param2_symb_id) == eParameter); - int tsid_endo = datatree.symbol_table.getTypeSpecificID(varg->symb_id); - int tsid_param1 = datatree.symbol_table.getTypeSpecificID(param1_symb_id); - int tsid_param2 = datatree.symbol_table.getTypeSpecificID(param2_symb_id); - output << "ss_param_2nd_deriv(" << tsid_endo+1 << "," << tsid_param1+1 - << "," << tsid_param2+1 << ")"; - } - return; - case oExpectation: - output << "EXPECTATION(" << expectation_information_set << ")"; - break; - case oErf: - output << "erf"; - break; - } - - bool close_parenthesis = false; - - /* Enclose argument with parentheses if: - - current opcode is not uminus, or - - current opcode is uminus and argument has lowest precedence - */ - if (op_code != oUminus - || (op_code == oUminus - && arg->precedenceJson(temporary_terms) < precedenceJson(temporary_terms))) - { - output << "("; - close_parenthesis = true; - } - - // Write argument - arg->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); - - if (close_parenthesis) - output << ")"; - - // Close parenthesis for uminus - if (op_code == oUminus) - output << ")"; -} - -void -UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - // If node is a temporary term - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (output_type == oMatlabDynamicModelSparse) - output << "T" << idx << "(it_)"; - else - output << "T" << idx; - return; - } - - // Always put parenthesis around uminus nodes - if (op_code == oUminus) - output << LEFT_PAR(output_type); - - switch (op_code) - { - case oUminus: - output << "-"; - break; - case oExp: - output << "exp"; - break; - case oLog: - if (IS_LATEX(output_type)) - output << "\\log"; - else - output << "log"; - break; - case oLog10: - if (IS_LATEX(output_type)) - output << "\\log_{10}"; - else - output << "log10"; - break; - case oCos: - output << "cos"; - break; - case oSin: - output << "sin"; - break; - case oTan: - output << "tan"; - break; - case oAcos: - output << "acos"; - break; - case oAsin: - output << "asin"; - break; - case oAtan: - output << "atan"; - break; - case oCosh: - output << "cosh"; - break; - case oSinh: - output << "sinh"; - break; - case oTanh: - output << "tanh"; - break; - case oAcosh: - output << "acosh"; - break; - case oAsinh: - output << "asinh"; - break; - case oAtanh: - output << "atanh"; - break; - case oSqrt: - output << "sqrt"; - break; - case oAbs: - output << "abs"; - break; - case oSign: - if (output_type == oCDynamicModel || output_type == oCStaticModel) - output << "copysign"; - else - output << "sign"; - break; - case oSteadyState: - ExprNodeOutputType new_output_type; - switch (output_type) - { - case oMatlabDynamicModel: - new_output_type = oMatlabDynamicSteadyStateOperator; - break; - case oLatexDynamicModel: - new_output_type = oLatexDynamicSteadyStateOperator; - break; - case oCDynamicModel: - new_output_type = oCDynamicSteadyStateOperator; - break; - case oJuliaDynamicModel: - new_output_type = oJuliaDynamicSteadyStateOperator; - break; - case oMatlabDynamicModelSparse: - new_output_type = oMatlabDynamicSparseSteadyStateOperator; - break; - default: - new_output_type = output_type; - break; - } - output << "("; - arg->writeOutput(output, new_output_type, temporary_terms, tef_terms); - output << ")"; - return; - case oSteadyStateParamDeriv: - { - VariableNode *varg = dynamic_cast(arg); - assert(varg != NULL); - assert(datatree.symbol_table.getType(varg->symb_id) == eEndogenous); - assert(datatree.symbol_table.getType(param1_symb_id) == eParameter); - int tsid_endo = datatree.symbol_table.getTypeSpecificID(varg->symb_id); - int tsid_param = datatree.symbol_table.getTypeSpecificID(param1_symb_id); - assert(IS_MATLAB(output_type)); - output << "ss_param_deriv(" << tsid_endo+1 << "," << tsid_param+1 << ")"; - } - return; - case oSteadyStateParam2ndDeriv: - { - VariableNode *varg = dynamic_cast(arg); - assert(varg != NULL); - assert(datatree.symbol_table.getType(varg->symb_id) == eEndogenous); - assert(datatree.symbol_table.getType(param1_symb_id) == eParameter); - assert(datatree.symbol_table.getType(param2_symb_id) == eParameter); - int tsid_endo = datatree.symbol_table.getTypeSpecificID(varg->symb_id); - int tsid_param1 = datatree.symbol_table.getTypeSpecificID(param1_symb_id); - int tsid_param2 = datatree.symbol_table.getTypeSpecificID(param2_symb_id); - assert(IS_MATLAB(output_type)); - output << "ss_param_2nd_deriv(" << tsid_endo+1 << "," << tsid_param1+1 - << "," << tsid_param2+1 << ")"; - } - return; - case oExpectation: - if (!IS_LATEX(output_type)) - { - cerr << "UnaryOpNode::writeOutput: not implemented on oExpectation" << endl; - exit(EXIT_FAILURE); - } - output << "\\mathbb{E}_{t"; - if (expectation_information_set != 0) - { - if (expectation_information_set > 0) - output << "+"; - output << expectation_information_set; - } - output << "}"; - break; - case oErf: - output << "erf"; - break; - } - - bool close_parenthesis = false; - - /* Enclose argument with parentheses if: - - current opcode is not uminus, or - - current opcode is uminus and argument has lowest precedence - */ - if (op_code != oUminus - || (op_code == oUminus - && arg->precedence(output_type, temporary_terms) < precedence(output_type, temporary_terms))) - { - output << LEFT_PAR(output_type); - if (op_code == oSign && (output_type == oCDynamicModel || output_type == oCStaticModel)) - output << "1.0,"; - close_parenthesis = true; - } - - // Write argument - arg->writeOutput(output, output_type, temporary_terms, tef_terms); - - if (close_parenthesis) - output << RIGHT_PAR(output_type); - - // Close parenthesis for uminus - if (op_code == oUminus) - output << RIGHT_PAR(output_type); -} - -void -UnaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - arg->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms); -} - -void -UnaryOpNode::writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - arg->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms, isdynamic); -} - -void -UnaryOpNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - arg->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, - dynamic, steady_dynamic, tef_terms); -} - -double -UnaryOpNode::eval_opcode(UnaryOpcode op_code, double v) throw (EvalException, EvalExternalFunctionException) -{ - switch (op_code) - { - case oUminus: - return (-v); - case oExp: - return (exp(v)); - case oLog: - return (log(v)); - case oLog10: - return (log10(v)); - case oCos: - return (cos(v)); - case oSin: - return (sin(v)); - case oTan: - return (tan(v)); - case oAcos: - return (acos(v)); - case oAsin: - return (asin(v)); - case oAtan: - return (atan(v)); - case oCosh: - return (cosh(v)); - case oSinh: - return (sinh(v)); - case oTanh: - return (tanh(v)); - case oAcosh: - return (acosh(v)); - case oAsinh: - return (asinh(v)); - case oAtanh: - return (atanh(v)); - case oSqrt: - return (sqrt(v)); - case oAbs: - return (abs(v)); - case oSign: - return (v > 0) ? 1 : ((v < 0) ? -1 : 0); - case oSteadyState: - return (v); - case oSteadyStateParamDeriv: - case oSteadyStateParam2ndDeriv: - case oExpectation: - throw EvalException(); - case oErf: - return (erf(v)); - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -double -UnaryOpNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) -{ - double v = arg->eval(eval_context); - - return eval_opcode(op_code, v); -} - -void -UnaryOpNode::compile(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (dynamic) - { - map_idx_t::const_iterator ii = map_idx.find(idx); - FLDT_ fldt(ii->second); - fldt.write(CompileCode, instruction_number); - } - else - { - map_idx_t::const_iterator ii = map_idx.find(idx); - FLDST_ fldst(ii->second); - fldst.write(CompileCode, instruction_number); - } - return; - } - if (op_code == oSteadyState) - arg->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, true, tef_terms); - else - { - arg->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms); - FUNARY_ funary(op_code); - funary.write(CompileCode, instruction_number); - } -} - -void -UnaryOpNode::collectDynamicVariables(SymbolType type_arg, set > &result) const -{ - arg->collectDynamicVariables(type_arg, result); -} - -pair -UnaryOpNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const -{ - pair res = arg->normalizeEquation(var_endo, List_of_Op_RHS); - int is_endogenous_present = res.first; - expr_t New_expr_t = res.second; - - if (is_endogenous_present == 2) /* The equation could not be normalized and the process is given-up*/ - return (make_pair(2, (expr_t) NULL)); - else if (is_endogenous_present) /* The argument of the function contains the current values of - the endogenous variable associated to the equation. - In order to normalized, we have to apply the invert function to the RHS.*/ - { - switch (op_code) - { - case oUminus: - List_of_Op_RHS.push_back(make_pair(oUminus, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oExp: - List_of_Op_RHS.push_back(make_pair(oLog, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oLog: - List_of_Op_RHS.push_back(make_pair(oExp, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oLog10: - List_of_Op_RHS.push_back(make_pair(oPower, make_pair((expr_t) NULL, datatree.AddNonNegativeConstant("10")))); - return (make_pair(1, (expr_t) NULL)); - case oCos: - List_of_Op_RHS.push_back(make_pair(oAcos, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oSin: - List_of_Op_RHS.push_back(make_pair(oAsin, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oTan: - List_of_Op_RHS.push_back(make_pair(oAtan, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oAcos: - List_of_Op_RHS.push_back(make_pair(oCos, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oAsin: - List_of_Op_RHS.push_back(make_pair(oSin, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oAtan: - List_of_Op_RHS.push_back(make_pair(oTan, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oCosh: - List_of_Op_RHS.push_back(make_pair(oAcosh, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oSinh: - List_of_Op_RHS.push_back(make_pair(oAsinh, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oTanh: - List_of_Op_RHS.push_back(make_pair(oAtanh, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oAcosh: - List_of_Op_RHS.push_back(make_pair(oCosh, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oAsinh: - List_of_Op_RHS.push_back(make_pair(oSinh, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oAtanh: - List_of_Op_RHS.push_back(make_pair(oTanh, make_pair((expr_t) NULL, (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - case oSqrt: - List_of_Op_RHS.push_back(make_pair(oPower, make_pair((expr_t) NULL, datatree.Two))); - return (make_pair(1, (expr_t) NULL)); - case oAbs: - return (make_pair(2, (expr_t) NULL)); - case oSign: - return (make_pair(2, (expr_t) NULL)); - case oSteadyState: - return (make_pair(2, (expr_t) NULL)); - case oErf: - return (make_pair(2, (expr_t) NULL)); - default: - cerr << "Unary operator not handled during the normalization process" << endl; - return (make_pair(2, (expr_t) NULL)); // Could not be normalized - } - } - else - { /* If the argument of the function do not contain the current values of the endogenous variable - related to the equation, the function with its argument is stored in the RHS*/ - switch (op_code) - { - case oUminus: - return (make_pair(0, datatree.AddUMinus(New_expr_t))); - case oExp: - return (make_pair(0, datatree.AddExp(New_expr_t))); - case oLog: - return (make_pair(0, datatree.AddLog(New_expr_t))); - case oLog10: - return (make_pair(0, datatree.AddLog10(New_expr_t))); - case oCos: - return (make_pair(0, datatree.AddCos(New_expr_t))); - case oSin: - return (make_pair(0, datatree.AddSin(New_expr_t))); - case oTan: - return (make_pair(0, datatree.AddTan(New_expr_t))); - case oAcos: - return (make_pair(0, datatree.AddAcos(New_expr_t))); - case oAsin: - return (make_pair(0, datatree.AddAsin(New_expr_t))); - case oAtan: - return (make_pair(0, datatree.AddAtan(New_expr_t))); - case oCosh: - return (make_pair(0, datatree.AddCosh(New_expr_t))); - case oSinh: - return (make_pair(0, datatree.AddSinh(New_expr_t))); - case oTanh: - return (make_pair(0, datatree.AddTanh(New_expr_t))); - case oAcosh: - return (make_pair(0, datatree.AddAcosh(New_expr_t))); - case oAsinh: - return (make_pair(0, datatree.AddAsinh(New_expr_t))); - case oAtanh: - return (make_pair(0, datatree.AddAtanh(New_expr_t))); - case oSqrt: - return (make_pair(0, datatree.AddSqrt(New_expr_t))); - case oAbs: - return (make_pair(0, datatree.AddAbs(New_expr_t))); - case oSign: - return (make_pair(0, datatree.AddSign(New_expr_t))); - case oSteadyState: - return (make_pair(0, datatree.AddSteadyState(New_expr_t))); - case oErf: - return (make_pair(0, datatree.AddErf(New_expr_t))); - default: - cerr << "Unary operator not handled during the normalization process" << endl; - return (make_pair(2, (expr_t) NULL)); // Could not be normalized - } - } - cerr << "UnaryOpNode::normalizeEquation: impossible case" << endl; - exit(EXIT_FAILURE); -} - -expr_t -UnaryOpNode::getChainRuleDerivative(int deriv_id, const map &recursive_variables) -{ - expr_t darg = arg->getChainRuleDerivative(deriv_id, recursive_variables); - return composeDerivatives(darg, deriv_id); -} - -expr_t -UnaryOpNode::buildSimilarUnaryOpNode(expr_t alt_arg, DataTree &alt_datatree) const -{ - switch (op_code) - { - case oUminus: - return alt_datatree.AddUMinus(alt_arg); - case oExp: - return alt_datatree.AddExp(alt_arg); - case oLog: - return alt_datatree.AddLog(alt_arg); - case oLog10: - return alt_datatree.AddLog10(alt_arg); - case oCos: - return alt_datatree.AddCos(alt_arg); - case oSin: - return alt_datatree.AddSin(alt_arg); - case oTan: - return alt_datatree.AddTan(alt_arg); - case oAcos: - return alt_datatree.AddAcos(alt_arg); - case oAsin: - return alt_datatree.AddAsin(alt_arg); - case oAtan: - return alt_datatree.AddAtan(alt_arg); - case oCosh: - return alt_datatree.AddCosh(alt_arg); - case oSinh: - return alt_datatree.AddSinh(alt_arg); - case oTanh: - return alt_datatree.AddTanh(alt_arg); - case oAcosh: - return alt_datatree.AddAcosh(alt_arg); - case oAsinh: - return alt_datatree.AddAsinh(alt_arg); - case oAtanh: - return alt_datatree.AddAtanh(alt_arg); - case oSqrt: - return alt_datatree.AddSqrt(alt_arg); - case oAbs: - return alt_datatree.AddAbs(alt_arg); - case oSign: - return alt_datatree.AddSign(alt_arg); - case oSteadyState: - return alt_datatree.AddSteadyState(alt_arg); - case oSteadyStateParamDeriv: - cerr << "UnaryOpNode::buildSimilarUnaryOpNode: oSteadyStateParamDeriv can't be translated" << endl; - exit(EXIT_FAILURE); - case oSteadyStateParam2ndDeriv: - cerr << "UnaryOpNode::buildSimilarUnaryOpNode: oSteadyStateParam2ndDeriv can't be translated" << endl; - exit(EXIT_FAILURE); - case oExpectation: - return alt_datatree.AddExpectation(expectation_information_set, alt_arg); - case oErf: - return alt_datatree.AddErf(alt_arg); - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -expr_t -UnaryOpNode::toStatic(DataTree &static_datatree) const -{ - expr_t sarg = arg->toStatic(static_datatree); - return buildSimilarUnaryOpNode(sarg, static_datatree); -} - -void -UnaryOpNode::computeXrefs(EquationInfo &ei) const -{ - arg->computeXrefs(ei); -} - -expr_t -UnaryOpNode::cloneDynamic(DataTree &dynamic_datatree) const -{ - expr_t substarg = arg->cloneDynamic(dynamic_datatree); - return buildSimilarUnaryOpNode(substarg, dynamic_datatree); -} - -int -UnaryOpNode::maxEndoLead() const -{ - return arg->maxEndoLead(); -} - -int -UnaryOpNode::maxExoLead() const -{ - return arg->maxExoLead(); -} - -int -UnaryOpNode::maxEndoLag() const -{ - return arg->maxEndoLag(); -} - -int -UnaryOpNode::maxExoLag() const -{ - return arg->maxExoLag(); -} - -int -UnaryOpNode::maxLead() const -{ - return arg->maxLead(); -} - -expr_t -UnaryOpNode::decreaseLeadsLags(int n) const -{ - expr_t argsubst = arg->decreaseLeadsLags(n); - return buildSimilarUnaryOpNode(argsubst, datatree); -} - -expr_t -UnaryOpNode::decreaseLeadsLagsPredeterminedVariables() const -{ - expr_t argsubst = arg->decreaseLeadsLagsPredeterminedVariables(); - return buildSimilarUnaryOpNode(argsubst, datatree); -} - -expr_t -UnaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const -{ - if (op_code == oUminus || deterministic_model) - { - expr_t argsubst = arg->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); - return buildSimilarUnaryOpNode(argsubst, datatree); - } - else - { - if (maxEndoLead() >= 2) - return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs); - else - return const_cast(this); - } -} - -expr_t -UnaryOpNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const -{ - expr_t argsubst = arg->substituteEndoLagGreaterThanTwo(subst_table, neweqs); - return buildSimilarUnaryOpNode(argsubst, datatree); -} - -expr_t -UnaryOpNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const -{ - if (op_code == oUminus || deterministic_model) - { - expr_t argsubst = arg->substituteExoLead(subst_table, neweqs, deterministic_model); - return buildSimilarUnaryOpNode(argsubst, datatree); - } - else - { - if (maxExoLead() >= 1) - return createExoLeadAuxiliaryVarForMyself(subst_table, neweqs); - else - return const_cast(this); - } -} - -expr_t -UnaryOpNode::substituteExoLag(subst_table_t &subst_table, vector &neweqs) const -{ - expr_t argsubst = arg->substituteExoLag(subst_table, neweqs); - return buildSimilarUnaryOpNode(argsubst, datatree); -} - -expr_t -UnaryOpNode::substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const -{ - if (op_code == oExpectation) - { - subst_table_t::iterator it = subst_table.find(const_cast(this)); - if (it != subst_table.end()) - return const_cast(it->second); - - //Arriving here, we need to create an auxiliary variable for this Expectation Operator: - //AUX_EXPECT_(LEAD/LAG)_(period)_(arg.idx) OR - //AUX_EXPECT_(info_set_name)_(arg.idx) - int symb_id = datatree.symbol_table.addExpectationAuxiliaryVar(expectation_information_set, arg->idx, arg); - expr_t newAuxE = datatree.AddVariable(symb_id, 0); - - if (partial_information_model && expectation_information_set == 0) - if (dynamic_cast(arg) == NULL) - { - cerr << "ERROR: In Partial Information models, EXPECTATION(0)(X) " - << "can only be used when X is a single variable." << endl; - exit(EXIT_FAILURE); - } - - //take care of any nested expectation operators by calling arg->substituteExpectation(.), then decreaseLeadsLags for this oExpectation operator - //arg(lag-period) (holds entire subtree of arg(lag-period) - expr_t substexpr = (arg->substituteExpectation(subst_table, neweqs, partial_information_model))->decreaseLeadsLags(expectation_information_set); - assert(substexpr != NULL); - neweqs.push_back(dynamic_cast(datatree.AddEqual(newAuxE, substexpr))); //AUXE_period_arg.idx = arg(lag-period) - newAuxE = datatree.AddVariable(symb_id, expectation_information_set); - - assert(dynamic_cast(newAuxE) != NULL); - subst_table[this] = dynamic_cast(newAuxE); - return newAuxE; - } - else - { - expr_t argsubst = arg->substituteExpectation(subst_table, neweqs, partial_information_model); - return buildSimilarUnaryOpNode(argsubst, datatree); - } -} - -expr_t -UnaryOpNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const -{ - expr_t argsubst = arg->differentiateForwardVars(subset, subst_table, neweqs); - return buildSimilarUnaryOpNode(argsubst, datatree); -} - -bool -UnaryOpNode::isNumConstNodeEqualTo(double value) const -{ - return false; -} - -bool -UnaryOpNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const -{ - return false; -} - -bool -UnaryOpNode::containsEndogenous(void) const -{ - return arg->containsEndogenous(); -} - -bool -UnaryOpNode::containsExogenous() const -{ - return arg->containsExogenous(); -} - -expr_t -UnaryOpNode::replaceTrendVar() const -{ - expr_t argsubst = arg->replaceTrendVar(); - return buildSimilarUnaryOpNode(argsubst, datatree); -} - -expr_t -UnaryOpNode::detrend(int symb_id, bool log_trend, expr_t trend) const -{ - expr_t argsubst = arg->detrend(symb_id, log_trend, trend); - return buildSimilarUnaryOpNode(argsubst, datatree); -} - -expr_t -UnaryOpNode::removeTrendLeadLag(map trend_symbols_map) const -{ - expr_t argsubst = arg->removeTrendLeadLag(trend_symbols_map); - return buildSimilarUnaryOpNode(argsubst, datatree); -} - -bool -UnaryOpNode::isInStaticForm() const -{ - if (op_code == oSteadyState || op_code == oSteadyStateParamDeriv - || op_code == oSteadyStateParam2ndDeriv - || op_code == oExpectation) - return false; - else - return arg->isInStaticForm(); -} - -expr_t -UnaryOpNode::substituteStaticAuxiliaryVariable() const -{ - expr_t argsubst = arg->substituteStaticAuxiliaryVariable(); - if (op_code == oExpectation) - return argsubst; - else - return buildSimilarUnaryOpNode(argsubst, datatree); -} - -BinaryOpNode::BinaryOpNode(DataTree &datatree_arg, const expr_t arg1_arg, - BinaryOpcode op_code_arg, const expr_t arg2_arg) : - ExprNode(datatree_arg), - arg1(arg1_arg), - arg2(arg2_arg), - op_code(op_code_arg), - powerDerivOrder(0) -{ - datatree.binary_op_node_map[make_pair(make_pair(make_pair(arg1, arg2), powerDerivOrder), op_code)] = this; -} - -BinaryOpNode::BinaryOpNode(DataTree &datatree_arg, const expr_t arg1_arg, - BinaryOpcode op_code_arg, const expr_t arg2_arg, int powerDerivOrder_arg) : - ExprNode(datatree_arg), - arg1(arg1_arg), - arg2(arg2_arg), - op_code(op_code_arg), - powerDerivOrder(powerDerivOrder_arg) -{ - assert(powerDerivOrder >= 0); - datatree.binary_op_node_map[make_pair(make_pair(make_pair(arg1, arg2), powerDerivOrder), op_code)] = this; -} - -void -BinaryOpNode::prepareForDerivation() -{ - if (preparedForDerivation) - return; - - preparedForDerivation = true; - - arg1->prepareForDerivation(); - arg2->prepareForDerivation(); - - // Non-null derivatives are the union of those of the arguments - // Compute set union of arg1->non_null_derivatives and arg2->non_null_derivatives - set_union(arg1->non_null_derivatives.begin(), - arg1->non_null_derivatives.end(), - arg2->non_null_derivatives.begin(), - arg2->non_null_derivatives.end(), - inserter(non_null_derivatives, non_null_derivatives.begin())); -} - -expr_t -BinaryOpNode::getNonZeroPartofEquation() const -{ - assert(arg1 == datatree.Zero || arg2 == datatree.Zero); - if (arg1 == datatree.Zero) - return arg2; - return arg1; -} - -expr_t -BinaryOpNode::composeDerivatives(expr_t darg1, expr_t darg2) -{ - expr_t t11, t12, t13, t14, t15; - - switch (op_code) - { - case oPlus: - return datatree.AddPlus(darg1, darg2); - case oMinus: - return datatree.AddMinus(darg1, darg2); - case oTimes: - t11 = datatree.AddTimes(darg1, arg2); - t12 = datatree.AddTimes(darg2, arg1); - return datatree.AddPlus(t11, t12); - case oDivide: - if (darg2 != datatree.Zero) - { - t11 = datatree.AddTimes(darg1, arg2); - t12 = datatree.AddTimes(darg2, arg1); - t13 = datatree.AddMinus(t11, t12); - t14 = datatree.AddTimes(arg2, arg2); - return datatree.AddDivide(t13, t14); - } - else - return datatree.AddDivide(darg1, arg2); - case oLess: - case oGreater: - case oLessEqual: - case oGreaterEqual: - case oEqualEqual: - case oDifferent: - return datatree.Zero; - case oPower: - if (darg2 == datatree.Zero) - if (darg1 == datatree.Zero) - return datatree.Zero; - else - if (dynamic_cast(arg2) != NULL) - { - t11 = datatree.AddMinus(arg2, datatree.One); - t12 = datatree.AddPower(arg1, t11); - t13 = datatree.AddTimes(arg2, t12); - return datatree.AddTimes(darg1, t13); - } - else - return datatree.AddTimes(darg1, datatree.AddPowerDeriv(arg1, arg2, powerDerivOrder + 1)); - else - { - t11 = datatree.AddLog(arg1); - t12 = datatree.AddTimes(darg2, t11); - t13 = datatree.AddTimes(darg1, arg2); - t14 = datatree.AddDivide(t13, arg1); - t15 = datatree.AddPlus(t12, t14); - return datatree.AddTimes(t15, this); - } - case oPowerDeriv: - if (darg2 == datatree.Zero) - return datatree.AddTimes(darg1, datatree.AddPowerDeriv(arg1, arg2, powerDerivOrder + 1)); - else - { - t11 = datatree.AddTimes(darg2, datatree.AddLog(arg1)); - t12 = datatree.AddMinus(arg2, datatree.AddPossiblyNegativeConstant(powerDerivOrder)); - t13 = datatree.AddTimes(darg1, t12); - t14 = datatree.AddDivide(t13, arg1); - t15 = datatree.AddPlus(t11, t14); - expr_t f = datatree.AddPower(arg1, t12); - expr_t first_part = datatree.AddTimes(f, t15); - - for (int i = 0; i < powerDerivOrder; i++) - first_part = datatree.AddTimes(first_part, datatree.AddMinus(arg2, datatree.AddPossiblyNegativeConstant(i))); - - t13 = datatree.Zero; - for (int i = 0; i < powerDerivOrder; i++) - { - t11 = datatree.One; - for (int j = 0; j < powerDerivOrder; j++) - if (i != j) - { - t12 = datatree.AddMinus(arg2, datatree.AddPossiblyNegativeConstant(j)); - t11 = datatree.AddTimes(t11, t12); - } - t13 = datatree.AddPlus(t13, t11); - } - t13 = datatree.AddTimes(darg2, t13); - t14 = datatree.AddTimes(f, t13); - return datatree.AddPlus(first_part, t14); - } - case oMax: - t11 = datatree.AddGreater(arg1, arg2); - t12 = datatree.AddTimes(t11, darg1); - t13 = datatree.AddMinus(datatree.One, t11); - t14 = datatree.AddTimes(t13, darg2); - return datatree.AddPlus(t14, t12); - case oMin: - t11 = datatree.AddGreater(arg2, arg1); - t12 = datatree.AddTimes(t11, darg1); - t13 = datatree.AddMinus(datatree.One, t11); - t14 = datatree.AddTimes(t13, darg2); - return datatree.AddPlus(t14, t12); - case oEqual: - return datatree.AddMinus(darg1, darg2); - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -expr_t -BinaryOpNode::unpackPowerDeriv() const -{ - if (op_code != oPowerDeriv) - return const_cast(this); - - expr_t front = datatree.One; - for (int i = 0; i < powerDerivOrder; i++) - front = datatree.AddTimes(front, - datatree.AddMinus(arg2, - datatree.AddPossiblyNegativeConstant(i))); - expr_t tmp = datatree.AddPower(arg1, - datatree.AddMinus(arg2, - datatree.AddPossiblyNegativeConstant(powerDerivOrder))); - return datatree.AddTimes(front, tmp); -} - -expr_t -BinaryOpNode::computeDerivative(int deriv_id) -{ - expr_t darg1 = arg1->getDerivative(deriv_id); - expr_t darg2 = arg2->getDerivative(deriv_id); - return composeDerivatives(darg1, darg2); -} - -int -BinaryOpNode::precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - // A temporary term behaves as a variable - if (it != temporary_terms.end()) - return 100; - - switch (op_code) - { - case oEqual: - return 0; - case oEqualEqual: - case oDifferent: - return 1; - case oLessEqual: - case oGreaterEqual: - case oLess: - case oGreater: - return 2; - case oPlus: - case oMinus: - return 3; - case oTimes: - case oDivide: - return 4; - case oPower: - case oPowerDeriv: - if (IS_C(output_type)) - // In C, power operator is of the form pow(a, b) - return 100; - else - return 5; - case oMin: - case oMax: - return 100; - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -int -BinaryOpNode::precedenceJson(const temporary_terms_t &temporary_terms) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - // A temporary term behaves as a variable - if (it != temporary_terms.end()) - return 100; - - switch (op_code) - { - case oEqual: - return 0; - case oEqualEqual: - case oDifferent: - return 1; - case oLessEqual: - case oGreaterEqual: - case oLess: - case oGreater: - return 2; - case oPlus: - case oMinus: - return 3; - case oTimes: - case oDivide: - return 4; - case oPower: - case oPowerDeriv: - return 5; - case oMin: - case oMax: - return 100; - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -int -BinaryOpNode::cost(const map &temp_terms_map, bool is_matlab) const -{ - // For a temporary term, the cost is null - for (map::const_iterator it = temp_terms_map.begin(); - it != temp_terms_map.end(); it++) - if (it->second.find(const_cast(this)) != it->second.end()) - return 0; - - int arg_cost = arg1->cost(temp_terms_map, is_matlab) + arg2->cost(temp_terms_map, is_matlab); - - return cost(arg_cost, is_matlab); -} - -int -BinaryOpNode::cost(const temporary_terms_t &temporary_terms, bool is_matlab) const -{ - // For a temporary term, the cost is null - if (temporary_terms.find(const_cast(this)) != temporary_terms.end()) - return 0; - - int arg_cost = arg1->cost(temporary_terms, is_matlab) + arg2->cost(temporary_terms, is_matlab); - - return cost(arg_cost, is_matlab); -} - -int -BinaryOpNode::cost(int cost, bool is_matlab) const -{ - if (is_matlab) - // Cost for Matlab files - switch (op_code) - { - case oLess: - case oGreater: - case oLessEqual: - case oGreaterEqual: - case oEqualEqual: - case oDifferent: - return cost + 60; - case oPlus: - case oMinus: - case oTimes: - return cost + 90; - case oMax: - case oMin: - return cost + 110; - case oDivide: - return cost + 990; - case oPower: - case oPowerDeriv: - return cost + (MIN_COST_MATLAB/2+1); - case oEqual: - return cost; - } - else - // Cost for C files - switch (op_code) - { - case oLess: - case oGreater: - case oLessEqual: - case oGreaterEqual: - case oEqualEqual: - case oDifferent: - return cost + 2; - case oPlus: - case oMinus: - case oTimes: - return cost + 4; - case oMax: - case oMin: - return cost + 5; - case oDivide: - return cost + 15; - case oPower: - return cost + 520; - case oPowerDeriv: - return cost + (MIN_COST_C/2+1);; - case oEqual: - return cost; - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -void -BinaryOpNode::computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const -{ - expr_t this2 = const_cast(this); - map >::iterator it = reference_count.find(this2); - if (it == reference_count.end()) - { - // If this node has never been encountered, set its ref count to one, - // and travel through its children - reference_count[this2] = make_pair(1, tr); - arg1->computeTemporaryTerms(reference_count, temp_terms_map, is_matlab, tr); - arg2->computeTemporaryTerms(reference_count, temp_terms_map, is_matlab, tr); - } - else - { - /* If the node has already been encountered, increment its ref count - and declare it as a temporary term if it is too costly (except if it is - an equal node: we don't want them as temporary terms) */ - reference_count[this2] = make_pair(it->second.first + 1, it->second.second);; - if (reference_count[this2].first * cost(temp_terms_map, is_matlab) > MIN_COST(is_matlab) - && op_code != oEqual) - temp_terms_map[reference_count[this2].second].insert(this2); - } -} - -void -BinaryOpNode::computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector > &v_temporary_terms, - int equation) const -{ - expr_t this2 = const_cast(this); - map::iterator it = reference_count.find(this2); - if (it == reference_count.end()) - { - reference_count[this2] = 1; - first_occurence[this2] = make_pair(Curr_block, equation); - arg1->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation); - arg2->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation); - } - else - { - reference_count[this2]++; - if (reference_count[this2] * cost(temporary_terms, false) > MIN_COST_C - && op_code != oEqual) - { - temporary_terms.insert(this2); - v_temporary_terms[first_occurence[this2].first][first_occurence[this2].second].insert(this2); - } - } -} - -double -BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2, int derivOrder) throw (EvalException, EvalExternalFunctionException) -{ - switch (op_code) - { - case oPlus: - return (v1 + v2); - case oMinus: - return (v1 - v2); - case oTimes: - return (v1 * v2); - case oDivide: - return (v1 / v2); - case oPower: - return (pow(v1, v2)); - case oPowerDeriv: - if (fabs(v1) < NEAR_ZERO && v2 > 0 - && derivOrder > v2 - && fabs(v2-nearbyint(v2)) < NEAR_ZERO) - return 0.0; - else - { - double dxp = pow(v1, v2-derivOrder); - for (int i = 0; i < derivOrder; i++) - dxp *= v2--; - return dxp; - } - case oMax: - if (v1 < v2) - return v2; - else - return v1; - case oMin: - if (v1 > v2) - return v2; - else - return v1; - case oLess: - return (v1 < v2); - case oGreater: - return (v1 > v2); - case oLessEqual: - return (v1 <= v2); - case oGreaterEqual: - return (v1 >= v2); - case oEqualEqual: - return (v1 == v2); - case oDifferent: - return (v1 != v2); - case oEqual: - throw EvalException(); - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -double -BinaryOpNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) -{ - double v1 = arg1->eval(eval_context); - double v2 = arg2->eval(eval_context); - - return eval_opcode(v1, op_code, v2, powerDerivOrder); -} - -void -BinaryOpNode::compile(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - // If current node is a temporary term - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (dynamic) - { - map_idx_t::const_iterator ii = map_idx.find(idx); - FLDT_ fldt(ii->second); - fldt.write(CompileCode, instruction_number); - } - else - { - map_idx_t::const_iterator ii = map_idx.find(idx); - FLDST_ fldst(ii->second); - fldst.write(CompileCode, instruction_number); - } - return; - } - if (op_code == oPowerDeriv) - { - FLDC_ fldc(powerDerivOrder); - fldc.write(CompileCode, instruction_number); - } - arg1->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms); - arg2->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms); - FBINARY_ fbinary(op_code); - fbinary.write(CompileCode, instruction_number); -} - -void -BinaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - temporary_terms_inuse.insert(idx); - else - { - arg1->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block); - arg2->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block); - } -} - -bool -BinaryOpNode::containsExternalFunction() const -{ - return arg1->containsExternalFunction() - || arg2->containsExternalFunction(); -} - -void -BinaryOpNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - // If current node is a temporary term - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - output << "T" << idx; - return; - } - - if (op_code == oMax || op_code == oMin) - { - switch (op_code) - { - case oMax: - output << "max("; - break; - case oMin: - output << "min("; - break; - default: - ; - } - arg1->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); - output << ","; - arg2->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); - output << ")"; - return; - } - - if (op_code == oPowerDeriv) - { - output << "get_power_deriv("; - arg1->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); - output << ","; - arg2->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); - output << "," << powerDerivOrder << ")"; - return; - } - - int prec = precedenceJson(temporary_terms); - - bool close_parenthesis = false; - - // If left argument has a lower precedence, or if current and left argument are both power operators, - // add parenthesis around left argument - BinaryOpNode *barg1 = dynamic_cast(arg1); - if (arg1->precedenceJson(temporary_terms) < prec - || (op_code == oPower && barg1 != NULL && barg1->op_code == oPower)) - { - output << "("; - close_parenthesis = true; - } - - // Write left argument - arg1->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); - - if (close_parenthesis) - output << ")"; - - // Write current operator symbol - switch (op_code) - { - case oPlus: - output << "+"; - break; - case oMinus: - output << "-"; - break; - case oTimes: - output << "*"; - break; - case oDivide: - output << "/"; - break; - case oPower: - output << "^"; - break; - case oLess: - output << "<"; - break; - case oGreater: - output << ">"; - break; - case oLessEqual: - output << "<="; - break; - case oGreaterEqual: - output << ">="; - break; - case oEqualEqual: - output << "=="; - break; - case oDifferent: - output << "!="; - break; - case oEqual: - output << "="; - break; - default: - ; - } - - close_parenthesis = false; - - /* Add parenthesis around right argument if: - - its precedence is lower than those of the current node - - it is a power operator and current operator is also a power operator - - it is a minus operator with same precedence than current operator - - it is a divide operator with same precedence than current operator */ - BinaryOpNode *barg2 = dynamic_cast(arg2); - int arg2_prec = arg2->precedenceJson(temporary_terms); - if (arg2_prec < prec - || (op_code == oPower && barg2 != NULL && barg2->op_code == oPower) - || (op_code == oMinus && arg2_prec == prec) - || (op_code == oDivide && arg2_prec == prec)) - { - output << "("; - close_parenthesis = true; - } - - // Write right argument - arg2->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); - - if (close_parenthesis) - output << ")"; -} - -void -BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - // If current node is a temporary term - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (output_type == oMatlabDynamicModelSparse) - output << "T" << idx << "(it_)"; - else - output << "T" << idx; - return; - } - - // Treat derivative of Power - if (op_code == oPowerDeriv) - { - if (IS_LATEX(output_type)) - unpackPowerDeriv()->writeOutput(output, output_type, temporary_terms, tef_terms); - else - { - if (output_type == oJuliaStaticModel || output_type == oJuliaDynamicModel) - output << "get_power_deriv("; - else - output << "getPowerDeriv("; - arg1->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ","; - arg2->writeOutput(output, output_type, temporary_terms, tef_terms); - output << "," << powerDerivOrder << ")"; - } - return; - } - - // Treat special case of power operator in C, and case of max and min operators - if ((op_code == oPower && IS_C(output_type)) || op_code == oMax || op_code == oMin) - { - switch (op_code) - { - case oPower: - output << "pow("; - break; - case oMax: - output << "max("; - break; - case oMin: - output << "min("; - break; - default: - ; - } - arg1->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ","; - arg2->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ")"; - return; - } - - int prec = precedence(output_type, temporary_terms); - - bool close_parenthesis = false; - - if (IS_LATEX(output_type) && op_code == oDivide) - output << "\\frac{"; - else - { - // If left argument has a lower precedence, or if current and left argument are both power operators, add parenthesis around left argument - BinaryOpNode *barg1 = dynamic_cast(arg1); - if (arg1->precedence(output_type, temporary_terms) < prec - || (op_code == oPower && barg1 != NULL && barg1->op_code == oPower)) - { - output << LEFT_PAR(output_type); - close_parenthesis = true; - } - } - - // Write left argument - arg1->writeOutput(output, output_type, temporary_terms, tef_terms); - - if (close_parenthesis) - output << RIGHT_PAR(output_type); - - if (IS_LATEX(output_type) && op_code == oDivide) - output << "}"; - - // Write current operator symbol - switch (op_code) - { - case oPlus: - output << "+"; - break; - case oMinus: - output << "-"; - break; - case oTimes: - if (IS_LATEX(output_type)) - output << "\\, "; - else - output << "*"; - break; - case oDivide: - if (!IS_LATEX(output_type)) - output << "/"; - break; - case oPower: - output << "^"; - break; - case oLess: - output << "<"; - break; - case oGreater: - output << ">"; - break; - case oLessEqual: - if (IS_LATEX(output_type)) - output << "\\leq "; - else - output << "<="; - break; - case oGreaterEqual: - if (IS_LATEX(output_type)) - output << "\\geq "; - else - output << ">="; - break; - case oEqualEqual: - output << "=="; - break; - case oDifferent: - if (IS_MATLAB(output_type)) - output << "~="; - else - { - if (IS_C(output_type) || IS_JULIA(output_type)) - output << "!="; - else - output << "\\neq "; - } - break; - case oEqual: - output << "="; - break; - default: - ; - } - - close_parenthesis = false; - - if (IS_LATEX(output_type) && (op_code == oPower || op_code == oDivide)) - output << "{"; - else - { - /* Add parenthesis around right argument if: - - its precedence is lower than those of the current node - - it is a power operator and current operator is also a power operator - - it is a minus operator with same precedence than current operator - - it is a divide operator with same precedence than current operator */ - BinaryOpNode *barg2 = dynamic_cast(arg2); - int arg2_prec = arg2->precedence(output_type, temporary_terms); - if (arg2_prec < prec - || (op_code == oPower && barg2 != NULL && barg2->op_code == oPower && !IS_LATEX(output_type)) - || (op_code == oMinus && arg2_prec == prec) - || (op_code == oDivide && arg2_prec == prec && !IS_LATEX(output_type))) - { - output << LEFT_PAR(output_type); - close_parenthesis = true; - } - } - - // Write right argument - arg2->writeOutput(output, output_type, temporary_terms, tef_terms); - - if (IS_LATEX(output_type) && (op_code == oPower || op_code == oDivide)) - output << "}"; - - if (close_parenthesis) - output << RIGHT_PAR(output_type); -} - -void -BinaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - arg1->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms); - arg2->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms); -} - -void -BinaryOpNode::writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - arg1->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms, isdynamic); - arg2->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms, isdynamic); -} - -void -BinaryOpNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - arg1->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, - dynamic, steady_dynamic, tef_terms); - arg2->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, - dynamic, steady_dynamic, tef_terms); -} - -void -BinaryOpNode::collectDynamicVariables(SymbolType type_arg, set > &result) const -{ - arg1->collectDynamicVariables(type_arg, result); - arg2->collectDynamicVariables(type_arg, result); -} - -expr_t -BinaryOpNode::Compute_RHS(expr_t arg1, expr_t arg2, int op, int op_type) const -{ - temporary_terms_t temp; - switch (op_type) - { - case 0: /*Unary Operator*/ - switch (op) - { - case oUminus: - return (datatree.AddUMinus(arg1)); - break; - case oExp: - return (datatree.AddExp(arg1)); - break; - case oLog: - return (datatree.AddLog(arg1)); - break; - case oLog10: - return (datatree.AddLog10(arg1)); - break; - default: - cerr << "BinaryOpNode::Compute_RHS: case not handled"; - exit(EXIT_FAILURE); - } - break; - case 1: /*Binary Operator*/ - switch (op) - { - case oPlus: - return (datatree.AddPlus(arg1, arg2)); - break; - case oMinus: - return (datatree.AddMinus(arg1, arg2)); - break; - case oTimes: - return (datatree.AddTimes(arg1, arg2)); - break; - case oDivide: - return (datatree.AddDivide(arg1, arg2)); - break; - case oPower: - return (datatree.AddPower(arg1, arg2)); - break; - default: - cerr << "BinaryOpNode::Compute_RHS: case not handled"; - exit(EXIT_FAILURE); - } - break; - } - return ((expr_t) NULL); -} - -pair -BinaryOpNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const -{ - /* Checks if the current value of the endogenous variable related to the equation - is present in the arguments of the binary operator. */ - vector > > List_of_Op_RHS1, List_of_Op_RHS2; - int is_endogenous_present_1, is_endogenous_present_2; - pair res; - expr_t expr_t_1, expr_t_2; - res = arg1->normalizeEquation(var_endo, List_of_Op_RHS1); - is_endogenous_present_1 = res.first; - expr_t_1 = res.second; - - res = arg2->normalizeEquation(var_endo, List_of_Op_RHS2); - is_endogenous_present_2 = res.first; - expr_t_2 = res.second; - - /* If the two expressions contains the current value of the endogenous variable associated to the equation - the equation could not be normalized and the process is given-up.*/ - if (is_endogenous_present_1 == 2 || is_endogenous_present_2 == 2) - return (make_pair(2, (expr_t) NULL)); - else if (is_endogenous_present_1 && is_endogenous_present_2) - return (make_pair(2, (expr_t) NULL)); - else if (is_endogenous_present_1) /*If the current values of the endogenous variable associated to the equation - is present only in the first operand of the expression, we try to normalize the equation*/ - { - if (op_code == oEqual) /* The end of the normalization process : - All the operations needed to normalize the equation are applied. */ - { - pair > it; - int oo = List_of_Op_RHS1.size(); - for (int i = 0; i < oo; i++) - { - it = List_of_Op_RHS1.back(); - List_of_Op_RHS1.pop_back(); - if (it.second.first && !it.second.second) /*Binary operator*/ - expr_t_2 = Compute_RHS(expr_t_2, (BinaryOpNode *) it.second.first, it.first, 1); - else if (it.second.second && !it.second.first) /*Binary operator*/ - expr_t_2 = Compute_RHS(it.second.second, expr_t_2, it.first, 1); - else if (it.second.second && it.second.first) /*Binary operator*/ - expr_t_2 = Compute_RHS(it.second.first, it.second.second, it.first, 1); - else /*Unary operator*/ - expr_t_2 = Compute_RHS((UnaryOpNode *) expr_t_2, (UnaryOpNode *) it.second.first, it.first, 0); - } - } - else - List_of_Op_RHS = List_of_Op_RHS1; - } - else if (is_endogenous_present_2) - { - if (op_code == oEqual) - { - int oo = List_of_Op_RHS2.size(); - for (int i = 0; i < oo; i++) - { - pair > it; - it = List_of_Op_RHS2.back(); - List_of_Op_RHS2.pop_back(); - if (it.second.first && !it.second.second) /*Binary operator*/ - expr_t_1 = Compute_RHS((BinaryOpNode *) expr_t_1, (BinaryOpNode *) it.second.first, it.first, 1); - else if (it.second.second && !it.second.first) /*Binary operator*/ - expr_t_1 = Compute_RHS((BinaryOpNode *) it.second.second, (BinaryOpNode *) expr_t_1, it.first, 1); - else if (it.second.second && it.second.first) /*Binary operator*/ - expr_t_1 = Compute_RHS(it.second.first, it.second.second, it.first, 1); - else - expr_t_1 = Compute_RHS((UnaryOpNode *) expr_t_1, (UnaryOpNode *) it.second.first, it.first, 0); - } - } - else - List_of_Op_RHS = List_of_Op_RHS2; - } - switch (op_code) - { - case oPlus: - if (!is_endogenous_present_1 && !is_endogenous_present_2) - { - List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(datatree.AddPlus(expr_t_1, expr_t_2), (expr_t) NULL))); - return (make_pair(0, datatree.AddPlus(expr_t_1, expr_t_2))); - } - else if (is_endogenous_present_1 && is_endogenous_present_2) - return (make_pair(1, (expr_t) NULL)); - else if (!is_endogenous_present_1 && is_endogenous_present_2) - { - List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(expr_t_1, (expr_t) NULL))); - return (make_pair(1, expr_t_1)); - } - else if (is_endogenous_present_1 && !is_endogenous_present_2) - { - List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(expr_t_2, (expr_t) NULL))); - return (make_pair(1, expr_t_2)); - } - break; - case oMinus: - if (!is_endogenous_present_1 && !is_endogenous_present_2) - { - List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(datatree.AddMinus(expr_t_1, expr_t_2), (expr_t) NULL))); - return (make_pair(0, datatree.AddMinus(expr_t_1, expr_t_2))); - } - else if (is_endogenous_present_1 && is_endogenous_present_2) - return (make_pair(1, (expr_t) NULL)); - else if (!is_endogenous_present_1 && is_endogenous_present_2) - { - List_of_Op_RHS.push_back(make_pair(oUminus, make_pair((expr_t) NULL, (expr_t) NULL))); - List_of_Op_RHS.push_back(make_pair(oMinus, make_pair(expr_t_1, (expr_t) NULL))); - return (make_pair(1, expr_t_1)); - } - else if (is_endogenous_present_1 && !is_endogenous_present_2) - { - List_of_Op_RHS.push_back(make_pair(oPlus, make_pair(expr_t_2, (expr_t) NULL))); - return (make_pair(1, datatree.AddUMinus(expr_t_2))); - } - break; - case oTimes: - if (!is_endogenous_present_1 && !is_endogenous_present_2) - return (make_pair(0, datatree.AddTimes(expr_t_1, expr_t_2))); - else if (!is_endogenous_present_1 && is_endogenous_present_2) - { - List_of_Op_RHS.push_back(make_pair(oDivide, make_pair(expr_t_1, (expr_t) NULL))); - return (make_pair(1, expr_t_1)); - } - else if (is_endogenous_present_1 && !is_endogenous_present_2) - { - List_of_Op_RHS.push_back(make_pair(oDivide, make_pair(expr_t_2, (expr_t) NULL))); - return (make_pair(1, expr_t_2)); - } - else - return (make_pair(1, (expr_t) NULL)); - break; - case oDivide: - if (!is_endogenous_present_1 && !is_endogenous_present_2) - return (make_pair(0, datatree.AddDivide(expr_t_1, expr_t_2))); - else if (!is_endogenous_present_1 && is_endogenous_present_2) - { - List_of_Op_RHS.push_back(make_pair(oDivide, make_pair((expr_t) NULL, expr_t_1))); - return (make_pair(1, expr_t_1)); - } - else if (is_endogenous_present_1 && !is_endogenous_present_2) - { - List_of_Op_RHS.push_back(make_pair(oTimes, make_pair(expr_t_2, (expr_t) NULL))); - return (make_pair(1, expr_t_2)); - } - else - return (make_pair(1, (expr_t) NULL)); - break; - case oPower: - if (!is_endogenous_present_1 && !is_endogenous_present_2) - return (make_pair(0, datatree.AddPower(expr_t_1, expr_t_2))); - else if (is_endogenous_present_1 && !is_endogenous_present_2) - { - List_of_Op_RHS.push_back(make_pair(oPower, make_pair(datatree.AddDivide(datatree.One, expr_t_2), (expr_t) NULL))); - return (make_pair(1, (expr_t) NULL)); - } - else if (!is_endogenous_present_1 && is_endogenous_present_2) - { - /* we have to nomalize a^f(X) = RHS */ - /* First computes the ln(RHS)*/ - List_of_Op_RHS.push_back(make_pair(oLog, make_pair((expr_t) NULL, (expr_t) NULL))); - /* Second computes f(X) = ln(RHS) / ln(a)*/ - List_of_Op_RHS.push_back(make_pair(oDivide, make_pair((expr_t) NULL, datatree.AddLog(expr_t_1)))); - return (make_pair(1, (expr_t) NULL)); - } - break; - case oEqual: - if (!is_endogenous_present_1 && !is_endogenous_present_2) - { - return (make_pair(0, - datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getID(eEndogenous, var_endo), 0), datatree.AddMinus(expr_t_2, expr_t_1)) - )); - } - else if (is_endogenous_present_1 && is_endogenous_present_2) - { - return (make_pair(0, - datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getID(eEndogenous, var_endo), 0), datatree.Zero) - )); - } - else if (!is_endogenous_present_1 && is_endogenous_present_2) - { - return (make_pair(0, - datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getID(eEndogenous, var_endo), 0), /*datatree.AddUMinus(expr_t_1)*/ expr_t_1) - )); - } - else if (is_endogenous_present_1 && !is_endogenous_present_2) - { - return (make_pair(0, - datatree.AddEqual(datatree.AddVariable(datatree.symbol_table.getID(eEndogenous, var_endo), 0), expr_t_2) - )); - } - break; - case oMax: - if (!is_endogenous_present_1 && !is_endogenous_present_2) - return (make_pair(0, datatree.AddMax(expr_t_1, expr_t_2))); - else - return (make_pair(1, (expr_t) NULL)); - break; - case oMin: - if (!is_endogenous_present_1 && !is_endogenous_present_2) - return (make_pair(0, datatree.AddMin(expr_t_1, expr_t_2))); - else - return (make_pair(1, (expr_t) NULL)); - break; - case oLess: - if (!is_endogenous_present_1 && !is_endogenous_present_2) - return (make_pair(0, datatree.AddLess(expr_t_1, expr_t_2))); - else - return (make_pair(1, (expr_t) NULL)); - break; - case oGreater: - if (!is_endogenous_present_1 && !is_endogenous_present_2) - return (make_pair(0, datatree.AddGreater(expr_t_1, expr_t_2))); - else - return (make_pair(1, (expr_t) NULL)); - break; - case oLessEqual: - if (!is_endogenous_present_1 && !is_endogenous_present_2) - return (make_pair(0, datatree.AddLessEqual(expr_t_1, expr_t_2))); - else - return (make_pair(1, (expr_t) NULL)); - break; - case oGreaterEqual: - if (!is_endogenous_present_1 && !is_endogenous_present_2) - return (make_pair(0, datatree.AddGreaterEqual(expr_t_1, expr_t_2))); - else - return (make_pair(1, (expr_t) NULL)); - break; - case oEqualEqual: - if (!is_endogenous_present_1 && !is_endogenous_present_2) - return (make_pair(0, datatree.AddEqualEqual(expr_t_1, expr_t_2))); - else - return (make_pair(1, (expr_t) NULL)); - break; - case oDifferent: - if (!is_endogenous_present_1 && !is_endogenous_present_2) - return (make_pair(0, datatree.AddDifferent(expr_t_1, expr_t_2))); - else - return (make_pair(1, (expr_t) NULL)); - break; - default: - cerr << "Binary operator not handled during the normalization process" << endl; - return (make_pair(2, (expr_t) NULL)); // Could not be normalized - } - // Suppress GCC warning - cerr << "BinaryOpNode::normalizeEquation: impossible case" << endl; - exit(EXIT_FAILURE); -} - -expr_t -BinaryOpNode::getChainRuleDerivative(int deriv_id, const map &recursive_variables) -{ - expr_t darg1 = arg1->getChainRuleDerivative(deriv_id, recursive_variables); - expr_t darg2 = arg2->getChainRuleDerivative(deriv_id, recursive_variables); - return composeDerivatives(darg1, darg2); -} - -expr_t -BinaryOpNode::buildSimilarBinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, DataTree &alt_datatree) const -{ - switch (op_code) - { - case oPlus: - return alt_datatree.AddPlus(alt_arg1, alt_arg2); - case oMinus: - return alt_datatree.AddMinus(alt_arg1, alt_arg2); - case oTimes: - return alt_datatree.AddTimes(alt_arg1, alt_arg2); - case oDivide: - return alt_datatree.AddDivide(alt_arg1, alt_arg2); - case oPower: - return alt_datatree.AddPower(alt_arg1, alt_arg2); - case oEqual: - return alt_datatree.AddEqual(alt_arg1, alt_arg2); - case oMax: - return alt_datatree.AddMax(alt_arg1, alt_arg2); - case oMin: - return alt_datatree.AddMin(alt_arg1, alt_arg2); - case oLess: - return alt_datatree.AddLess(alt_arg1, alt_arg2); - case oGreater: - return alt_datatree.AddGreater(alt_arg1, alt_arg2); - case oLessEqual: - return alt_datatree.AddLessEqual(alt_arg1, alt_arg2); - case oGreaterEqual: - return alt_datatree.AddGreaterEqual(alt_arg1, alt_arg2); - case oEqualEqual: - return alt_datatree.AddEqualEqual(alt_arg1, alt_arg2); - case oDifferent: - return alt_datatree.AddDifferent(alt_arg1, alt_arg2); - case oPowerDeriv: - return alt_datatree.AddPowerDeriv(alt_arg1, alt_arg2, powerDerivOrder); - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -expr_t -BinaryOpNode::toStatic(DataTree &static_datatree) const -{ - expr_t sarg1 = arg1->toStatic(static_datatree); - expr_t sarg2 = arg2->toStatic(static_datatree); - return buildSimilarBinaryOpNode(sarg1, sarg2, static_datatree); -} - -void -BinaryOpNode::computeXrefs(EquationInfo &ei) const -{ - arg1->computeXrefs(ei); - arg2->computeXrefs(ei); -} - -expr_t -BinaryOpNode::cloneDynamic(DataTree &dynamic_datatree) const -{ - expr_t substarg1 = arg1->cloneDynamic(dynamic_datatree); - expr_t substarg2 = arg2->cloneDynamic(dynamic_datatree); - return buildSimilarBinaryOpNode(substarg1, substarg2, dynamic_datatree); -} - -int -BinaryOpNode::maxEndoLead() const -{ - return max(arg1->maxEndoLead(), arg2->maxEndoLead()); -} - -int -BinaryOpNode::maxExoLead() const -{ - return max(arg1->maxExoLead(), arg2->maxExoLead()); -} - -int -BinaryOpNode::maxEndoLag() const -{ - return max(arg1->maxEndoLag(), arg2->maxEndoLag()); -} - -int -BinaryOpNode::maxExoLag() const -{ - return max(arg1->maxExoLag(), arg2->maxExoLag()); -} - -int -BinaryOpNode::maxLead() const -{ - return max(arg1->maxLead(), arg2->maxLead()); -} - -expr_t -BinaryOpNode::decreaseLeadsLags(int n) const -{ - expr_t arg1subst = arg1->decreaseLeadsLags(n); - expr_t arg2subst = arg2->decreaseLeadsLags(n); - return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); -} - -expr_t -BinaryOpNode::decreaseLeadsLagsPredeterminedVariables() const -{ - expr_t arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables(); - expr_t arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables(); - return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); -} - -expr_t -BinaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const -{ - expr_t arg1subst, arg2subst; - int maxendolead1 = arg1->maxEndoLead(), maxendolead2 = arg2->maxEndoLead(); - - if (maxendolead1 < 2 && maxendolead2 < 2) - return const_cast(this); - if (deterministic_model) - { - arg1subst = maxendolead1 >= 2 ? arg1->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model) : arg1; - arg2subst = maxendolead2 >= 2 ? arg2->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model) : arg2; - return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); - } - else - { - switch (op_code) - { - case oPlus: - case oMinus: - case oEqual: - arg1subst = maxendolead1 >= 2 ? arg1->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model) : arg1; - arg2subst = maxendolead2 >= 2 ? arg2->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model) : arg2; - return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); - case oTimes: - case oDivide: - if (maxendolead1 >= 2 && maxendolead2 == 0 && arg2->maxExoLead() == 0) - { - arg1subst = arg1->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); - return buildSimilarBinaryOpNode(arg1subst, arg2, datatree); - } - if (maxendolead1 == 0 && arg1->maxExoLead() == 0 - && maxendolead2 >= 2 && op_code == oTimes) - { - arg2subst = arg2->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); - return buildSimilarBinaryOpNode(arg1, arg2subst, datatree); - } - return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs); - default: - return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs); - } - } -} - -expr_t -BinaryOpNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const -{ - expr_t arg1subst = arg1->substituteEndoLagGreaterThanTwo(subst_table, neweqs); - expr_t arg2subst = arg2->substituteEndoLagGreaterThanTwo(subst_table, neweqs); - return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); -} - -expr_t -BinaryOpNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const -{ - expr_t arg1subst, arg2subst; - int maxexolead1 = arg1->maxExoLead(), maxexolead2 = arg2->maxExoLead(); - - if (maxexolead1 < 1 && maxexolead2 < 1) - return const_cast(this); - if (deterministic_model) - { - arg1subst = maxexolead1 >= 1 ? arg1->substituteExoLead(subst_table, neweqs, deterministic_model) : arg1; - arg2subst = maxexolead2 >= 1 ? arg2->substituteExoLead(subst_table, neweqs, deterministic_model) : arg2; - return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); - } - else - { - switch (op_code) - { - case oPlus: - case oMinus: - case oEqual: - arg1subst = maxexolead1 >= 1 ? arg1->substituteExoLead(subst_table, neweqs, deterministic_model) : arg1; - arg2subst = maxexolead2 >= 1 ? arg2->substituteExoLead(subst_table, neweqs, deterministic_model) : arg2; - return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); - case oTimes: - case oDivide: - if (maxexolead1 >= 1 && maxexolead2 == 0 && arg2->maxEndoLead() == 0) - { - arg1subst = arg1->substituteExoLead(subst_table, neweqs, deterministic_model); - return buildSimilarBinaryOpNode(arg1subst, arg2, datatree); - } - if (maxexolead1 == 0 && arg1->maxEndoLead() == 0 - && maxexolead2 >= 1 && op_code == oTimes) - { - arg2subst = arg2->substituteExoLead(subst_table, neweqs, deterministic_model); - return buildSimilarBinaryOpNode(arg1, arg2subst, datatree); - } - return createExoLeadAuxiliaryVarForMyself(subst_table, neweqs); - default: - return createExoLeadAuxiliaryVarForMyself(subst_table, neweqs); - } - } -} - -expr_t -BinaryOpNode::substituteExoLag(subst_table_t &subst_table, vector &neweqs) const -{ - expr_t arg1subst = arg1->substituteExoLag(subst_table, neweqs); - expr_t arg2subst = arg2->substituteExoLag(subst_table, neweqs); - return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); -} - -expr_t -BinaryOpNode::substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const -{ - expr_t arg1subst = arg1->substituteExpectation(subst_table, neweqs, partial_information_model); - expr_t arg2subst = arg2->substituteExpectation(subst_table, neweqs, partial_information_model); - return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); -} - -expr_t -BinaryOpNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const -{ - expr_t arg1subst = arg1->differentiateForwardVars(subset, subst_table, neweqs); - expr_t arg2subst = arg2->differentiateForwardVars(subset, subst_table, neweqs); - return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); -} - -expr_t -BinaryOpNode::addMultipliersToConstraints(int i) -{ - int symb_id = datatree.symbol_table.addMultiplierAuxiliaryVar(i); - expr_t newAuxLM = datatree.AddVariable(symb_id, 0); - return datatree.AddEqual(datatree.AddTimes(newAuxLM, datatree.AddMinus(arg1, arg2)), datatree.Zero); -} - -bool -BinaryOpNode::isNumConstNodeEqualTo(double value) const -{ - return false; -} - -bool -BinaryOpNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const -{ - return false; -} - -bool -BinaryOpNode::containsEndogenous(void) const -{ - return (arg1->containsEndogenous() || arg2->containsEndogenous()); -} - -bool -BinaryOpNode::containsExogenous() const -{ - return (arg1->containsExogenous() || arg2->containsExogenous()); -} - -expr_t -BinaryOpNode::replaceTrendVar() const -{ - expr_t arg1subst = arg1->replaceTrendVar(); - expr_t arg2subst = arg2->replaceTrendVar(); - return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); -} - -expr_t -BinaryOpNode::detrend(int symb_id, bool log_trend, expr_t trend) const -{ - expr_t arg1subst = arg1->detrend(symb_id, log_trend, trend); - expr_t arg2subst = arg2->detrend(symb_id, log_trend, trend); - return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); -} - -expr_t -BinaryOpNode::removeTrendLeadLag(map trend_symbols_map) const -{ - expr_t arg1subst = arg1->removeTrendLeadLag(trend_symbols_map); - expr_t arg2subst = arg2->removeTrendLeadLag(trend_symbols_map); - return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); -} - -bool -BinaryOpNode::isInStaticForm() const -{ - return arg1->isInStaticForm() && arg2->isInStaticForm(); -} - -expr_t -BinaryOpNode::substituteStaticAuxiliaryVariable() const -{ - expr_t arg1subst = arg1->substituteStaticAuxiliaryVariable(); - expr_t arg2subst = arg2->substituteStaticAuxiliaryVariable(); - return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); -} - -expr_t -BinaryOpNode::substituteStaticAuxiliaryDefinition() const -{ - expr_t arg2subst = arg2->substituteStaticAuxiliaryVariable(); - return buildSimilarBinaryOpNode(arg1, arg2subst, datatree); -} - -TrinaryOpNode::TrinaryOpNode(DataTree &datatree_arg, const expr_t arg1_arg, - TrinaryOpcode op_code_arg, const expr_t arg2_arg, const expr_t arg3_arg) : - ExprNode(datatree_arg), - arg1(arg1_arg), - arg2(arg2_arg), - arg3(arg3_arg), - op_code(op_code_arg) -{ - datatree.trinary_op_node_map[make_pair(make_pair(make_pair(arg1, arg2), arg3), op_code)] = this; -} - -void -TrinaryOpNode::prepareForDerivation() -{ - if (preparedForDerivation) - return; - - preparedForDerivation = true; - - arg1->prepareForDerivation(); - arg2->prepareForDerivation(); - arg3->prepareForDerivation(); - - // Non-null derivatives are the union of those of the arguments - // Compute set union of arg{1,2,3}->non_null_derivatives - set non_null_derivatives_tmp; - set_union(arg1->non_null_derivatives.begin(), - arg1->non_null_derivatives.end(), - arg2->non_null_derivatives.begin(), - arg2->non_null_derivatives.end(), - inserter(non_null_derivatives_tmp, non_null_derivatives_tmp.begin())); - set_union(non_null_derivatives_tmp.begin(), - non_null_derivatives_tmp.end(), - arg3->non_null_derivatives.begin(), - arg3->non_null_derivatives.end(), - inserter(non_null_derivatives, non_null_derivatives.begin())); -} - -expr_t -TrinaryOpNode::composeDerivatives(expr_t darg1, expr_t darg2, expr_t darg3) -{ - - expr_t t11, t12, t13, t14, t15; - - switch (op_code) - { - case oNormcdf: - // normal pdf is inlined in the tree - expr_t y; - // sqrt(2*pi) - t14 = datatree.AddSqrt(datatree.AddTimes(datatree.Two, datatree.Pi)); - // x - mu - t12 = datatree.AddMinus(arg1, arg2); - // y = (x-mu)/sigma - y = datatree.AddDivide(t12, arg3); - // (x-mu)^2/sigma^2 - t12 = datatree.AddTimes(y, y); - // -(x-mu)^2/sigma^2 - t13 = datatree.AddUMinus(t12); - // -((x-mu)^2/sigma^2)/2 - t12 = datatree.AddDivide(t13, datatree.Two); - // exp(-((x-mu)^2/sigma^2)/2) - t13 = datatree.AddExp(t12); - // derivative of a standardized normal - // t15 = (1/sqrt(2*pi))*exp(-y^2/2) - t15 = datatree.AddDivide(t13, t14); - // derivatives thru x - t11 = datatree.AddDivide(darg1, arg3); - // derivatives thru mu - t12 = datatree.AddDivide(darg2, arg3); - // intermediary sum - t14 = datatree.AddMinus(t11, t12); - // derivatives thru sigma - t11 = datatree.AddDivide(y, arg3); - t12 = datatree.AddTimes(t11, darg3); - //intermediary sum - t11 = datatree.AddMinus(t14, t12); - // total derivative: - // (darg1/sigma - darg2/sigma - darg3*(x-mu)/sigma^2) * t15 - // where t15 is the derivative of a standardized normal - return datatree.AddTimes(t11, t15); - case oNormpdf: - // (x - mu) - t11 = datatree.AddMinus(arg1, arg2); - // (x - mu)/sigma - t12 = datatree.AddDivide(t11, arg3); - // darg3 * (x - mu)/sigma - t11 = datatree.AddTimes(darg3, t12); - // darg2 - darg1 - t13 = datatree.AddMinus(darg2, darg1); - // darg2 - darg1 + darg3 * (x - mu)/sigma - t14 = datatree.AddPlus(t13, t11); - // ((x - mu)/sigma) * (darg2 - darg1 + darg3 * (x - mu)/sigma) - t11 = datatree.AddTimes(t12, t14); - // ((x - mu)/sigma) * (darg2 - darg1 + darg3 * (x - mu)/sigma) - darg3 - t12 = datatree.AddMinus(t11, darg3); - // this / sigma - t11 = datatree.AddDivide(this, arg3); - // total derivative: - // (this / sigma) * (((x - mu)/sigma) * (darg2 - darg1 + darg3 * (x - mu)/sigma) - darg3) - return datatree.AddTimes(t11, t12); - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -expr_t -TrinaryOpNode::computeDerivative(int deriv_id) -{ - expr_t darg1 = arg1->getDerivative(deriv_id); - expr_t darg2 = arg2->getDerivative(deriv_id); - expr_t darg3 = arg3->getDerivative(deriv_id); - return composeDerivatives(darg1, darg2, darg3); -} - -int -TrinaryOpNode::precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - // A temporary term behaves as a variable - if (it != temporary_terms.end()) - return 100; - - switch (op_code) - { - case oNormcdf: - case oNormpdf: - return 100; - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -int -TrinaryOpNode::cost(const map &temp_terms_map, bool is_matlab) const -{ - // For a temporary term, the cost is null - for (map::const_iterator it = temp_terms_map.begin(); - it != temp_terms_map.end(); it++) - if (it->second.find(const_cast(this)) != it->second.end()) - return 0; - - int arg_cost = arg1->cost(temp_terms_map, is_matlab) - + arg2->cost(temp_terms_map, is_matlab) - + arg3->cost(temp_terms_map, is_matlab); - - return cost(arg_cost, is_matlab); -} - -int -TrinaryOpNode::cost(const temporary_terms_t &temporary_terms, bool is_matlab) const -{ - // For a temporary term, the cost is null - if (temporary_terms.find(const_cast(this)) != temporary_terms.end()) - return 0; - - int arg_cost = arg1->cost(temporary_terms, is_matlab) - + arg2->cost(temporary_terms, is_matlab) - + arg3->cost(temporary_terms, is_matlab); - - return cost(arg_cost, is_matlab); -} - -int -TrinaryOpNode::cost(int cost, bool is_matlab) const -{ - if (is_matlab) - // Cost for Matlab files - switch (op_code) - { - case oNormcdf: - case oNormpdf: - return cost+1000; - } - else - // Cost for C files - switch (op_code) - { - case oNormcdf: - case oNormpdf: - return cost+1000; - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -void -TrinaryOpNode::computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const -{ - expr_t this2 = const_cast(this); - map >::iterator it = reference_count.find(this2); - if (it == reference_count.end()) - { - // If this node has never been encountered, set its ref count to one, - // and travel through its children - reference_count[this2] = make_pair(1, tr); - arg1->computeTemporaryTerms(reference_count, temp_terms_map, is_matlab, tr); - arg2->computeTemporaryTerms(reference_count, temp_terms_map, is_matlab, tr); - arg3->computeTemporaryTerms(reference_count, temp_terms_map, is_matlab, tr); - } - else - { - // If the node has already been encountered, increment its ref count - // and declare it as a temporary term if it is too costly - reference_count[this2] = make_pair(it->second.first + 1, it->second.second);; - if (reference_count[this2].first * cost(temp_terms_map, is_matlab) > MIN_COST(is_matlab)) - temp_terms_map[reference_count[this2].second].insert(this2); - } -} - -void -TrinaryOpNode::computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector > &v_temporary_terms, - int equation) const -{ - expr_t this2 = const_cast(this); - map::iterator it = reference_count.find(this2); - if (it == reference_count.end()) - { - reference_count[this2] = 1; - first_occurence[this2] = make_pair(Curr_block, equation); - arg1->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation); - arg2->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation); - arg3->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation); - } - else - { - reference_count[this2]++; - if (reference_count[this2] * cost(temporary_terms, false) > MIN_COST_C) - { - temporary_terms.insert(this2); - v_temporary_terms[first_occurence[this2].first][first_occurence[this2].second].insert(this2); - } - } -} - -double -TrinaryOpNode::eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException, EvalExternalFunctionException) -{ - switch (op_code) - { - case oNormcdf: - return (0.5*(1+erf((v1-v2)/v3/M_SQRT2))); - case oNormpdf: - return (1/(v3*sqrt(2*M_PI)*exp(pow((v1-v2)/v3, 2)/2))); - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -double -TrinaryOpNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) -{ - double v1 = arg1->eval(eval_context); - double v2 = arg2->eval(eval_context); - double v3 = arg3->eval(eval_context); - - return eval_opcode(v1, op_code, v2, v3); -} - -void -TrinaryOpNode::compile(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - // If current node is a temporary term - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (dynamic) - { - map_idx_t::const_iterator ii = map_idx.find(idx); - FLDT_ fldt(ii->second); - fldt.write(CompileCode, instruction_number); - } - else - { - map_idx_t::const_iterator ii = map_idx.find(idx); - FLDST_ fldst(ii->second); - fldst.write(CompileCode, instruction_number); - } - return; - } - arg1->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms); - arg2->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms); - arg3->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, dynamic, steady_dynamic, tef_terms); - FTRINARY_ ftrinary(op_code); - ftrinary.write(CompileCode, instruction_number); -} - -void -TrinaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - temporary_terms_inuse.insert(idx); - else - { - arg1->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block); - arg2->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block); - arg3->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block); - } -} - -bool -TrinaryOpNode::containsExternalFunction() const -{ - return arg1->containsExternalFunction() - || arg2->containsExternalFunction() - || arg3->containsExternalFunction(); -} - -void -TrinaryOpNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - // If current node is a temporary term - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - output << "T" << idx; - return; - } - - switch (op_code) - { - case oNormcdf: - output << "normcdf("; - break; - case oNormpdf: - output << "normpdf("; - break; - } - - arg1->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); - output << ","; - arg2->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); - output << ","; - arg3->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); - output << ")"; -} - -void -TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - // If current node is a temporary term - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - output << "T" << idx; - return; - } - - switch (op_code) - { - case oNormcdf: - if (IS_C(output_type)) - { - // In C, there is no normcdf() primitive, so use erf() - output << "(0.5*(1+erf((("; - arg1->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ")-("; - arg2->writeOutput(output, output_type, temporary_terms, tef_terms); - output << "))/("; - arg3->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ")/M_SQRT2)))"; - } - else - { - output << "normcdf("; - arg1->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ","; - arg2->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ","; - arg3->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ")"; - } - break; - case oNormpdf: - if (IS_C(output_type)) - { - //(1/(v3*sqrt(2*M_PI)*exp(pow((v1-v2)/v3,2)/2))) - output << "(1/("; - arg3->writeOutput(output, output_type, temporary_terms, tef_terms); - output << "*sqrt(2*M_PI)*exp(pow(("; - arg1->writeOutput(output, output_type, temporary_terms, tef_terms); - output << "-"; - arg2->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ")/"; - arg3->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ",2)/2)))"; - } - else - { - output << "normpdf("; - arg1->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ","; - arg2->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ","; - arg3->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ")"; - } - break; - } -} - -void -TrinaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - arg1->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms); - arg2->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms); - arg3->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms); -} - -void -TrinaryOpNode::writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - arg1->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms, isdynamic); - arg2->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms, isdynamic); - arg3->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms, isdynamic); -} - -void -TrinaryOpNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - arg1->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, - dynamic, steady_dynamic, tef_terms); - arg2->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, - dynamic, steady_dynamic, tef_terms); - arg3->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, - dynamic, steady_dynamic, tef_terms); -} - -void -TrinaryOpNode::collectDynamicVariables(SymbolType type_arg, set > &result) const -{ - arg1->collectDynamicVariables(type_arg, result); - arg2->collectDynamicVariables(type_arg, result); - arg3->collectDynamicVariables(type_arg, result); -} - -pair -TrinaryOpNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const -{ - pair res = arg1->normalizeEquation(var_endo, List_of_Op_RHS); - bool is_endogenous_present_1 = res.first; - expr_t expr_t_1 = res.second; - res = arg2->normalizeEquation(var_endo, List_of_Op_RHS); - bool is_endogenous_present_2 = res.first; - expr_t expr_t_2 = res.second; - res = arg3->normalizeEquation(var_endo, List_of_Op_RHS); - bool is_endogenous_present_3 = res.first; - expr_t expr_t_3 = res.second; - if (!is_endogenous_present_1 && !is_endogenous_present_2 && !is_endogenous_present_3) - return (make_pair(0, datatree.AddNormcdf(expr_t_1, expr_t_2, expr_t_3))); - else - return (make_pair(1, (expr_t) NULL)); -} - -expr_t -TrinaryOpNode::getChainRuleDerivative(int deriv_id, const map &recursive_variables) -{ - expr_t darg1 = arg1->getChainRuleDerivative(deriv_id, recursive_variables); - expr_t darg2 = arg2->getChainRuleDerivative(deriv_id, recursive_variables); - expr_t darg3 = arg3->getChainRuleDerivative(deriv_id, recursive_variables); - return composeDerivatives(darg1, darg2, darg3); -} - -expr_t -TrinaryOpNode::buildSimilarTrinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, expr_t alt_arg3, DataTree &alt_datatree) const -{ - switch (op_code) - { - case oNormcdf: - return alt_datatree.AddNormcdf(alt_arg1, alt_arg2, alt_arg3); - case oNormpdf: - return alt_datatree.AddNormpdf(alt_arg1, alt_arg2, alt_arg3); - } - // Suppress GCC warning - exit(EXIT_FAILURE); -} - -expr_t -TrinaryOpNode::toStatic(DataTree &static_datatree) const -{ - expr_t sarg1 = arg1->toStatic(static_datatree); - expr_t sarg2 = arg2->toStatic(static_datatree); - expr_t sarg3 = arg3->toStatic(static_datatree); - return buildSimilarTrinaryOpNode(sarg1, sarg2, sarg3, static_datatree); -} - -void -TrinaryOpNode::computeXrefs(EquationInfo &ei) const -{ - arg1->computeXrefs(ei); - arg2->computeXrefs(ei); - arg3->computeXrefs(ei); -} - -expr_t -TrinaryOpNode::cloneDynamic(DataTree &dynamic_datatree) const -{ - expr_t substarg1 = arg1->cloneDynamic(dynamic_datatree); - expr_t substarg2 = arg2->cloneDynamic(dynamic_datatree); - expr_t substarg3 = arg3->cloneDynamic(dynamic_datatree); - return buildSimilarTrinaryOpNode(substarg1, substarg2, substarg3, dynamic_datatree); -} - -int -TrinaryOpNode::maxEndoLead() const -{ - return max(arg1->maxEndoLead(), max(arg2->maxEndoLead(), arg3->maxEndoLead())); -} - -int -TrinaryOpNode::maxExoLead() const -{ - return max(arg1->maxExoLead(), max(arg2->maxExoLead(), arg3->maxExoLead())); -} - -int -TrinaryOpNode::maxEndoLag() const -{ - return max(arg1->maxEndoLag(), max(arg2->maxEndoLag(), arg3->maxEndoLag())); -} - -int -TrinaryOpNode::maxExoLag() const -{ - return max(arg1->maxExoLag(), max(arg2->maxExoLag(), arg3->maxExoLag())); -} - -int -TrinaryOpNode::maxLead() const -{ - return max(arg1->maxLead(), max(arg2->maxLead(), arg3->maxLead())); -} - -expr_t -TrinaryOpNode::decreaseLeadsLags(int n) const -{ - expr_t arg1subst = arg1->decreaseLeadsLags(n); - expr_t arg2subst = arg2->decreaseLeadsLags(n); - expr_t arg3subst = arg3->decreaseLeadsLags(n); - return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); -} - -expr_t -TrinaryOpNode::decreaseLeadsLagsPredeterminedVariables() const -{ - expr_t arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables(); - expr_t arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables(); - expr_t arg3subst = arg3->decreaseLeadsLagsPredeterminedVariables(); - return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); -} - -expr_t -TrinaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const -{ - if (maxEndoLead() < 2) - return const_cast(this); - else if (deterministic_model) - { - expr_t arg1subst = arg1->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); - expr_t arg2subst = arg2->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); - expr_t arg3subst = arg3->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); - return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); - } - else - return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs); -} - -expr_t -TrinaryOpNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const -{ - expr_t arg1subst = arg1->substituteEndoLagGreaterThanTwo(subst_table, neweqs); - expr_t arg2subst = arg2->substituteEndoLagGreaterThanTwo(subst_table, neweqs); - expr_t arg3subst = arg3->substituteEndoLagGreaterThanTwo(subst_table, neweqs); - return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); -} - -expr_t -TrinaryOpNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const -{ - if (maxExoLead() == 0) - return const_cast(this); - else if (deterministic_model) - { - expr_t arg1subst = arg1->substituteExoLead(subst_table, neweqs, deterministic_model); - expr_t arg2subst = arg2->substituteExoLead(subst_table, neweqs, deterministic_model); - expr_t arg3subst = arg3->substituteExoLead(subst_table, neweqs, deterministic_model); - return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); - } - else - return createExoLeadAuxiliaryVarForMyself(subst_table, neweqs); -} - -expr_t -TrinaryOpNode::substituteExoLag(subst_table_t &subst_table, vector &neweqs) const -{ - expr_t arg1subst = arg1->substituteExoLag(subst_table, neweqs); - expr_t arg2subst = arg2->substituteExoLag(subst_table, neweqs); - expr_t arg3subst = arg3->substituteExoLag(subst_table, neweqs); - return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); -} - -expr_t -TrinaryOpNode::substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const -{ - expr_t arg1subst = arg1->substituteExpectation(subst_table, neweqs, partial_information_model); - expr_t arg2subst = arg2->substituteExpectation(subst_table, neweqs, partial_information_model); - expr_t arg3subst = arg3->substituteExpectation(subst_table, neweqs, partial_information_model); - return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); -} - -expr_t -TrinaryOpNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const -{ - expr_t arg1subst = arg1->differentiateForwardVars(subset, subst_table, neweqs); - expr_t arg2subst = arg2->differentiateForwardVars(subset, subst_table, neweqs); - expr_t arg3subst = arg3->differentiateForwardVars(subset, subst_table, neweqs); - return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); -} - -bool -TrinaryOpNode::isNumConstNodeEqualTo(double value) const -{ - return false; -} - -bool -TrinaryOpNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const -{ - return false; -} - -bool -TrinaryOpNode::containsEndogenous(void) const -{ - return (arg1->containsEndogenous() || arg2->containsEndogenous() || arg3->containsEndogenous()); -} - -bool -TrinaryOpNode::containsExogenous() const -{ - return (arg1->containsExogenous() || arg2->containsExogenous() || arg3->containsExogenous()); -} - -expr_t -TrinaryOpNode::replaceTrendVar() const -{ - expr_t arg1subst = arg1->replaceTrendVar(); - expr_t arg2subst = arg2->replaceTrendVar(); - expr_t arg3subst = arg3->replaceTrendVar(); - return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); -} - -expr_t -TrinaryOpNode::detrend(int symb_id, bool log_trend, expr_t trend) const -{ - expr_t arg1subst = arg1->detrend(symb_id, log_trend, trend); - expr_t arg2subst = arg2->detrend(symb_id, log_trend, trend); - expr_t arg3subst = arg3->detrend(symb_id, log_trend, trend); - return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); -} - -expr_t -TrinaryOpNode::removeTrendLeadLag(map trend_symbols_map) const -{ - expr_t arg1subst = arg1->removeTrendLeadLag(trend_symbols_map); - expr_t arg2subst = arg2->removeTrendLeadLag(trend_symbols_map); - expr_t arg3subst = arg3->removeTrendLeadLag(trend_symbols_map); - return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); -} - -bool -TrinaryOpNode::isInStaticForm() const -{ - return arg1->isInStaticForm() && arg2->isInStaticForm() && arg3->isInStaticForm(); -} - -expr_t -TrinaryOpNode::substituteStaticAuxiliaryVariable() const -{ - expr_t arg1subst = arg1->substituteStaticAuxiliaryVariable(); - expr_t arg2subst = arg2->substituteStaticAuxiliaryVariable(); - expr_t arg3subst = arg3->substituteStaticAuxiliaryVariable(); - return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); -} - -AbstractExternalFunctionNode::AbstractExternalFunctionNode(DataTree &datatree_arg, - int symb_id_arg, - const vector &arguments_arg) : - ExprNode(datatree_arg), - symb_id(symb_id_arg), - arguments(arguments_arg) -{ -} - -void -AbstractExternalFunctionNode::prepareForDerivation() -{ - if (preparedForDerivation) - return; - - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - (*it)->prepareForDerivation(); - - non_null_derivatives = arguments.at(0)->non_null_derivatives; - for (int i = 1; i < (int) arguments.size(); i++) - set_union(non_null_derivatives.begin(), - non_null_derivatives.end(), - arguments.at(i)->non_null_derivatives.begin(), - arguments.at(i)->non_null_derivatives.end(), - inserter(non_null_derivatives, non_null_derivatives.begin())); - - preparedForDerivation = true; -} - -expr_t -AbstractExternalFunctionNode::computeDerivative(int deriv_id) -{ - assert(datatree.external_functions_table.getNargs(symb_id) > 0); - vector dargs; - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - dargs.push_back((*it)->getDerivative(deriv_id)); - return composeDerivatives(dargs); -} - -expr_t -AbstractExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map &recursive_variables) -{ - assert(datatree.external_functions_table.getNargs(symb_id) > 0); - vector dargs; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - dargs.push_back((*it)->getChainRuleDerivative(deriv_id, recursive_variables)); - return composeDerivatives(dargs); -} - -unsigned int -AbstractExternalFunctionNode::compileExternalFunctionArguments(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->compile(CompileCode, instruction_number, lhs_rhs, temporary_terms, map_idx, - dynamic, steady_dynamic, tef_terms); - return (arguments.size()); -} - -void -AbstractExternalFunctionNode::collectDynamicVariables(SymbolType type_arg, set > &result) const -{ - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->collectDynamicVariables(type_arg, result); -} - -void -AbstractExternalFunctionNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - temporary_terms_inuse.insert(idx); - else - { - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block); - } -} - -double -AbstractExternalFunctionNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) -{ - throw EvalExternalFunctionException(); -} - -int -AbstractExternalFunctionNode::maxEndoLead() const -{ - int val = 0; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - val = max(val, (*it)->maxEndoLead()); - return val; -} - -int -AbstractExternalFunctionNode::maxExoLead() const -{ - int val = 0; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - val = max(val, (*it)->maxExoLead()); - return val; -} - -int -AbstractExternalFunctionNode::maxEndoLag() const -{ - int val = 0; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - val = max(val, (*it)->maxEndoLag()); - return val; -} - -int -AbstractExternalFunctionNode::maxExoLag() const -{ - int val = 0; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - val = max(val, (*it)->maxExoLag()); - return val; -} - -int -AbstractExternalFunctionNode::maxLead() const -{ - int val = 0; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - val = max(val, (*it)->maxLead()); - return val; -} - -expr_t -AbstractExternalFunctionNode::decreaseLeadsLags(int n) const -{ - vector arguments_subst; - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - arguments_subst.push_back((*it)->decreaseLeadsLags(n)); - return buildSimilarExternalFunctionNode(arguments_subst, datatree); -} - -expr_t -AbstractExternalFunctionNode::decreaseLeadsLagsPredeterminedVariables() const -{ - vector arguments_subst; - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - arguments_subst.push_back((*it)->decreaseLeadsLagsPredeterminedVariables()); - return buildSimilarExternalFunctionNode(arguments_subst, datatree); -} - -expr_t -AbstractExternalFunctionNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const -{ - vector arguments_subst; - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - arguments_subst.push_back((*it)->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model)); - return buildSimilarExternalFunctionNode(arguments_subst, datatree); -} - -expr_t -AbstractExternalFunctionNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const -{ - vector arguments_subst; - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - arguments_subst.push_back((*it)->substituteEndoLagGreaterThanTwo(subst_table, neweqs)); - return buildSimilarExternalFunctionNode(arguments_subst, datatree); -} - -expr_t -AbstractExternalFunctionNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const -{ - vector arguments_subst; - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - arguments_subst.push_back((*it)->substituteExoLead(subst_table, neweqs, deterministic_model)); - return buildSimilarExternalFunctionNode(arguments_subst, datatree); -} - -expr_t -AbstractExternalFunctionNode::substituteExoLag(subst_table_t &subst_table, vector &neweqs) const -{ - vector arguments_subst; - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - arguments_subst.push_back((*it)->substituteExoLag(subst_table, neweqs)); - return buildSimilarExternalFunctionNode(arguments_subst, datatree); -} - -expr_t -AbstractExternalFunctionNode::substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const -{ - vector arguments_subst; - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - arguments_subst.push_back((*it)->substituteExpectation(subst_table, neweqs, partial_information_model)); - return buildSimilarExternalFunctionNode(arguments_subst, datatree); -} - -expr_t -AbstractExternalFunctionNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const -{ - vector arguments_subst; - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - arguments_subst.push_back((*it)->differentiateForwardVars(subset, subst_table, neweqs)); - return buildSimilarExternalFunctionNode(arguments_subst, datatree); -} - -bool -AbstractExternalFunctionNode::alreadyWrittenAsTefTerm(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const -{ - deriv_node_temp_terms_t::const_iterator it = tef_terms.find(make_pair(the_symb_id, arguments)); - if (it != tef_terms.end()) - return true; - return false; -} - -int -AbstractExternalFunctionNode::getIndxInTefTerms(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const throw (UnknownFunctionNameAndArgs) -{ - deriv_node_temp_terms_t::const_iterator it = tef_terms.find(make_pair(the_symb_id, arguments)); - if (it != tef_terms.end()) - return it->second; - throw UnknownFunctionNameAndArgs(); -} - -bool -AbstractExternalFunctionNode::isNumConstNodeEqualTo(double value) const -{ - return false; -} - -bool -AbstractExternalFunctionNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const -{ - return false; -} - -bool -AbstractExternalFunctionNode::containsEndogenous(void) const -{ - bool result = false; - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - result = result || (*it)->containsEndogenous(); - return result; -} - -bool -AbstractExternalFunctionNode::containsExogenous() const -{ - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - if ((*it)->containsExogenous()) - return true; - return false; -} - -expr_t -AbstractExternalFunctionNode::replaceTrendVar() const -{ - vector arguments_subst; - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - arguments_subst.push_back((*it)->replaceTrendVar()); - return buildSimilarExternalFunctionNode(arguments_subst, datatree); -} - -expr_t -AbstractExternalFunctionNode::detrend(int symb_id, bool log_trend, expr_t trend) const -{ - vector arguments_subst; - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - arguments_subst.push_back((*it)->detrend(symb_id, log_trend, trend)); - return buildSimilarExternalFunctionNode(arguments_subst, datatree); -} - -expr_t -AbstractExternalFunctionNode::removeTrendLeadLag(map trend_symbols_map) const -{ - vector arguments_subst; - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - arguments_subst.push_back((*it)->removeTrendLeadLag(trend_symbols_map)); - return buildSimilarExternalFunctionNode(arguments_subst, datatree); -} - -bool -AbstractExternalFunctionNode::isInStaticForm() const -{ - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); ++it) - if (!(*it)->isInStaticForm()) - return false; - return true; -} - -pair -AbstractExternalFunctionNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const -{ - vector > V_arguments; - vector V_expr_t; - bool present = false; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - { - V_arguments.push_back((*it)->normalizeEquation(var_endo, List_of_Op_RHS)); - present = present || V_arguments[V_arguments.size()-1].first; - V_expr_t.push_back(V_arguments[V_arguments.size()-1].second); - } - if (!present) - return (make_pair(0, datatree.AddExternalFunction(symb_id, V_expr_t))); - else - return (make_pair(1, (expr_t) NULL)); -} - -void -AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - { - if (it != arguments.begin()) - output << ","; - - (*it)->writeOutput(output, output_type, temporary_terms, tef_terms); - } -} - -void -AbstractExternalFunctionNode::writeJsonExternalFunctionArguments(ostream &output, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - { - if (it != arguments.begin()) - output << ","; - - (*it)->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); - } -} - -void -AbstractExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, const string &ending) const -{ - output << "mxArray *prhs"<< ending << "[nrhs"<< ending << "];" << endl; - int i = 0; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - { - output << "prhs" << ending << "[" << i++ << "] = mxCreateDoubleScalar("; // All external_function arguments are scalars - (*it)->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ");" << endl; - } -} - -bool -AbstractExternalFunctionNode::containsExternalFunction() const -{ - return true; -} - -expr_t -AbstractExternalFunctionNode::substituteStaticAuxiliaryVariable() const -{ - vector arguments_subst; - for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - arguments_subst.push_back((*it)->substituteStaticAuxiliaryVariable()); - return buildSimilarExternalFunctionNode(arguments_subst, datatree); -} - -ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg, - int symb_id_arg, - const vector &arguments_arg) : - AbstractExternalFunctionNode(datatree_arg, symb_id_arg, arguments_arg) -{ - // Add myself to the external function map - datatree.external_function_node_map[make_pair(arguments, symb_id)] = this; -} - -expr_t -ExternalFunctionNode::composeDerivatives(const vector &dargs) -{ - vector dNodes; - for (int i = 0; i < (int) dargs.size(); i++) - dNodes.push_back(datatree.AddTimes(dargs.at(i), - datatree.AddFirstDerivExternalFunction(symb_id, arguments, i+1))); - - expr_t theDeriv = datatree.Zero; - for (vector::const_iterator it = dNodes.begin(); it != dNodes.end(); it++) - theDeriv = datatree.AddPlus(theDeriv, *it); - return theDeriv; -} - -void -ExternalFunctionNode::computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const -{ - temp_terms_map[tr].insert(const_cast(this)); -} - -void -ExternalFunctionNode::computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const -{ - expr_t this2 = const_cast(this); - temporary_terms.insert(this2); - first_occurence[this2] = make_pair(Curr_block, equation); - v_temporary_terms[Curr_block][equation].insert(this2); -} - -void -ExternalFunctionNode::compile(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (dynamic) - { - map_idx_t::const_iterator ii = map_idx.find(idx); - FLDT_ fldt(ii->second); - fldt.write(CompileCode, instruction_number); - } - else - { - map_idx_t::const_iterator ii = map_idx.find(idx); - FLDST_ fldst(ii->second); - fldst.write(CompileCode, instruction_number); - } - return; - } - - if (!lhs_rhs) - { - FLDTEF_ fldtef(getIndxInTefTerms(symb_id, tef_terms)); - fldtef.write(CompileCode, instruction_number); - } - else - { - FSTPTEF_ fstptef(getIndxInTefTerms(symb_id, tef_terms)); - fstptef.write(CompileCode, instruction_number); - } -} - -void -ExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); - assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, - map_idx, dynamic, steady_dynamic, tef_terms); - - if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) - { - tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size(); - int indx = getIndxInTefTerms(symb_id, tef_terms); - int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); - assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); - - unsigned int nb_output_arguments = 0; - if (symb_id == first_deriv_symb_id - && symb_id == second_deriv_symb_id) - nb_output_arguments = 3; - else if (symb_id == first_deriv_symb_id) - nb_output_arguments = 2; - else - nb_output_arguments = 1; - unsigned int nb_input_arguments = compileExternalFunctionArguments(CompileCode, instruction_number, lhs_rhs, temporary_terms, - map_idx, dynamic, steady_dynamic, tef_terms); - - FCALL_ fcall(nb_output_arguments, nb_input_arguments, datatree.symbol_table.getName(symb_id), indx); - switch (nb_output_arguments) - { - case 1: - fcall.set_function_type(ExternalFunctionWithoutDerivative); - break; - case 2: - fcall.set_function_type(ExternalFunctionWithFirstDerivative); - break; - case 3: - fcall.set_function_type(ExternalFunctionWithFirstandSecondDerivative); - break; - } - fcall.write(CompileCode, instruction_number); - FSTPTEF_ fstptef(indx); - fstptef.write(CompileCode, instruction_number); - } -} - -void -ExternalFunctionNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - output << "T" << idx; - return; - } - - output << datatree.symbol_table.getName(symb_id) << "("; - writeJsonExternalFunctionArguments(output, temporary_terms, tef_terms, isdynamic); - output << ")"; -} - -void -ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - if (output_type == oMatlabOutsideModel || output_type == oSteadyStateFile - || output_type == oCSteadyStateFile || output_type == oJuliaSteadyStateFile - || IS_LATEX(output_type)) - { - string name = IS_LATEX(output_type) ? datatree.symbol_table.getTeXName(symb_id) - : datatree.symbol_table.getName(symb_id); - output << name << "("; - writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms); - output << ")"; - return; - } - - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (output_type == oMatlabDynamicModelSparse) - output << "T" << idx << "(it_)"; - else - output << "T" << idx; - return; - } - - if (IS_C(output_type)) - output << "*"; - output << "TEF_" << getIndxInTefTerms(symb_id, tef_terms); -} - -void -ExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); - assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms); - - if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) - { - tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size(); - int indx = getIndxInTefTerms(symb_id, tef_terms); - int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); - assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); - - if (IS_C(output_type)) - { - stringstream ending; - ending << "_tef_" << getIndxInTefTerms(symb_id, tef_terms); - if (symb_id == first_deriv_symb_id - && symb_id == second_deriv_symb_id) - output << "int nlhs" << ending.str() << " = 3;" << endl - << "double *TEF_" << indx << ", " - << "*TEFD_" << indx << ", " - << "*TEFDD_" << indx << ";" << endl; - else if (symb_id == first_deriv_symb_id) - output << "int nlhs" << ending.str() << " = 2;" << endl - << "double *TEF_" << indx << ", " - << "*TEFD_" << indx << "; " << endl; - else - output << "int nlhs" << ending.str() << " = 1;" << endl - << "double *TEF_" << indx << ";" << endl; - - output << "mxArray *plhs" << ending.str()<< "[nlhs"<< ending.str() << "];" << endl; - output << "int nrhs" << ending.str()<< " = " << arguments.size() << ";" << endl; - writePrhs(output, output_type, temporary_terms, tef_terms, ending.str()); - - output << "mexCallMATLAB(" - << "nlhs" << ending.str() << ", " - << "plhs" << ending.str() << ", " - << "nrhs" << ending.str() << ", " - << "prhs" << ending.str() << ", \"" - << datatree.symbol_table.getName(symb_id) << "\");" << endl; - - if (symb_id == first_deriv_symb_id - && symb_id == second_deriv_symb_id) - output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl - << "TEFD_" << indx << " = mxGetPr(plhs" << ending.str() << "[1]);" << endl - << "TEFDD_" << indx << " = mxGetPr(plhs" << ending.str() << "[2]);" << endl - << "int TEFDD_" << indx << "_nrows = (int)mxGetM(plhs" << ending.str()<< "[2]);" << endl; - else if (symb_id == first_deriv_symb_id) - output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl - << "TEFD_" << indx << " = mxGetPr(plhs" << ending.str() << "[1]);" << endl; - else - output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl; - } - else - { - if (symb_id == first_deriv_symb_id - && symb_id == second_deriv_symb_id) - output << "[TEF_" << indx << ", TEFD_"<< indx << ", TEFDD_"<< indx << "] = "; - else if (symb_id == first_deriv_symb_id) - output << "[TEF_" << indx << ", TEFD_"<< indx << "] = "; - else - output << "TEF_" << indx << " = "; - - output << datatree.symbol_table.getName(symb_id) << "("; - writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms); - output << ");" << endl; - } - } -} - -void -ExternalFunctionNode::writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); - assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms, isdynamic); - - if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) - { - tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size(); - int indx = getIndxInTefTerms(symb_id, tef_terms); - int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); - assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); - - stringstream ef; - ef << "{\"external_function\": {" - << "\"external_function_term\": \"TEF_" << indx << "\""; - - if (symb_id == first_deriv_symb_id) - ef << ", \"external_function_term_d\": \"TEFD_" << indx << "\""; - - if (symb_id == second_deriv_symb_id) - ef << ", \"external_function_term_dd\": \"TEFDD_" << indx << "\""; - - ef << ", \"value\": \"" << datatree.symbol_table.getName(symb_id) << "("; - writeJsonExternalFunctionArguments(ef, temporary_terms, tef_terms, isdynamic); - ef << ")\"}}"; - efout.push_back(ef.str()); - } -} - -expr_t -ExternalFunctionNode::toStatic(DataTree &static_datatree) const -{ - vector static_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - static_arguments.push_back((*it)->toStatic(static_datatree)); - return static_datatree.AddExternalFunction(symb_id, static_arguments); -} - -void -ExternalFunctionNode::computeXrefs(EquationInfo &ei) const -{ - vector dynamic_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->computeXrefs(ei); -} - -expr_t -ExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const -{ - vector dynamic_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - dynamic_arguments.push_back((*it)->cloneDynamic(dynamic_datatree)); - return dynamic_datatree.AddExternalFunction(symb_id, dynamic_arguments); -} - -expr_t -ExternalFunctionNode::buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const -{ - return alt_datatree.AddExternalFunction(symb_id, alt_args); -} - -FirstDerivExternalFunctionNode::FirstDerivExternalFunctionNode(DataTree &datatree_arg, - int top_level_symb_id_arg, - const vector &arguments_arg, - int inputIndex_arg) : - AbstractExternalFunctionNode(datatree_arg, top_level_symb_id_arg, arguments_arg), - inputIndex(inputIndex_arg) -{ - // Add myself to the first derivative external function map - datatree.first_deriv_external_function_node_map[make_pair(make_pair(arguments, inputIndex), symb_id)] = this; -} - -void -FirstDerivExternalFunctionNode::computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const -{ - temp_terms_map[tr].insert(const_cast(this)); -} - -void -FirstDerivExternalFunctionNode::computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const -{ - expr_t this2 = const_cast(this); - temporary_terms.insert(this2); - first_occurence[this2] = make_pair(Curr_block, equation); - v_temporary_terms[Curr_block][equation].insert(this2); -} - -expr_t -FirstDerivExternalFunctionNode::composeDerivatives(const vector &dargs) -{ - vector dNodes; - for (int i = 0; i < (int) dargs.size(); i++) - dNodes.push_back(datatree.AddTimes(dargs.at(i), - datatree.AddSecondDerivExternalFunction(symb_id, arguments, inputIndex, i+1))); - expr_t theDeriv = datatree.Zero; - for (vector::const_iterator it = dNodes.begin(); it != dNodes.end(); it++) - theDeriv = datatree.AddPlus(theDeriv, *it); - return theDeriv; -} - -void -FirstDerivExternalFunctionNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - // If current node is a temporary term - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - output << "T" << idx; - return; - } - - const int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); - assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - - const int tmpIndx = inputIndex - 1; - - if (first_deriv_symb_id == symb_id) - output << "TEFD_" << getIndxInTefTerms(symb_id, tef_terms) - << "[" << tmpIndx << "]"; - else if (first_deriv_symb_id == eExtFunNotSet) - output << "TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex; - else - output << "TEFD_def_" << getIndxInTefTerms(first_deriv_symb_id, tef_terms) - << "[" << tmpIndx << "]"; -} - -void -FirstDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - assert(output_type != oMatlabOutsideModel); - - if (IS_LATEX(output_type)) - { - output << "\\frac{\\partial " << datatree.symbol_table.getTeXName(symb_id) - << "}{\\partial " << inputIndex << "}("; - writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms); - output << ")"; - return; - } - - // If current node is a temporary term - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (output_type == oMatlabDynamicModelSparse) - output << "T" << idx << "(it_)"; - else - output << "T" << idx; - return; - } - - const int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); - assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - - const int tmpIndx = inputIndex - 1 + ARRAY_SUBSCRIPT_OFFSET(output_type); - - if (first_deriv_symb_id == symb_id) - output << "TEFD_" << getIndxInTefTerms(symb_id, tef_terms) - << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndx << RIGHT_ARRAY_SUBSCRIPT(output_type); - else if (first_deriv_symb_id == eExtFunNotSet) - { - if (IS_C(output_type)) - output << "*"; - output << "TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex; - } - else - output << "TEFD_def_" << getIndxInTefTerms(first_deriv_symb_id, tef_terms) - << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndx << RIGHT_ARRAY_SUBSCRIPT(output_type); -} - -void -FirstDerivExternalFunctionNode::compile(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (dynamic) - { - map_idx_t::const_iterator ii = map_idx.find(idx); - FLDT_ fldt(ii->second); - fldt.write(CompileCode, instruction_number); - } - else - { - map_idx_t::const_iterator ii = map_idx.find(idx); - FLDST_ fldst(ii->second); - fldst.write(CompileCode, instruction_number); - } - return; - } - int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); - assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - - if (!lhs_rhs) - { - FLDTEFD_ fldtefd(getIndxInTefTerms(symb_id, tef_terms), inputIndex); - fldtefd.write(CompileCode, instruction_number); - } - else - { - FSTPTEFD_ fstptefd(getIndxInTefTerms(symb_id, tef_terms), inputIndex); - fstptefd.write(CompileCode, instruction_number); - } -} - -void -FirstDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - assert(output_type != oMatlabOutsideModel); - int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); - assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - - /* For a node with derivs provided by the user function, call the method - on the non-derived node */ - if (first_deriv_symb_id == symb_id) - { - expr_t parent = datatree.AddExternalFunction(symb_id, arguments); - parent->writeExternalFunctionOutput(output, output_type, temporary_terms, - tef_terms); - return; - } - - if (alreadyWrittenAsTefTerm(first_deriv_symb_id, tef_terms)) - return; - - if (IS_C(output_type)) - if (first_deriv_symb_id == eExtFunNotSet) - { - stringstream ending; - ending << "_tefd_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex; - output << "int nlhs" << ending.str() << " = 1;" << endl - << "double *TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex << ";" << endl - << "mxArray *plhs" << ending.str() << "[nlhs"<< ending.str() << "];" << endl - << "int nrhs" << ending.str() << " = 3;" << endl - << "mxArray *prhs" << ending.str() << "[nrhs"<< ending.str() << "];" << endl - << "mwSize dims" << ending.str() << "[2];" << endl; - - output << "dims" << ending.str() << "[0] = 1;" << endl - << "dims" << ending.str() << "[1] = " << arguments.size() << ";" << endl; - - output << "prhs" << ending.str() << "[0] = mxCreateString(\"" << datatree.symbol_table.getName(symb_id) << "\");" << endl - << "prhs" << ending.str() << "[1] = mxCreateDoubleScalar(" << inputIndex << ");"<< endl - << "prhs" << ending.str() << "[2] = mxCreateCellArray(2, dims" << ending.str() << ");"<< endl; - - int i = 0; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - { - output << "mxSetCell(prhs" << ending.str() << "[2], " - << i++ << ", " - << "mxCreateDoubleScalar("; // All external_function arguments are scalars - (*it)->writeOutput(output, output_type, temporary_terms, tef_terms); - output << "));" << endl; - } - - output << "mexCallMATLAB(" - << "nlhs" << ending.str() << ", " - << "plhs" << ending.str() << ", " - << "nrhs" << ending.str() << ", " - << "prhs" << ending.str() << ", \"" - << "jacob_element\");" << endl; - - output << "TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex - << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl; - } - else - { - tef_terms[make_pair(first_deriv_symb_id, arguments)] = (int) tef_terms.size(); - int indx = getIndxInTefTerms(first_deriv_symb_id, tef_terms); - stringstream ending; - ending << "_tefd_def_" << indx; - output << "int nlhs" << ending.str() << " = 1;" << endl - << "double *TEFD_def_" << indx << ";" << endl - << "mxArray *plhs" << ending.str() << "[nlhs"<< ending.str() << "];" << endl - << "int nrhs" << ending.str() << " = " << arguments.size() << ";" << endl; - writePrhs(output, output_type, temporary_terms, tef_terms, ending.str()); - - output << "mexCallMATLAB(" - << "nlhs" << ending.str() << ", " - << "plhs" << ending.str() << ", " - << "nrhs" << ending.str() << ", " - << "prhs" << ending.str() << ", \"" - << datatree.symbol_table.getName(first_deriv_symb_id) << "\");" << endl; - - output << "TEFD_def_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl; - } - else - { - if (first_deriv_symb_id == eExtFunNotSet) - output << "TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex << " = jacob_element('" - << datatree.symbol_table.getName(symb_id) << "'," << inputIndex << ",{"; - else - { - tef_terms[make_pair(first_deriv_symb_id, arguments)] = (int) tef_terms.size(); - output << "TEFD_def_" << getIndxInTefTerms(first_deriv_symb_id, tef_terms) - << " = " << datatree.symbol_table.getName(first_deriv_symb_id) << "("; - } - - writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms); - - if (first_deriv_symb_id == eExtFunNotSet) - output << "}"; - output << ");" << endl; - } -} - -void -FirstDerivExternalFunctionNode::writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); - assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - - /* For a node with derivs provided by the user function, call the method - on the non-derived node */ - if (first_deriv_symb_id == symb_id) - { - expr_t parent = datatree.AddExternalFunction(symb_id, arguments); - parent->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms, isdynamic); - return; - } - - if (alreadyWrittenAsTefTerm(first_deriv_symb_id, tef_terms)) - return; - - stringstream ef; - if (first_deriv_symb_id == eExtFunNotSet) - ef << "{\"first_deriv_external_function\": {" - << "\"external_function_term\": \"TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex << "\"" - << ", \"analytic_derivative\": false" - << ", \"wrt\": " << inputIndex - << ", \"value\": \"" << datatree.symbol_table.getName(symb_id) << "("; - else - { - tef_terms[make_pair(first_deriv_symb_id, arguments)] = (int) tef_terms.size(); - ef << "{\"first_deriv_external_function\": {" - << "\"external_function_term\": \"TEFD_def_" << getIndxInTefTerms(first_deriv_symb_id, tef_terms) << "\"" - << ", \"analytic_derivative\": true" - << ", \"value\": \"" << datatree.symbol_table.getName(first_deriv_symb_id) << "("; - } - - writeJsonExternalFunctionArguments(ef, temporary_terms, tef_terms, isdynamic); - ef << ")\"}}"; - efout.push_back(ef.str()); -} - -void -FirstDerivExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); - assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - - if (first_deriv_symb_id == symb_id || alreadyWrittenAsTefTerm(first_deriv_symb_id, tef_terms)) - return; - - unsigned int nb_add_input_arguments = compileExternalFunctionArguments(CompileCode, instruction_number, lhs_rhs, temporary_terms, - map_idx, dynamic, steady_dynamic, tef_terms); - if (first_deriv_symb_id == eExtFunNotSet) - { - unsigned int nb_input_arguments = 0; - unsigned int nb_output_arguments = 1; - unsigned int indx = getIndxInTefTerms(symb_id, tef_terms); - FCALL_ fcall(nb_output_arguments, nb_input_arguments, "jacob_element", indx); - fcall.set_arg_func_name(datatree.symbol_table.getName(symb_id)); - fcall.set_row(inputIndex); - fcall.set_nb_add_input_arguments(nb_add_input_arguments); - fcall.set_function_type(ExternalFunctionNumericalFirstDerivative); - fcall.write(CompileCode, instruction_number); - FSTPTEFD_ fstptefd(indx, inputIndex); - fstptefd.write(CompileCode, instruction_number); - } - else - { - tef_terms[make_pair(first_deriv_symb_id, arguments)] = (int) tef_terms.size(); - int indx = getIndxInTefTerms(symb_id, tef_terms); - int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); - assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); - - unsigned int nb_output_arguments = 1; - - FCALL_ fcall(nb_output_arguments, nb_add_input_arguments, datatree.symbol_table.getName(first_deriv_symb_id), indx); - fcall.set_function_type(ExternalFunctionFirstDerivative); - fcall.write(CompileCode, instruction_number); - FSTPTEFD_ fstptefd(indx, inputIndex); - fstptefd.write(CompileCode, instruction_number); - } -} - -expr_t -FirstDerivExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const -{ - vector dynamic_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - dynamic_arguments.push_back((*it)->cloneDynamic(dynamic_datatree)); - return dynamic_datatree.AddFirstDerivExternalFunction(symb_id, dynamic_arguments, - inputIndex); -} - -expr_t -FirstDerivExternalFunctionNode::buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const -{ - return alt_datatree.AddFirstDerivExternalFunction(symb_id, alt_args, inputIndex); -} - -expr_t -FirstDerivExternalFunctionNode::toStatic(DataTree &static_datatree) const -{ - vector static_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - static_arguments.push_back((*it)->toStatic(static_datatree)); - return static_datatree.AddFirstDerivExternalFunction(symb_id, static_arguments, - inputIndex); -} - -void -FirstDerivExternalFunctionNode::computeXrefs(EquationInfo &ei) const -{ - vector dynamic_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->computeXrefs(ei); -} - -SecondDerivExternalFunctionNode::SecondDerivExternalFunctionNode(DataTree &datatree_arg, - int top_level_symb_id_arg, - const vector &arguments_arg, - int inputIndex1_arg, - int inputIndex2_arg) : - AbstractExternalFunctionNode(datatree_arg, top_level_symb_id_arg, arguments_arg), - inputIndex1(inputIndex1_arg), - inputIndex2(inputIndex2_arg) -{ - // Add myself to the second derivative external function map - datatree.second_deriv_external_function_node_map[make_pair(make_pair(arguments, make_pair(inputIndex1, inputIndex2)), symb_id)] = this; -} - -void -SecondDerivExternalFunctionNode::computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const -{ - temp_terms_map[tr].insert(const_cast(this)); -} - -void -SecondDerivExternalFunctionNode::computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const -{ - expr_t this2 = const_cast(this); - temporary_terms.insert(this2); - first_occurence[this2] = make_pair(Curr_block, equation); - v_temporary_terms[Curr_block][equation].insert(this2); -} - -expr_t -SecondDerivExternalFunctionNode::composeDerivatives(const vector &dargs) - -{ - cerr << "ERROR: third order derivatives of external functions are not implemented" << endl; - exit(EXIT_FAILURE); -} - -void -SecondDerivExternalFunctionNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - // If current node is a temporary term - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - output << "T" << idx; - return; - } - - const int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); - assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); - - const int tmpIndex1 = inputIndex1 - 1; - const int tmpIndex2 = inputIndex2 - 1; - - if (second_deriv_symb_id == symb_id) - output << "TEFDD_" << getIndxInTefTerms(symb_id, tef_terms) - << "[" << tmpIndex1 << "," << tmpIndex2 << "]"; - else if (second_deriv_symb_id == eExtFunNotSet) - output << "TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2; - else - output << "TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) - << "[" << tmpIndex1 << "," << tmpIndex2 << "]"; -} - -void -SecondDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - assert(output_type != oMatlabOutsideModel); - - if (IS_LATEX(output_type)) - { - output << "\\frac{\\partial^2 " << datatree.symbol_table.getTeXName(symb_id) - << "}{\\partial " << inputIndex1 << "\\partial " << inputIndex2 << "}("; - writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms); - output << ")"; - return; - } - - // If current node is a temporary term - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (output_type == oMatlabDynamicModelSparse) - output << "T" << idx << "(it_)"; - else - output << "T" << idx; - return; - } - - const int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); - assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); - - const int tmpIndex1 = inputIndex1 - 1 + ARRAY_SUBSCRIPT_OFFSET(output_type); - const int tmpIndex2 = inputIndex2 - 1 + ARRAY_SUBSCRIPT_OFFSET(output_type); - - int indx = getIndxInTefTerms(symb_id, tef_terms); - if (second_deriv_symb_id == symb_id) - if (IS_C(output_type)) - output << "TEFDD_" << indx - << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndex1 << " * TEFDD_" << indx << "_nrows + " - << tmpIndex2 << RIGHT_ARRAY_SUBSCRIPT(output_type); - else - output << "TEFDD_" << getIndxInTefTerms(symb_id, tef_terms) - << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndex1 << "," << tmpIndex2 << RIGHT_ARRAY_SUBSCRIPT(output_type); - else if (second_deriv_symb_id == eExtFunNotSet) - { - if (IS_C(output_type)) - output << "*"; - output << "TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2; - } - else - if (IS_C(output_type)) - output << "TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) - << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndex1 << " * PROBLEM_" << indx << "_nrows" - << tmpIndex2 << RIGHT_ARRAY_SUBSCRIPT(output_type); - else - output << "TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) - << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndex1 << "," << tmpIndex2 << RIGHT_ARRAY_SUBSCRIPT(output_type); -} - -void -SecondDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - assert(output_type != oMatlabOutsideModel); - int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); - assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); - - /* For a node with derivs provided by the user function, call the method - on the non-derived node */ - if (second_deriv_symb_id == symb_id) - { - expr_t parent = datatree.AddExternalFunction(symb_id, arguments); - parent->writeExternalFunctionOutput(output, output_type, temporary_terms, - tef_terms); - return; - } - - if (alreadyWrittenAsTefTerm(second_deriv_symb_id, tef_terms)) - return; - - if (IS_C(output_type)) - if (second_deriv_symb_id == eExtFunNotSet) - { - stringstream ending; - ending << "_tefdd_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2; - output << "int nlhs" << ending.str() << " = 1;" << endl - << "double *TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2 << ";" << endl - << "mxArray *plhs" << ending.str() << "[nlhs"<< ending.str() << "];" << endl - << "int nrhs" << ending.str() << " = 4;" << endl - << "mxArray *prhs" << ending.str() << "[nrhs"<< ending.str() << "];" << endl - << "mwSize dims" << ending.str() << "[2];" << endl; - - output << "dims" << ending.str() << "[0] = 1;" << endl - << "dims" << ending.str() << "[1] = " << arguments.size() << ";" << endl; - - output << "prhs" << ending.str() << "[0] = mxCreateString(\"" << datatree.symbol_table.getName(symb_id) << "\");" << endl - << "prhs" << ending.str() << "[1] = mxCreateDoubleScalar(" << inputIndex1 << ");"<< endl - << "prhs" << ending.str() << "[2] = mxCreateDoubleScalar(" << inputIndex2 << ");"<< endl - << "prhs" << ending.str() << "[3] = mxCreateCellArray(2, dims" << ending.str() << ");"<< endl; - - int i = 0; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - { - output << "mxSetCell(prhs" << ending.str() << "[3], " - << i++ << ", " - << "mxCreateDoubleScalar("; // All external_function arguments are scalars - (*it)->writeOutput(output, output_type, temporary_terms, tef_terms); - output << "));" << endl; - } - - output << "mexCallMATLAB(" - << "nlhs" << ending.str() << ", " - << "plhs" << ending.str() << ", " - << "nrhs" << ending.str() << ", " - << "prhs" << ending.str() << ", \"" - << "hess_element\");" << endl; - - output << "TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2 - << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl; - } - else - { - tef_terms[make_pair(second_deriv_symb_id, arguments)] = (int) tef_terms.size(); - int indx = getIndxInTefTerms(second_deriv_symb_id, tef_terms); - stringstream ending; - ending << "_tefdd_def_" << indx; - - output << "int nlhs" << ending.str() << " = 1;" << endl - << "double *TEFDD_def_" << indx << ";" << endl - << "mxArray *plhs" << ending.str() << "[nlhs"<< ending.str() << "];" << endl - << "int nrhs" << ending.str() << " = " << arguments.size() << ";" << endl; - writePrhs(output, output_type, temporary_terms, tef_terms, ending.str()); - - output << "mexCallMATLAB(" - << "nlhs" << ending.str() << ", " - << "plhs" << ending.str() << ", " - << "nrhs" << ending.str() << ", " - << "prhs" << ending.str() << ", \"" - << datatree.symbol_table.getName(second_deriv_symb_id) << "\");" << endl; - - output << "TEFDD_def_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl; - } - else - { - if (second_deriv_symb_id == eExtFunNotSet) - output << "TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2 - << " = hess_element('" << datatree.symbol_table.getName(symb_id) << "'," - << inputIndex1 << "," << inputIndex2 << ",{"; - else - { - tef_terms[make_pair(second_deriv_symb_id, arguments)] = (int) tef_terms.size(); - output << "TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) - << " = " << datatree.symbol_table.getName(second_deriv_symb_id) << "("; - } - - writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms); - - if (second_deriv_symb_id == eExtFunNotSet) - output << "}"; - output << ");" << endl; - } -} - -void -SecondDerivExternalFunctionNode::writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const -{ - int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); - assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); - - /* For a node with derivs provided by the user function, call the method - on the non-derived node */ - if (second_deriv_symb_id == symb_id) - { - expr_t parent = datatree.AddExternalFunction(symb_id, arguments); - parent->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms, isdynamic); - return; - } - - if (alreadyWrittenAsTefTerm(second_deriv_symb_id, tef_terms)) - return; - - stringstream ef; - if (second_deriv_symb_id == eExtFunNotSet) - ef << "{\"second_deriv_external_function\": {" - << "\"external_function_term\": \"TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2 << "\"" - << ", \"analytic_derivative\": false" - << ", \"wrt1\": " << inputIndex1 - << ", \"wrt2\": " << inputIndex2 - << ", \"value\": \"" << datatree.symbol_table.getName(symb_id) << "("; - else - { - tef_terms[make_pair(second_deriv_symb_id, arguments)] = (int) tef_terms.size(); - ef << "{\"second_deriv_external_function\": {" - << "\"external_function_term\": \"TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) << "\"" - << ", \"analytic_derivative\": true" - << ", \"value\": \"" << datatree.symbol_table.getName(second_deriv_symb_id) << "("; - } - - writeJsonExternalFunctionArguments(ef, temporary_terms, tef_terms, isdynamic); - ef << ")\"}}" << endl; - efout.push_back(ef.str()); -} - -expr_t -SecondDerivExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const -{ - vector dynamic_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - dynamic_arguments.push_back((*it)->cloneDynamic(dynamic_datatree)); - return dynamic_datatree.AddSecondDerivExternalFunction(symb_id, dynamic_arguments, - inputIndex1, inputIndex2); -} - -expr_t -SecondDerivExternalFunctionNode::buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const -{ - return alt_datatree.AddSecondDerivExternalFunction(symb_id, alt_args, inputIndex1, inputIndex2); -} - -expr_t -SecondDerivExternalFunctionNode::toStatic(DataTree &static_datatree) const -{ - vector static_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - static_arguments.push_back((*it)->toStatic(static_datatree)); - return static_datatree.AddSecondDerivExternalFunction(symb_id, static_arguments, - inputIndex1, inputIndex2); -} - -void -SecondDerivExternalFunctionNode::computeXrefs(EquationInfo &ei) const -{ - vector dynamic_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->computeXrefs(ei); -} - -void -SecondDerivExternalFunctionNode::compile(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - cerr << "SecondDerivExternalFunctionNode::compile: not implemented." << endl; - exit(EXIT_FAILURE); -} - -void -SecondDerivExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - cerr << "SecondDerivExternalFunctionNode::compileExternalFunctionOutput: not implemented." << endl; - exit(EXIT_FAILURE); -} diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh deleted file mode 100644 index 7bdd9a675..000000000 --- a/preprocessor/ExprNode.hh +++ /dev/null @@ -1,1093 +0,0 @@ -/* - * 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 . - */ - -#ifndef _EXPR_NODE_HH -#define _EXPR_NODE_HH - -#include -#include -#include -#include - -using namespace std; - -#include "SymbolTable.hh" -#include "CodeInterpreter.hh" -#include "ExternalFunctionsTable.hh" - -class DataTree; -class VariableNode; -class BinaryOpNode; - -typedef class ExprNode *expr_t; - -struct ExprNodeLess; - -//! Type for set of temporary terms -/*! They are ordered by index number thanks to ExprNodeLess */ -typedef set temporary_terms_t; - -//! set of temporary terms used in a block -typedef set temporary_terms_inuse_t; - -typedef map map_idx_t; - -//! Type for evaluation contexts -/*! The key is a symbol id. Lags are assumed to be null */ -typedef map eval_context_t; - -//! Type for tracking first/second derivative functions that have already been written as temporary terms -typedef map >, int> deriv_node_temp_terms_t; - -//! Possible types of output when writing ExprNode(s) -enum ExprNodeOutputType - { - oMatlabStaticModel, //!< Matlab code, static model - oMatlabDynamicModel, //!< Matlab code, dynamic model - oMatlabStaticModelSparse, //!< Matlab code, static block decomposed model - oMatlabDynamicModelSparse, //!< Matlab code, dynamic block decomposed model - oCDynamicModel, //!< C code, dynamic model - oCDynamic2Model, //!< C code, dynamic model, alternative numbering of endogenous variables - oCStaticModel, //!< C code, static model - oJuliaStaticModel, //!< Julia code, static model - oJuliaDynamicModel, //!< Julia code, dynamic model - oMatlabOutsideModel, //!< Matlab code, outside model block (for example in initval) - oLatexStaticModel, //!< LaTeX code, static model - oLatexDynamicModel, //!< LaTeX code, dynamic model - oLatexDynamicSteadyStateOperator, //!< LaTeX code, dynamic model, inside a steady state operator - oMatlabDynamicSteadyStateOperator, //!< Matlab code, dynamic model, inside a steady state operator - oMatlabDynamicSparseSteadyStateOperator, //!< Matlab code, dynamic block decomposed model, inside a steady state operator - oCDynamicSteadyStateOperator, //!< C code, dynamic model, inside a steady state operator - oJuliaDynamicSteadyStateOperator, //!< Julia code, dynamic model, inside a steady state operator - oSteadyStateFile, //!< Matlab code, in the generated steady state file - oCSteadyStateFile, //!< C code, in the generated steady state file - oJuliaSteadyStateFile //!< Julia code, in the generated steady state file - }; - -#define IS_MATLAB(output_type) ((output_type) == oMatlabStaticModel \ - || (output_type) == oMatlabDynamicModel \ - || (output_type) == oMatlabOutsideModel \ - || (output_type) == oMatlabStaticModelSparse \ - || (output_type) == oMatlabDynamicModelSparse \ - || (output_type) == oMatlabDynamicSteadyStateOperator \ - || (output_type) == oMatlabDynamicSparseSteadyStateOperator \ - || (output_type) == oSteadyStateFile) - -#define IS_JULIA(output_type) ((output_type) == oJuliaStaticModel \ - || (output_type) == oJuliaDynamicModel \ - || (output_type) == oJuliaDynamicSteadyStateOperator \ - || (output_type) == oJuliaSteadyStateFile) - -#define IS_C(output_type) ((output_type) == oCDynamicModel \ - || (output_type) == oCDynamic2Model \ - || (output_type) == oCStaticModel \ - || (output_type) == oCDynamicSteadyStateOperator \ - || (output_type) == oCSteadyStateFile) - -#define IS_LATEX(output_type) ((output_type) == oLatexStaticModel \ - || (output_type) == oLatexDynamicModel \ - || (output_type) == oLatexDynamicSteadyStateOperator) - -/* Equal to 1 for Matlab langage or Julia, or to 0 for C language. Not defined for LaTeX. - In Matlab and Julia, array indexes begin at 1, while they begin at 0 in C */ -#define ARRAY_SUBSCRIPT_OFFSET(output_type) ((int) (IS_MATLAB(output_type) || IS_JULIA(output_type))) - -// Left and right array subscript delimiters: '(' and ')' for Matlab, '[' and ']' for C -#define LEFT_ARRAY_SUBSCRIPT(output_type) (IS_MATLAB(output_type) ? '(' : '[') -#define RIGHT_ARRAY_SUBSCRIPT(output_type) (IS_MATLAB(output_type) ? ')' : ']') - -// Left and right parentheses -#define LEFT_PAR(output_type) (IS_LATEX(output_type) ? "\\left(" : "(") -#define RIGHT_PAR(output_type) (IS_LATEX(output_type) ? "\\right)" : ")") - -// Computing cost above which a node can be declared a temporary term -#define MIN_COST_MATLAB (40*90) -#define MIN_COST_C (40*4) -#define MIN_COST(is_matlab) ((is_matlab) ? MIN_COST_MATLAB : MIN_COST_C) - -//! Base class for expression nodes - class ExprNode - { - friend class DataTree; - friend class DynamicModel; - friend class StaticModel; - friend class ModelTree; - friend struct ExprNodeLess; - friend class NumConstNode; - friend class VariableNode; - friend class UnaryOpNode; - friend class BinaryOpNode; - friend class TrinaryOpNode; - friend class AbstractExternalFunctionNode; - private: - //! Computes derivative w.r. to a derivation ID (but doesn't store it in derivatives map) - /*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */ - virtual expr_t computeDerivative(int deriv_id) = 0; - - protected: - //! Reference to the enclosing DataTree - DataTree &datatree; - - //! Index number - int idx; - - //! Is the data member non_null_derivatives initialized ? - bool preparedForDerivation; - - //! Set of derivation IDs with respect to which the derivative is potentially non-null - set non_null_derivatives; - - //! Used for caching of first order derivatives (when non-null) - map derivatives; - - //! Cost of computing current node - /*! Nodes included in temporary_terms are considered having a null cost */ - virtual int cost(int cost, bool is_matlab) const; - virtual int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const; - virtual int cost(const map &temp_terms_map, bool is_matlab) const; - - //! For creating equation cross references - struct EquationInfo - { - set > param; - set > endo; - set > exo; - set > exo_det; - }; - - public: - ExprNode(DataTree &datatree_arg); - virtual - ~ExprNode(); - - //! Initializes data member non_null_derivatives - virtual void prepareForDerivation() = 0; - - //! Returns derivative w.r. to derivation ID - /*! Uses a symbolic a priori to pre-detect null derivatives, and caches the result for other derivatives (to avoid computing it several times) - For an equal node, returns the derivative of lhs minus rhs */ - expr_t getDerivative(int deriv_id); - - //! Computes derivatives by applying the chain rule for some variables - /*! - \param deriv_id The derivation ID with respect to which we are derivating - \param recursive_variables Contains the derivation ID for which chain rules must be applied. Keys are derivation IDs, values are equations of the form x=f(y) where x is the key variable and x doesn't appear in y - */ - virtual expr_t getChainRuleDerivative(int deriv_id, const map &recursive_variables) = 0; - - //! Returns precedence of node - /*! Equals 100 for constants, variables, unary ops, and temporary terms */ - virtual int precedence(ExprNodeOutputType output_t, const temporary_terms_t &temporary_terms) const; - - //! Fills temporary_terms set, using reference counts - /*! A node will be marked as a temporary term if it is referenced at least two times (i.e. has at least two parents), and has a computing cost (multiplied by reference count) greater to datatree.min_cost */ - virtual void computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const; - - //! Writes output of node, using a Txxx notation for nodes in temporary_terms, and specifiying the set of already written external functions - /*! - \param[in] output the output stream - \param[in] output_type the type of output (MATLAB, C, LaTeX...) - \param[in] temporary_terms the nodes that are marked as temporary terms - \param[in,out] tef_terms the set of already written external function nodes - */ - virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0; - - //! returns true if the expr node contains an external function - virtual bool containsExternalFunction() const = 0; - - //! Writes output of node (with no temporary terms and with "outside model" output type) - void writeOutput(ostream &output) const; - - //! Writes output of node (with no temporary terms) - void writeOutput(ostream &output, ExprNodeOutputType output_type) const; - - //! Writes output of node, using a Txxx notation for nodes in temporary_terms - void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const; - - //! Writes output of node in JSON syntax - virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const bool isdynamic = true) const = 0; - - virtual int precedenceJson(const temporary_terms_t &temporary_terms) const; - - //! Writes the output for an external function, ensuring that the external function is called as few times as possible using temporary terms - virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const; - - //! Write the JSON output of an external function in a string vector - //! Allows the insertion of commas if necessary - virtual void writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic = true) const; - - virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const; - - //! Computes the set of all variables of a given symbol type in the expression (with information on lags) - /*! - Variables are stored as integer pairs of the form (symb_id, lag). - They are added to the set given in argument. - Note that model local variables are substituted by their expression in the computation - (and added if type_arg = ModelLocalVariable). - */ - virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const = 0; - - //! Computes the set of all variables of a given symbol type in the expression (without information on lags) - /*! - Variables are stored as symb_id. - They are added to the set given in argument. - Note that model local variables are substituted by their expression in the computation - (and added if type_arg = ModelLocalVariable). - */ - void collectVariables(SymbolType type_arg, set &result) const; - - //! Computes the set of endogenous variables in the expression - /*! - Endogenous are stored as integer pairs of the form (type_specific_id, lag). - They are added to the set given in argument. - Note that model local variables are substituted by their expression in the computation. - */ - virtual void collectEndogenous(set > &result) const; - - //! Computes the set of exogenous variables in the expression - /*! - Exogenous are stored as integer pairs of the form (type_specific_id, lag). - They are added to the set given in argument. - Note that model local variables are substituted by their expression in the computation. - */ - virtual void collectExogenous(set > &result) const; - - virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const = 0; - - virtual void computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const; - - class EvalException - - { - }; - - class EvalExternalFunctionException : public EvalException - - { - }; - - virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) = 0; - virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const = 0; - void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const; - //! Creates a static version of this node - /*! - This method duplicates the current node by creating a similar node from which all leads/lags have been stripped, - adds the result in the static_datatree argument (and not in the original datatree), and returns it. - */ - virtual expr_t toStatic(DataTree &static_datatree) const = 0; - - /*! - Compute cross references for equations - */ - // virtual void computeXrefs(set ¶m, set &endo, set &exo, set &exo_det) const = 0; - virtual void computeXrefs(EquationInfo &ei) const = 0; - //! Try to normalize an equation linear in its endogenous variable - virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const = 0; - - //! Returns the maximum lead of endogenous in this expression - /*! Always returns a non-negative value */ - virtual int maxEndoLead() const = 0; - - //! Returns the maximum lead of exogenous in this expression - /*! Always returns a non-negative value */ - virtual int maxExoLead() const = 0; - - //! Returns the maximum lag of endogenous in this expression - /*! Always returns a non-negative value */ - virtual int maxEndoLag() const = 0; - - //! Returns the maximum lag of exogenous in this expression - /*! Always returns a non-negative value */ - virtual int maxExoLag() const = 0; - - //! Returns the relative period of the most forward term in this expression - /*! A negative value means that the expression contains only lagged variables */ - virtual int maxLead() const = 0; - - //! Returns a new expression where all the leads/lags have been shifted backwards by the same amount - /*! - Only acts on endogenous, exogenous, exogenous det - \param[in] n The number of lags by which to shift - \return The same expression except that leads/lags have been shifted backwards - */ - virtual expr_t decreaseLeadsLags(int n) const = 0; - - //! Type for the substitution map used in the process of creating auxiliary vars for leads >= 2 - typedef map subst_table_t; - - //! Creates auxiliary endo lead variables corresponding to this expression - /*! - If maximum endogenous lead >= 3, this method will also create intermediary auxiliary var, and will add the equations of the form aux1 = aux2(+1) to the substitution table. - \pre This expression is assumed to have maximum endogenous lead >= 2 - \param[in,out] subst_table The table to which new auxiliary variables and their correspondance will be added - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. - \return The new variable node corresponding to the current expression - */ - VariableNode *createEndoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector &neweqs) const; - - //! Creates auxiliary exo lead variables corresponding to this expression - /*! - If maximum exogenous lead >= 2, this method will also create intermediary auxiliary var, and will add the equations of the form aux1 = aux2(+1) to the substitution table. - \pre This expression is assumed to have maximum exogenous lead >= 1 - \param[in,out] subst_table The table to which new auxiliary variables and their correspondance will be added - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. - \return The new variable node corresponding to the current expression - */ - VariableNode *createExoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector &neweqs) const; - - //! Constructs a new expression where sub-expressions with max endo lead >= 2 have been replaced by auxiliary variables - /*! - \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr. - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. - - If the method detects a sub-expr which needs to be substituted, two cases are possible: - - if this expr is in the table, then it will use the corresponding variable and return the substituted expression - - if this expr is not in the table, then it will create an auxiliary endogenous variable, add the substitution in the table and return the substituted expression - - \return A new equivalent expression where sub-expressions with max endo lead >= 2 have been replaced by auxiliary variables - */ - virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const = 0; - - //! Constructs a new expression where endo variables with max endo lag >= 2 have been replaced by auxiliary variables - /*! - \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr. - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. - */ - virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const = 0; - - //! Constructs a new expression where exogenous variables with a lead have been replaced by auxiliary variables - /*! - \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr. - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. - */ - virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const = 0; - //! Constructs a new expression where exogenous variables with a lag have been replaced by auxiliary variables - /*! - \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr. - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. - */ - virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const = 0; - - //! Constructs a new expression where the expectation operator has been replaced by auxiliary variables - /*! - \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr. - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. - \param[in] partial_information_model Are we substituting in a partial information model? - */ - virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const = 0; - - virtual expr_t decreaseLeadsLagsPredeterminedVariables() const = 0; - - //! Constructs a new expression where forward variables (supposed to be at most in t+1) have been replaced by themselves at t, plus a new aux var representing their (time) differentiate - /*! - \param[in] subset variables to which to limit the transformation; transform - all fwrd vars if empty - \param[in,out] subst_table Map used to store mapping between a given - forward variable and the aux var that contains its differentiate - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. - */ - virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const = 0; - - //! Return true if the nodeID is a numerical constant equal to value and false otherwise - /*! - \param[in] value of the numerical constante - \param[out] the boolean equal to true if NodeId is a constant equal to value - */ - virtual bool isNumConstNodeEqualTo(double value) const = 0; - - //! Returns true if the expression contains one or several endogenous variable - virtual bool containsEndogenous(void) const = 0; - - //! Returns true if the expression contains one or several exogenous variable - virtual bool containsExogenous() const = 0; - - //! Return true if the nodeID is a variable withe a type equal to type_arg, a specific variable id aqual to varfiable_id and a lag equal to lag_arg and false otherwise - /*! - \param[in] the type (type_arg), specifique variable id (variable_id and the lag (lag_arg) - \param[out] the boolean equal to true if NodeId is the variable - */ - virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const = 0; - - //! Replaces the Trend var with datatree.One - virtual expr_t replaceTrendVar() const = 0; - - //! Constructs a new expression where the variable indicated by symb_id has been detrended - /*! - \param[in] symb_id indicating the variable to be detrended - \param[in] log_trend indicates if the trend is in log - \param[in] trend indicating the trend - \return the new binary op pointing to a detrended variable - */ - virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const = 0; - - //! Add ExprNodes to the provided datatree - virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const = 0; - - //! Move a trend variable with lag/lead to time t by dividing/multiplying by its growth factor - virtual expr_t removeTrendLeadLag(map trend_symbols_map) const = 0; - - //! Returns true if the expression is in static form (no lead, no lag, no expectation, no STEADY_STATE) - virtual bool isInStaticForm() const = 0; - - //! Substitute auxiliary variables by their expression in static model - virtual expr_t substituteStaticAuxiliaryVariable() const = 0; - }; - -//! Object used to compare two nodes (using their indexes) -struct ExprNodeLess -{ - bool - operator()(expr_t arg1, expr_t arg2) const - { - return arg1->idx < arg2->idx; - } -}; - -//! Numerical constant node -/*! The constant is necessarily non-negative (this is enforced at the NumericalConstants class level) */ -class NumConstNode : public ExprNode -{ -private: - //! Id from numerical constants table - const int id; - virtual expr_t computeDerivative(int deriv_id); -public: - NumConstNode(DataTree &datatree_arg, int id_arg); - int - get_id() const - { - return id; - }; - virtual void prepareForDerivation(); - virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; - virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const bool isdynamic) const; - virtual bool containsExternalFunction() const; - virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; - virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; - virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); - virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; - virtual expr_t toStatic(DataTree &static_datatree) const; - virtual void computeXrefs(EquationInfo &ei) const; - virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; - virtual expr_t getChainRuleDerivative(int deriv_id, const map &recursive_variables); - virtual int maxEndoLead() const; - virtual int maxExoLead() const; - virtual int maxEndoLag() const; - virtual int maxExoLag() const; - virtual int maxLead() const; - virtual expr_t decreaseLeadsLags(int n) const; - virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; - virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; - virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; - virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; - virtual bool isNumConstNodeEqualTo(double value) const; - virtual bool containsEndogenous(void) const; - virtual bool containsExogenous() const; - virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; - virtual expr_t replaceTrendVar() const; - virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; - virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; - virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; - virtual bool isInStaticForm() const; - virtual expr_t substituteStaticAuxiliaryVariable() const; -}; - -//! Symbol or variable node -class VariableNode : public ExprNode -{ - friend class UnaryOpNode; -private: - //! Id from the symbol table - const int symb_id; - const SymbolType type; - //! A positive value is a lead, a negative is a lag - const int lag; - virtual expr_t computeDerivative(int deriv_id); -public: - VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg); - virtual void prepareForDerivation(); - virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; - virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const bool isdynamic) const; - virtual bool containsExternalFunction() const; - virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; - virtual void computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const; - virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; - virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); - virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; - virtual expr_t toStatic(DataTree &static_datatree) const; - virtual void computeXrefs(EquationInfo &ei) const; - SymbolType - get_type() const - { - return type; - }; - int - get_symb_id() const - { - return symb_id; - }; - int - get_lag() const - { - return lag; - }; - virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; - virtual expr_t getChainRuleDerivative(int deriv_id, const map &recursive_variables); - virtual int maxEndoLead() const; - virtual int maxExoLead() const; - virtual int maxEndoLag() const; - virtual int maxExoLag() const; - virtual int maxLead() const; - virtual expr_t decreaseLeadsLags(int n) const; - virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; - virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; - virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; - virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; - virtual bool isNumConstNodeEqualTo(double value) const; - virtual bool containsEndogenous(void) const; - virtual bool containsExogenous() const; - virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; - virtual expr_t replaceTrendVar() const; - virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; - virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; - virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; - virtual bool isInStaticForm() const; - //! Substitute auxiliary variables by their expression in static model - virtual expr_t substituteStaticAuxiliaryVariable() const; -}; - -//! Unary operator node -class UnaryOpNode : public ExprNode -{ -private: - const expr_t arg; - //! Stores the information set. Only used for expectation operator - const int expectation_information_set; - //! Only used for oSteadyStateParamDeriv and oSteadyStateParam2ndDeriv - const int param1_symb_id, param2_symb_id; - const UnaryOpcode op_code; - virtual expr_t computeDerivative(int deriv_id); - virtual int cost(int cost, bool is_matlab) const; - virtual int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const; - virtual int cost(const map &temp_terms_map, bool is_matlab) const; - //! Returns the derivative of this node if darg is the derivative of the argument - expr_t composeDerivatives(expr_t darg, int deriv_id); -public: - UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg); - virtual void prepareForDerivation(); - virtual void computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const; - virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; - virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const bool isdynamic) const; - virtual bool containsExternalFunction() const; - virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const; - virtual void writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const; - virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const; - virtual void computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const; - virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; - virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; - static double eval_opcode(UnaryOpcode op_code, double v) throw (EvalException, EvalExternalFunctionException); - virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); - virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; - //! Returns operand - expr_t - get_arg() const - { - return (arg); - }; - //! Returns op code - UnaryOpcode - get_op_code() const - { - return (op_code); - }; - virtual expr_t toStatic(DataTree &static_datatree) const; - virtual void computeXrefs(EquationInfo &ei) const; - virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; - virtual expr_t getChainRuleDerivative(int deriv_id, const map &recursive_variables); - virtual int maxEndoLead() const; - virtual int maxExoLead() const; - virtual int maxEndoLag() const; - virtual int maxExoLag() const; - virtual int maxLead() const; - virtual expr_t decreaseLeadsLags(int n) const; - virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; - //! Creates another UnaryOpNode with the same opcode, but with a possibly different datatree and argument - expr_t buildSimilarUnaryOpNode(expr_t alt_arg, DataTree &alt_datatree) const; - virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; - virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; - virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; - virtual bool isNumConstNodeEqualTo(double value) const; - virtual bool containsEndogenous(void) const; - virtual bool containsExogenous() const; - virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; - virtual expr_t replaceTrendVar() const; - virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; - virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; - virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; - virtual bool isInStaticForm() const; - //! Substitute auxiliary variables by their expression in static model - virtual expr_t substituteStaticAuxiliaryVariable() const; -}; - -//! Binary operator node -class BinaryOpNode : public ExprNode -{ -private: - const expr_t arg1, arg2; - const BinaryOpcode op_code; - virtual expr_t computeDerivative(int deriv_id); - virtual int cost(int cost, bool is_matlab) const; - virtual int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const; - virtual int cost(const map &temp_terms_map, bool is_matlab) const; - //! Returns the derivative of this node if darg1 and darg2 are the derivatives of the arguments - expr_t composeDerivatives(expr_t darg1, expr_t darg2); - const int powerDerivOrder; -public: - BinaryOpNode(DataTree &datatree_arg, const expr_t arg1_arg, - BinaryOpcode op_code_arg, const expr_t arg2_arg); - BinaryOpNode(DataTree &datatree_arg, const expr_t arg1_arg, - BinaryOpcode op_code_arg, const expr_t arg2_arg, int powerDerivOrder); - virtual void prepareForDerivation(); - virtual int precedenceJson(const temporary_terms_t &temporary_terms) const; - virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const; - virtual void computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const; - virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; - virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const bool isdynamic) const; - virtual bool containsExternalFunction() const; - virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const; - virtual void writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const; - virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const; - virtual void computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const; - virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; - virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; - static double eval_opcode(double v1, BinaryOpcode op_code, double v2, int derivOrder) throw (EvalException, EvalExternalFunctionException); - virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); - virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; - virtual expr_t Compute_RHS(expr_t arg1, expr_t arg2, int op, int op_type) const; - //! Returns first operand - expr_t - get_arg1() const - { - return (arg1); - }; - //! Returns second operand - expr_t - get_arg2() const - { - return (arg2); - }; - //! Returns op code - BinaryOpcode - get_op_code() const - { - return (op_code); - }; - int - get_power_deriv_order() const - { - return powerDerivOrder; - } - virtual expr_t toStatic(DataTree &static_datatree) const; - virtual void computeXrefs(EquationInfo &ei) const; - virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; - virtual expr_t getChainRuleDerivative(int deriv_id, const map &recursive_variables); - virtual int maxEndoLead() const; - virtual int maxExoLead() const; - virtual int maxEndoLag() const; - virtual int maxExoLag() const; - virtual int maxLead() const; - virtual expr_t decreaseLeadsLags(int n) const; - virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; - //! Creates another BinaryOpNode with the same opcode, but with a possibly different datatree and arguments - expr_t buildSimilarBinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, DataTree &alt_datatree) const; - virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; - virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; - virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; - virtual bool isNumConstNodeEqualTo(double value) const; - virtual bool containsEndogenous(void) const; - virtual bool containsExogenous() const; - virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; - virtual expr_t replaceTrendVar() const; - virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; - virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; - virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; - //! Function to write out the oPowerNode in expr_t terms as opposed to writing out the function itself - expr_t unpackPowerDeriv() const; - //! Returns MULT_i*(lhs-rhs) = 0, creating multiplier MULT_i - expr_t addMultipliersToConstraints(int i); - //! Returns the non-zero hand-side of an equation (that must have a hand side equal to zero) - expr_t getNonZeroPartofEquation() const; - virtual bool isInStaticForm() const; - //! Substitute auxiliary variables by their expression in static model - virtual expr_t substituteStaticAuxiliaryVariable() const; - //! Substitute auxiliary variables by their expression in static model auxiliary variable definition - virtual expr_t substituteStaticAuxiliaryDefinition() const; -}; - -//! Trinary operator node -class TrinaryOpNode : public ExprNode -{ - friend class ModelTree; -private: - const expr_t arg1, arg2, arg3; - const TrinaryOpcode op_code; - virtual expr_t computeDerivative(int deriv_id); - virtual int cost(int cost, bool is_matlab) const; - virtual int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const; - virtual int cost(const map &temp_terms_map, bool is_matlab) const; - //! Returns the derivative of this node if darg1, darg2 and darg3 are the derivatives of the arguments - expr_t composeDerivatives(expr_t darg1, expr_t darg2, expr_t darg3); -public: - TrinaryOpNode(DataTree &datatree_arg, const expr_t arg1_arg, - TrinaryOpcode op_code_arg, const expr_t arg2_arg, const expr_t arg3_arg); - virtual void prepareForDerivation(); - virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const; - virtual void computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const; - virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; - virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const bool isdynamic) const; - virtual bool containsExternalFunction() const; - virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const; - virtual void writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const; - virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const; - virtual void computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const; - virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; - virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; - static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException, EvalExternalFunctionException); - virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); - virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; - virtual expr_t toStatic(DataTree &static_datatree) const; - virtual void computeXrefs(EquationInfo &ei) const; - virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; - virtual expr_t getChainRuleDerivative(int deriv_id, const map &recursive_variables); - virtual int maxEndoLead() const; - virtual int maxExoLead() const; - virtual int maxEndoLag() const; - virtual int maxExoLag() const; - virtual int maxLead() const; - virtual expr_t decreaseLeadsLags(int n) const; - virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; - //! Creates another TrinaryOpNode with the same opcode, but with a possibly different datatree and arguments - expr_t buildSimilarTrinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, expr_t alt_arg3, DataTree &alt_datatree) const; - virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; - virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; - virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; - virtual bool isNumConstNodeEqualTo(double value) const; - virtual bool containsEndogenous(void) const; - virtual bool containsExogenous() const; - virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; - virtual expr_t replaceTrendVar() const; - virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; - virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; - virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; - virtual bool isInStaticForm() const; - //! Substitute auxiliary variables by their expression in static model - virtual expr_t substituteStaticAuxiliaryVariable() const; -}; - -//! External function node -class AbstractExternalFunctionNode : public ExprNode -{ -private: - virtual expr_t computeDerivative(int deriv_id); - virtual expr_t composeDerivatives(const vector &dargs) = 0; -protected: - //! Thrown when trying to access an unknown entry in external_function_node_map - class UnknownFunctionNameAndArgs - { - }; - const int symb_id; - const vector arguments; - //! Returns true if the given external function has been written as a temporary term - bool alreadyWrittenAsTefTerm(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const; - //! Returns the index in the tef_terms map of this external function - int getIndxInTefTerms(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const throw (UnknownFunctionNameAndArgs); - //! Helper function to write output arguments of any given external function - void writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; - void writeJsonExternalFunctionArguments(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const bool isdynamic) const; -public: - AbstractExternalFunctionNode(DataTree &datatree_arg, int symb_id_arg, - const vector &arguments_arg); - virtual void prepareForDerivation(); - virtual void computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const = 0; - virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0; - virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const bool isdynamic = true) const = 0; - virtual bool containsExternalFunction() const; - virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const = 0; - virtual void writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic = true) const = 0; - virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const = 0; - virtual void computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const = 0; - virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; - virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; - virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); - unsigned int compileExternalFunctionArguments(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const; - - virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const = 0; - virtual expr_t toStatic(DataTree &static_datatree) const = 0; - virtual void computeXrefs(EquationInfo &ei) const = 0; - virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; - virtual expr_t getChainRuleDerivative(int deriv_id, const map &recursive_variables); - virtual int maxEndoLead() const; - virtual int maxExoLead() const; - virtual int maxEndoLag() const; - virtual int maxExoLag() const; - virtual int maxLead() const; - virtual expr_t decreaseLeadsLags(int n) const; - virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; - virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; - virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; - virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; - virtual expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const = 0; - virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; - virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; - virtual bool isNumConstNodeEqualTo(double value) const; - virtual bool containsEndogenous(void) const; - virtual bool containsExogenous() const; - virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; - virtual void writePrhs(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const string &ending) const; - virtual expr_t replaceTrendVar() const; - virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; - virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const = 0; - virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; - virtual bool isInStaticForm() const; - //! Substitute auxiliary variables by their expression in static model - virtual expr_t substituteStaticAuxiliaryVariable() const; -}; - -class ExternalFunctionNode : public AbstractExternalFunctionNode -{ -private: - virtual expr_t composeDerivatives(const vector &dargs); -public: - ExternalFunctionNode(DataTree &datatree_arg, int symb_id_arg, - const vector &arguments_arg); - virtual void computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const; - virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; - virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const bool isdynamic) const; - virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const; - virtual void writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const; - virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const; - virtual void computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const; - virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; - virtual expr_t toStatic(DataTree &static_datatree) const; - virtual void computeXrefs(EquationInfo &ei) const; - virtual expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const; - virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; -}; - -class FirstDerivExternalFunctionNode : public AbstractExternalFunctionNode -{ -private: - const int inputIndex; - virtual expr_t composeDerivatives(const vector &dargs); -public: - FirstDerivExternalFunctionNode(DataTree &datatree_arg, - int top_level_symb_id_arg, - const vector &arguments_arg, - int inputIndex_arg); - virtual void computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const; - virtual void computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const; - virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; - virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const bool isdynamic) const; - virtual void compile(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const; - virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const; - virtual void writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const; - virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const; - virtual expr_t toStatic(DataTree &static_datatree) const; - virtual void computeXrefs(EquationInfo &ei) const; - virtual expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const; - virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; -}; - -class SecondDerivExternalFunctionNode : public AbstractExternalFunctionNode -{ -private: - const int inputIndex1; - const int inputIndex2; - virtual expr_t composeDerivatives(const vector &dargs); -public: - SecondDerivExternalFunctionNode(DataTree &datatree_arg, - int top_level_symb_id_arg, - const vector &arguments_arg, - int inputIndex1_arg, - int inputIndex2_arg); - virtual void computeTemporaryTerms(map > &reference_count, - map &temp_terms_map, - bool is_matlab, NodeTreeReference tr) const; - virtual void computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const; - virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; - virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const bool isdynamic) const; - virtual void compile(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const; - virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const; - virtual void writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - const bool isdynamic) const; - virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const; - virtual expr_t toStatic(DataTree &static_datatree) const; - virtual void computeXrefs(EquationInfo &ei) const; - virtual expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const; - virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; -}; - -#endif diff --git a/preprocessor/ExtendedPreprocessorTypes.hh b/preprocessor/ExtendedPreprocessorTypes.hh deleted file mode 100644 index e40c73eeb..000000000 --- a/preprocessor/ExtendedPreprocessorTypes.hh +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2014-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 . - */ - -#ifndef _EXTENDED_PREPROCESSOR_TYPES_HH -#define _EXTENDED_PREPROCESSOR_TYPES_HH - -enum FileOutputType - { - none, // outputs files for Matlab/Octave processing - dynamic, // outputs _dynamic.* and related files - first, // outputs _first_derivatives.* and related files - second, // outputs _first_derivatives.*, _second_derivatives.* and related files - third, // outputs _first_derivatives.*, _second_derivatives.*, _third_derivatives.* and related files - }; - -enum LanguageOutputType - { - matlab, // outputs files for Matlab/Octave processing - c, // outputs files for C - cpp, // outputs files for C++ - cuda, // outputs files for CUDA (not yet implemented) - julia, // outputs files for Julia - python, // outputs files for Python (not yet implemented) (not yet implemented) - }; - -enum JsonFileOutputType - { - file, // output JSON files to file - standardout, // output JSON files to stdout - }; - -enum JsonOutputPointType - { - nojson, // don't output JSON - parsing, // output JSON after the parsing step - checkpass, // output JSON after the check pass - transformpass, // output JSON after the transform pass - computingpass // output JSON after the computing pass - }; -#endif diff --git a/preprocessor/ExternalFunctionsTable.cc b/preprocessor/ExternalFunctionsTable.cc deleted file mode 100644 index eb4ab00cb..000000000 --- a/preprocessor/ExternalFunctionsTable.cc +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2010-2015 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 . - */ - -#include -#include -#include -#include -#include - -#include "ExternalFunctionsTable.hh" -#include "SymbolTable.hh" - -ExternalFunctionsTable::ExternalFunctionsTable() -{ -} - -void -ExternalFunctionsTable::addExternalFunction(int symb_id, const external_function_options &external_function_options_arg, bool track_nargs) -{ - assert(symb_id >= 0); - assert(external_function_options_arg.nargs > 0); - - // Change options to be saved so the table is consistent - external_function_options external_function_options_chng = external_function_options_arg; - if (external_function_options_arg.firstDerivSymbID == eExtFunSetButNoNameProvided) - external_function_options_chng.firstDerivSymbID = symb_id; - - if (external_function_options_arg.secondDerivSymbID == eExtFunSetButNoNameProvided) - external_function_options_chng.secondDerivSymbID = symb_id; - - if (!track_nargs) - external_function_options_chng.nargs = eExtFunNotSet; - - // Ensure 1st & 2nd deriv option consistency - if (external_function_options_chng.secondDerivSymbID == symb_id - && external_function_options_chng.firstDerivSymbID != symb_id) - { - cerr << "ERROR: If the second derivative is provided by the top-level function " - << "the first derivative must also be provided by the same function." << endl; - exit(EXIT_FAILURE); - } - - if ((external_function_options_chng.secondDerivSymbID != symb_id - && external_function_options_chng.firstDerivSymbID == symb_id) - && external_function_options_chng.secondDerivSymbID != eExtFunNotSet) - { - cerr << "ERROR: If the first derivative is provided by the top-level function, the " - << "second derivative cannot be provided by any other external function." << endl; - exit(EXIT_FAILURE); - } - - if (external_function_options_chng.secondDerivSymbID != eExtFunNotSet - && external_function_options_chng.firstDerivSymbID == eExtFunNotSet) - { - cerr << "ERROR: If the second derivative is provided, the first derivative must also be provided." << endl; - exit(EXIT_FAILURE); - } - - if (external_function_options_chng.secondDerivSymbID == external_function_options_chng.firstDerivSymbID - && external_function_options_chng.firstDerivSymbID != symb_id - && external_function_options_chng.firstDerivSymbID != eExtFunNotSet) - { - cerr << "ERROR: If the Jacobian and Hessian are provided by the same function, that " - << "function must be the top-level function." << endl; - exit(EXIT_FAILURE); - } - - // Ensure that if we're overwriting something, we mean to do it - if (exists(symb_id)) - { - bool ok_to_overwrite = false; - if (getNargs(symb_id) == eExtFunNotSet) // implies that the information stored about this function is not important - ok_to_overwrite = true; - - if (!ok_to_overwrite) // prevents multiple non-compatible calls to external_function(name=funcname) - { // e.g. e_f(name=a,nargs=1,fd,sd) and e_f(name=a,nargs=2,fd=b,sd=c) should cause an error - if (external_function_options_chng.nargs != getNargs(symb_id)) - { - cerr << "ERROR: The number of arguments passed to the external_function() statement do not " - << "match the number of arguments passed to a previous call or declaration of the top-level function."<< endl; - exit(EXIT_FAILURE); - } - - if (external_function_options_chng.firstDerivSymbID != getFirstDerivSymbID(symb_id)) - { - cerr << "ERROR: The first derivative function passed to the external_function() statement does not " - << "match the first derivative function passed to a previous call or declaration of the top-level function."<< endl; - exit(EXIT_FAILURE); - } - - if (external_function_options_chng.secondDerivSymbID != getSecondDerivSymbID(symb_id)) - { - cerr << "ERROR: The second derivative function passed to the external_function() statement does not " - << "match the second derivative function passed to a previous call or declaration of the top-level function."<< endl; - exit(EXIT_FAILURE); - } - } - } - - externalFunctionTable[symb_id] = external_function_options_chng; -} diff --git a/preprocessor/ExternalFunctionsTable.hh b/preprocessor/ExternalFunctionsTable.hh deleted file mode 100644 index 42d18391e..000000000 --- a/preprocessor/ExternalFunctionsTable.hh +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2010-2015 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 . - */ - -#ifndef _EXTERNALFUNCTIONSTABLE_HH -#define _EXTERNALFUNCTIONSTABLE_HH - -using namespace std; - -#include -#include -#include -#include - -enum ExternalFunctionSetOrNot - { - eExtFunSetButNoNameProvided = -2, //! Signifies that the derivative is obtained from the top-level function - eExtFunNotSet = -1, //! Signifies that no external function exists that calculates the derivative - eExtFunSetDefaultNargs = 1 //! This is the default number of arguments when nargs is not specified - }; - -//! Handles external functions -class ExternalFunctionsTable -{ -public: - //! Thrown when trying to access an unknown symbol (by id) - class UnknownExternalFunctionSymbolIDException - { - public: - //! Symbol ID - int id; - UnknownExternalFunctionSymbolIDException(int id_arg) : id(id_arg) - { - } - }; - - /* For all arguments, -2 means not set - * For firstDerivSymbID and secondDerivSymbID, -1 means that the derivatives are - * provided in the main function given in the by the "name" option to the - * external_function() statement. - */ - struct external_function_options - { - int nargs, firstDerivSymbID, secondDerivSymbID; - }; - typedef map external_function_table_type; -private: - //! Map containing options provided to external_functions() - external_function_table_type externalFunctionTable; -public: - ExternalFunctionsTable(); - //! Adds an external function to the table as well as its derivative functions - void addExternalFunction(int symb_id, const external_function_options &external_function_options_arg, bool track_nargs); - //! See if the function exists in the External Functions Table - inline bool exists(int symb_id) const; - //! Get the number of arguments for a given external function - inline int getNargs(int symb_id) const throw (UnknownExternalFunctionSymbolIDException); - //! Get the symbol_id of the first derivative function - inline int getFirstDerivSymbID(int symb_id) const throw (UnknownExternalFunctionSymbolIDException); - //! Get the symbol_id of the second derivative function - inline int getSecondDerivSymbID(int symb_id) const throw (UnknownExternalFunctionSymbolIDException); - //! Returns the total number of unique external functions declared or used in the .mod file - inline int get_total_number_of_unique_model_block_external_functions() const; -}; - -inline bool -ExternalFunctionsTable::exists(int symb_id) const -{ - external_function_table_type::const_iterator iter = externalFunctionTable.find(symb_id); - return (iter != externalFunctionTable.end()); -} - -inline int -ExternalFunctionsTable::getNargs(int symb_id) const throw (UnknownExternalFunctionSymbolIDException) -{ - if (exists(symb_id)) - return externalFunctionTable.find(symb_id)->second.nargs; - else - throw UnknownExternalFunctionSymbolIDException(symb_id); -} - -inline int -ExternalFunctionsTable::getFirstDerivSymbID(int symb_id) const throw (UnknownExternalFunctionSymbolIDException) -{ - if (exists(symb_id)) - return externalFunctionTable.find(symb_id)->second.firstDerivSymbID; - else - throw UnknownExternalFunctionSymbolIDException(symb_id); -} - -inline int -ExternalFunctionsTable::getSecondDerivSymbID(int symb_id) const throw (UnknownExternalFunctionSymbolIDException) -{ - if (exists(symb_id)) - return externalFunctionTable.find(symb_id)->second.secondDerivSymbID; - else - throw UnknownExternalFunctionSymbolIDException(symb_id); -} - -inline int -ExternalFunctionsTable::get_total_number_of_unique_model_block_external_functions() const -{ - int number_of_unique_model_block_external_functions = 0; - for (external_function_table_type::const_iterator it = externalFunctionTable.begin(); - it != externalFunctionTable.end(); it++) - if (it->second.nargs > 0) - number_of_unique_model_block_external_functions++; - - return number_of_unique_model_block_external_functions; -} - -#endif diff --git a/preprocessor/Makefile.am b/preprocessor/Makefile.am deleted file mode 100644 index 5a8ac507e..000000000 --- a/preprocessor/Makefile.am +++ /dev/null @@ -1,95 +0,0 @@ -SUBDIRS = macro - -BUILT_SOURCES = DynareBison.hh stack.hh position.hh location.hh DynareBison.cc DynareFlex.cc FlexLexer.h - -matlabdir = $(pkglibdir)/matlab - -matlab_PROGRAMS = dynare_m - -# We don't put BUILT_SOURCES in dynare_m_SOURCES, otherwise DynareBison.o and DynareFlex.o will be linked two times (Automake translates DynareFlex.ll and DynareBison.yy into their respective .o); so BUILT_SOURCES is in EXTRA_DIST -dynare_m_SOURCES = \ - DynareFlex.ll \ - DynareBison.yy \ - ComputingTasks.cc \ - ComputingTasks.hh \ - ModelTree.cc \ - ModelTree.hh \ - StaticModel.cc \ - StaticModel.hh \ - DynamicModel.cc \ - DynamicModel.hh \ - NumericalConstants.cc \ - NumericalConstants.hh \ - NumericalInitialization.cc \ - NumericalInitialization.hh \ - Shocks.cc \ - Shocks.hh \ - SigmaeInitialization.cc \ - SigmaeInitialization.hh \ - SymbolTable.cc \ - SymbolTable.hh \ - SymbolList.cc \ - SymbolList.hh \ - ParsingDriver.cc \ - ParsingDriver.hh \ - DataTree.cc \ - DataTree.hh \ - ModFile.cc \ - ModFile.hh \ - ConfigFile.cc \ - ConfigFile.hh \ - Statement.cc \ - Statement.hh \ - ExprNode.cc \ - ExprNode.hh \ - MinimumFeedbackSet.cc \ - MinimumFeedbackSet.hh \ - DynareMain.cc \ - DynareMain1.cc \ - DynareMain2.cc \ - CodeInterpreter.hh \ - ExternalFunctionsTable.cc \ - ExternalFunctionsTable.hh \ - SteadyStateModel.hh \ - SteadyStateModel.cc \ - WarningConsolidation.hh \ - WarningConsolidation.cc \ - ExtendedPreprocessorTypes.hh - - -# The -I. is for -dynare_m_CPPFLAGS = $(BOOST_CPPFLAGS) -I. -dynare_m_LDFLAGS = $(BOOST_LDFLAGS) -dynare_m_LDADD = macro/libmacro.a - -DynareFlex.cc FlexLexer.h: DynareFlex.ll - $(LEX) -o DynareFlex.cc DynareFlex.ll - cp $(LEXINC)/FlexLexer.h . || test -f ./FlexLexer.h - -DynareBison.cc DynareBison.hh location.hh stack.hh position.hh: DynareBison.yy - $(YACC) -o DynareBison.cc DynareBison.yy - -all-local: $(PROGRAMS) - if [ -z "`file $(PROGRAMS) | grep x86.64`" ]; then \ - ARCH="32"; \ - else \ - ARCH="64"; \ - fi; \ - mkdir -p ../matlab/preprocessor$$ARCH ; \ - cd ../matlab/preprocessor$$ARCH && $(LN_S) -f $(abs_srcdir)/$(PROGRAMS) $(PROGRAMS) ; \ - mkdir -p ../../julia/preprocessor$$ARCH ; \ - cd ../../julia/preprocessor$$ARCH && $(LN_S) -f $(abs_srcdir)/$(PROGRAMS) $(PROGRAMS) - -if HAVE_DOXYGEN -html-local: - $(DOXYGEN) -endif - -clean-local: - rm -rf ../matlab/preprocessor* ../julia/preprocessor* - rm -rf doc/html/ - -EXTRA_DIST = $(BUILT_SOURCES) Doxyfile - -install-exec-local: - $(MKDIR_P) $(DESTDIR)$(pkglibdir)/matlab diff --git a/preprocessor/MinimumFeedbackSet.cc b/preprocessor/MinimumFeedbackSet.cc deleted file mode 100644 index d91391c58..000000000 --- a/preprocessor/MinimumFeedbackSet.cc +++ /dev/null @@ -1,457 +0,0 @@ -/* - * Copyright (C) 2009-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 . - */ - -#include - -#include "MinimumFeedbackSet.hh" - -namespace MFS -{ - void - Suppress(AdjacencyList_t::vertex_descriptor vertex_to_eliminate, AdjacencyList_t &G) - { - clear_vertex(vertex_to_eliminate, G); - remove_vertex(vertex_to_eliminate, G); - } - - void - Suppress(int vertex_num, AdjacencyList_t &G) - { - Suppress(vertex(vertex_num, G), G); - } - - void - Eliminate(AdjacencyList_t::vertex_descriptor vertex_to_eliminate, AdjacencyList_t &G) - { - if (in_degree(vertex_to_eliminate, G) > 0 && out_degree(vertex_to_eliminate, G) > 0) - { - AdjacencyList_t::in_edge_iterator it_in, in_end; - AdjacencyList_t::out_edge_iterator it_out, out_end; - for (tie(it_in, in_end) = in_edges(vertex_to_eliminate, G); it_in != in_end; ++it_in) - for (tie(it_out, out_end) = out_edges(vertex_to_eliminate, G); it_out != out_end; ++it_out) - { - AdjacencyList_t::edge_descriptor ed; - bool exist; - tie(ed, exist) = edge(source(*it_in, G), target(*it_out, G), G); - if (!exist) - add_edge(source(*it_in, G), target(*it_out, G), G); - } - } - Suppress(vertex_to_eliminate, G); - } - - bool - has_cycle_dfs(AdjacencyList_t &g, AdjacencyList_t::vertex_descriptor u, color_t &color, vector &circuit_stack) - { - property_map::type v_index = get(vertex_index, g); - color[u] = gray_color; - graph_traits::out_edge_iterator vi, vi_end; - for (tie(vi, vi_end) = out_edges(u, g); vi != vi_end; ++vi) - if (color[target(*vi, g)] == white_color && has_cycle_dfs(g, target(*vi, g), color, circuit_stack)) - { - // cycle detected, return immediately - circuit_stack.push_back(v_index[target(*vi, g)]); - return true; - } - else if (color[target(*vi, g)] == gray_color) - { - // *vi is an ancestor! - circuit_stack.push_back(v_index[target(*vi, g)]); - return true; - } - color[u] = black_color; - return false; - } - - bool - has_cycle(vector &circuit_stack, AdjacencyList_t &g) - { - // Initialize color map to white - color_t color; - graph_traits::vertex_iterator vi, vi_end; - for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - color[*vi] = white_color; - - // Perform depth-first search - for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - if (color[*vi] == white_color && has_cycle_dfs(g, *vi, color, circuit_stack)) - return true; - - return false; - } - - void - Print(AdjacencyList_t &G) - { - AdjacencyList_t::vertex_iterator it, it_end; - property_map::type v_index = get(vertex_index, G); - cout << "Graph\n"; - cout << "-----\n"; - for (tie(it, it_end) = vertices(G); it != it_end; ++it) - { - cout << "vertex[" << v_index[*it] + 1 << "] <-"; - AdjacencyList_t::in_edge_iterator it_in, in_end; - for (tie(it_in, in_end) = in_edges(*it, G); it_in != in_end; ++it_in) - cout << v_index[source(*it_in, G)] + 1 << " "; - cout << "\n ->"; - AdjacencyList_t::out_edge_iterator it_out, out_end; - for (tie(it_out, out_end) = out_edges(*it, G); it_out != out_end; ++it_out) - cout << v_index[target(*it_out, G)] + 1 << " "; - cout << "\n"; - } - } - - AdjacencyList_t - AM_2_AdjacencyList(bool *AM, unsigned int n) - { - AdjacencyList_t G(n); - property_map::type v_index = get(vertex_index, G); - property_map::type v_index1 = get(vertex_index1, G); - for (unsigned int i = 0; i < n; i++) - { - put(v_index, vertex(i, G), i); - put(v_index1, vertex(i, G), i); - } - for (unsigned int i = 0; i < n; i++) - for (unsigned int j = 0; j < n; j++) - if (AM[i*n+j]) - add_edge(vertex(j, G), vertex(i, G), G); - return G; - } - - AdjacencyList_t - extract_subgraph(AdjacencyList_t &G1, set select_index) - { - unsigned int n = select_index.size(); - AdjacencyList_t G(n); - property_map::type v_index = get(vertex_index, G); - property_map::type v_index1 = get(vertex_index1, G); - property_map::type v1_index = get(vertex_index, G1); - map reverse_index; - set::iterator it; - unsigned int i; - for (it = select_index.begin(), i = 0; i < n; i++, ++it) - { - reverse_index[get(v1_index, vertex(*it, G1))] = i; - put(v_index, vertex(i, G), get(v1_index, vertex(*it, G1))); - put(v_index1, vertex(i, G), i); - } - for (it = select_index.begin(), i = 0; i < n; i++, ++it) - { - AdjacencyList_t::out_edge_iterator it_out, out_end; - AdjacencyList_t::vertex_descriptor vi = vertex(*it, G1); - for (tie(it_out, out_end) = out_edges(vi, G1); it_out != out_end; ++it_out) - { - int ii = v1_index[target(*it_out, G1)]; - if (select_index.find(ii) != select_index.end()) - add_edge(vertex(reverse_index[get(v1_index, source(*it_out, G1))], G), vertex(reverse_index[get(v1_index, target(*it_out, G1))], G), G); - } - } - return G; - } - - vector_vertex_descriptor_t - Collect_Doublet(AdjacencyList_t::vertex_descriptor vertex, AdjacencyList_t &G) - { - AdjacencyList_t::in_edge_iterator it_in, in_end; - AdjacencyList_t::out_edge_iterator it_out, out_end; - vector Doublet; - if (in_degree(vertex, G) > 0 && out_degree(vertex, G) > 0) - for (tie(it_in, in_end) = in_edges(vertex, G); it_in != in_end; ++it_in) - for (tie(it_out, out_end) = out_edges(vertex, G); it_out != out_end; ++it_out) - if (source(*it_in, G) == target(*it_out, G) && source(*it_in, G) != target(*it_in, G)) // not a loop - Doublet.push_back(source(*it_in, G)); - return Doublet; - } - - bool - Vertex_Belong_to_a_Clique(AdjacencyList_t::vertex_descriptor vertex, AdjacencyList_t &G) - { - vector liste; - bool agree = true; - AdjacencyList_t::in_edge_iterator it_in, in_end; - AdjacencyList_t::out_edge_iterator it_out, out_end; - tie(it_in, in_end) = in_edges(vertex, G); - tie(it_out, out_end) = out_edges(vertex, G); - while (it_in != in_end && it_out != out_end && agree) - { - agree = (source(*it_in, G) == target(*it_out, G) && source(*it_in, G) != target(*it_in, G)); //not a loop - liste.push_back(source(*it_in, G)); - ++it_in; - ++it_out; - } - if (agree) - { - if (it_in != in_end || it_out != out_end) - agree = false; - unsigned int i = 1; - while (i < liste.size() && agree) - { - unsigned int j = i + 1; - while (j < liste.size() && agree) - { - AdjacencyList_t::edge_descriptor ed; - bool exist1, exist2; - tie(ed, exist1) = edge(liste[i], liste[j], G); - tie(ed, exist2) = edge(liste[j], liste[i], G); - agree = (exist1 && exist2); - j++; - } - i++; - } - } - return agree; - } - - bool - Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(AdjacencyList_t &G) - { - bool something_has_been_done = false; - bool not_a_loop; - int i; - AdjacencyList_t::vertex_iterator it, it1, ita, it_end; - for (tie(it, it_end) = vertices(G), i = 0; it != it_end; ++it, i++) - { - int in_degree_n = in_degree(*it, G); - int out_degree_n = out_degree(*it, G); - if (in_degree_n <= 1 || out_degree_n <= 1) - { - not_a_loop = true; - if (in_degree_n >= 1 && out_degree_n >= 1) // Do not eliminate a vertex if it loops on itself! - { - AdjacencyList_t::in_edge_iterator it_in, in_end; - for (tie(it_in, in_end) = in_edges(*it, G); it_in != in_end; ++it_in) - if (source(*it_in, G) == target(*it_in, G)) - { -#ifdef verbose - cout << v_index[source(*it_in, G)] << " == " << v_index[target(*it_in, G)] << "\n"; -#endif - not_a_loop = false; - } - } - if (not_a_loop) - { -#ifdef verbose - property_map::type v_index = get(vertex_index, G); - cout << "->eliminate vertex[" << v_index[*it] + 1 << "]\n"; -#endif - Eliminate(*it, G); -#ifdef verbose - Print(G); -#endif - something_has_been_done = true; - if (i > 0) - it = ita; - else - { - tie(it, it_end) = vertices(G); - i--; - } - } - } - ita = it; - } - return something_has_been_done; - } - - bool - Elimination_of_Vertex_belonging_to_a_clique_Step(AdjacencyList_t &G) - { - AdjacencyList_t::vertex_iterator it, it1, ita, it_end; - bool something_has_been_done = false; - int i; - for (tie(it, it_end) = vertices(G), i = 0; it != it_end; ++it, i++) - { - if (Vertex_Belong_to_a_Clique(*it, G)) - { -#ifdef verbose - property_map::type v_index = get(vertex_index, G); - cout << "eliminate vertex[" << v_index[*it] + 1 << "]\n"; -#endif - Eliminate(*it, G); - something_has_been_done = true; - if (i > 0) - it = ita; - else - { - tie(it, it_end) = vertices(G); - i--; - } - } - ita = it; - } - return something_has_been_done; - } - - bool - Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(set &feed_back_vertices, AdjacencyList_t &G) - { - bool something_has_been_done = false; - AdjacencyList_t::vertex_iterator it, it_end, ita; - int i = 0; - for (tie(it, it_end) = vertices(G); it != it_end; ++it, i++) - { - AdjacencyList_t::edge_descriptor ed; - bool exist; - tie(ed, exist) = edge(*it, *it, G); - if (exist) - { -#ifdef verbose - property_map::type v_index = get(vertex_index, G); - cout << "store v[*it] = " << v_index[*it]+1 << "\n"; -#endif - property_map::type v_index1 = get(vertex_index1, G); - feed_back_vertices.insert(v_index1[*it]); - /*property_map::type v_index = get(vertex_index, G); - feed_back_vertices.insert(v_index[*it] );*/ - Suppress(*it, G); - something_has_been_done = true; - if (i > 0) - it = ita; - else - { - tie(it, it_end) = vertices(G); - i--; - } - } - ita = it; - } - return something_has_been_done; - } - - AdjacencyList_t - Minimal_set_of_feedback_vertex(set &feed_back_vertices, const AdjacencyList_t &G1) - { - bool something_has_been_done = true; - int cut_ = 0; - feed_back_vertices.clear(); - AdjacencyList_t G(G1); - while (num_vertices(G) > 0) - { - while (something_has_been_done && num_vertices(G) > 0) - { - //Rule 1 - something_has_been_done = (Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(G) /*or something_has_been_done*/); -#ifdef verbose - cout << "1 something_has_been_done=" << something_has_been_done << "\n"; -#endif - - //Rule 2 - something_has_been_done = (Elimination_of_Vertex_belonging_to_a_clique_Step(G) || something_has_been_done); -#ifdef verbose - cout << "2 something_has_been_done=" << something_has_been_done << "\n"; -#endif - - //Rule 3 - something_has_been_done = (Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(feed_back_vertices, G) || something_has_been_done); -#ifdef verbose - cout << "3 something_has_been_done=" << something_has_been_done << "\n"; -#endif - } - vector circuit; - if (!has_cycle(circuit, G)) - { -#ifdef verbose - cout << "has_cycle=false\n"; -#endif - //sort(feed_back_vertices.begin(), feed_back_vertices.end()); - return G; - } - if (num_vertices(G) > 0) - { - /*if nothing has been done in the five previous rule then cut the vertex with the maximum in_degree+out_degree*/ - unsigned int max_degree = 0, num = 0; - AdjacencyList_t::vertex_iterator it, it_end, max_degree_index; - for (tie(it, it_end) = vertices(G); it != it_end; ++it, num++) - { - if (in_degree(*it, G) + out_degree(*it, G) > max_degree) - { - max_degree = in_degree(*it, G) + out_degree(*it, G); - max_degree_index = it; - } - } - property_map::type v_index1 = get(vertex_index1, G); - feed_back_vertices.insert(v_index1[*max_degree_index]); - /*property_map::type v_index = get(vertex_index, G); - feed_back_vertices.insert(v_index[*max_degree_index]);*/ - //cout << "v_index1[*max_degree_index] = " << v_index1[*max_degree_index] << "\n"; - cut_++; -#ifdef verbose - property_map::type v_index = get(vertex_index, G); - cout << "--> cut vertex " << v_index[*max_degree_index] + 1 << "\n"; -#endif - Suppress(*max_degree_index, G); - something_has_been_done = true; - } - } -#ifdef verbose - cout << "cut_=" << cut_ << "\n"; -#endif - //sort(feed_back_vertices.begin(), feed_back_vertices.end()); - return G; - } - - struct rev - { - bool - operator()(const int a, const int b) const - { - return (a > b); - } - }; - - void - Reorder_the_recursive_variables(const AdjacencyList_t &G1, set &feedback_vertices, vector< int> &Reordered_Vertices) - { - AdjacencyList_t G(G1); - property_map::type v_index = get(vertex_index, G); - set::iterator its, ita; - set fv; - for (its = feedback_vertices.begin(); its != feedback_vertices.end(); its++) - fv.insert(*its); - int i = 0; - for (its = fv.begin(); its != fv.end(); ++its, i++) - Suppress(*its, G); - bool something_has_been_done = true; - while (something_has_been_done) - { - something_has_been_done = false; - AdjacencyList_t::vertex_iterator it, it_end, ita; - for (tie(it, it_end) = vertices(G), i = 0; it != it_end; ++it, i++) - { - if (in_degree(*it, G) == 0) - { - Reordered_Vertices.push_back(v_index[*it]); - Suppress(*it, G); - something_has_been_done = true; - if (i > 0) - it = ita; - else - { - tie(it, it_end) = vertices(G); - i--; - } - } - ita = it; - } - } - if (num_vertices(G)) - cout << "Error in the computation of feedback vertex set\n"; - } -} diff --git a/preprocessor/MinimumFeedbackSet.hh b/preprocessor/MinimumFeedbackSet.hh deleted file mode 100644 index 066df3a7f..000000000 --- a/preprocessor/MinimumFeedbackSet.hh +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2009-2010 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 . - */ - -#ifndef _MINIMUMFEEDBACKSET_HH -#define _MINIMUMFEEDBACKSET_HH - -#include -#include -#include - -using namespace std; -using namespace boost; - -namespace MFS -{ - typedef property > > > > VertexProperty_t; - typedef adjacency_list AdjacencyList_t; - typedef map::vertex_descriptor, default_color_type> color_t; - typedef vector vector_vertex_descriptor_t; - - //! Eliminate a vertex i - /*! For a vertex i replace all edges e_k_i and e_i_j by a shorcut e_k_j and then Suppress the vertex i*/ - void Eliminate(AdjacencyList_t::vertex_descriptor vertex_to_eliminate, AdjacencyList_t &G); - //! Collect all doublets (edges e_i_k such that there is an edge e_k_i with k!=i in the graph) - /*! Returns the vector of doublets */ - vector_vertex_descriptor_t Collect_Doublet(AdjacencyList_t::vertex_descriptor vertex, AdjacencyList_t &G); - //! Detect all the clique (all vertex in a clique are related to each other) in the graph - bool Vertex_Belong_to_a_Clique(AdjacencyList_t::vertex_descriptor vertex, AdjacencyList_t &G); - //! Graph reduction: eliminating purely intermediate variables or variables outside of any circuit - bool Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(AdjacencyList_t &G); - //! Graph reduction: elimination of a vertex inside a clique - bool Elimination_of_Vertex_belonging_to_a_clique_Step(AdjacencyList_t &G); - //! A vertex belong to the feedback vertex set if the vertex loops on itself. - /*! We have to suppress this vertex and store it into the feedback set.*/ - bool Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(set &feed_back_vertices, AdjacencyList_t &G1); - //! Print the Graph - void Print(AdjacencyList_t &G); - //! Create an adjacency graph from a Adjacency Matrix (an incidence Matrix without the diagonal terms) - AdjacencyList_t AM_2_AdjacencyList(bool *AMp, unsigned int n); - //! Extracts a subgraph - /*! - \param[in] G1 The original graph - \param[in] select_index The vertex indices to select - \return The subgraph - - The property vertex_index of the subgraph contains indices of the original - graph, the property vertex_index1 contains new contiguous indices specific - to the subgraph. - */ - AdjacencyList_t extract_subgraph(AdjacencyList_t &G1, set select_index); - //! Check if the graph contains any cycle (true if the model contains at least one cycle, false otherwise) - bool has_cycle(vector &circuit_stack, AdjacencyList_t &g); - bool has_cycle_dfs(AdjacencyList_t &g, AdjacencyList_t::vertex_descriptor u, color_t &color, vector &circuit_stack); - //! Return the feedback set - AdjacencyList_t Minimal_set_of_feedback_vertex(set &feed_back_vertices, const AdjacencyList_t &G); - //! Clear all in and out edges of vertex_to_eliminate and remove vertex_to_eliminate from the graph - void Suppress(AdjacencyList_t::vertex_descriptor vertex_to_eliminate, AdjacencyList_t &G); - void Suppress(int vertex_num, AdjacencyList_t &G); - //! Reorder the recursive variables - /*! They appear first in a quasi triangular form and they are followed by the feedback variables */ - void Reorder_the_recursive_variables(const AdjacencyList_t &G1, set &feedback_vertices, vector< int> &Reordered_Vertices); -}; - -#endif // _MINIMUMFEEDBACKSET_HH diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc deleted file mode 100644 index a103c5957..000000000 --- a/preprocessor/ModFile.cc +++ /dev/null @@ -1,1558 +0,0 @@ -/* - * Copyright (C) 2006-2018 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 . - */ - -#include -#include -#include -#include -#include -#ifndef _WIN32 -# include -#endif - -#include "ModFile.hh" -#include "ConfigFile.hh" -#include "ComputingTasks.hh" - -ModFile::ModFile(WarningConsolidation &warnings_arg) - : expressions_tree(symbol_table, num_constants, external_functions_table), - original_model(symbol_table, num_constants, external_functions_table), - dynamic_model(symbol_table, num_constants, external_functions_table), - trend_dynamic_model(symbol_table, num_constants, external_functions_table), - ramsey_FOC_equations_dynamic_model(symbol_table, num_constants, external_functions_table), - orig_ramsey_dynamic_model(symbol_table, num_constants, external_functions_table), - static_model(symbol_table, num_constants, external_functions_table), - steady_state_model(symbol_table, num_constants, external_functions_table, static_model), - linear(false), block(false), byte_code(false), use_dll(false), no_static(false), - differentiate_forward_vars(false), nonstationary_variables(false), - param_used_with_lead_lag(false), warnings(warnings_arg) -{ -} - -ModFile::~ModFile() -{ - for (vector::iterator it = statements.begin(); - it != statements.end(); it++) - delete (*it); -} - -void -ModFile::evalAllExpressions(bool warn_uninit, const bool nopreprocessoroutput) -{ - if (!nopreprocessoroutput) - cout << "Evaluating expressions..."; - - // Loop over all statements, and fill global eval context if relevant - for (vector::const_iterator it = statements.begin(); it != statements.end(); it++) - { - InitParamStatement *ips = dynamic_cast(*it); - if (ips) - ips->fillEvalContext(global_eval_context); - - InitOrEndValStatement *ies = dynamic_cast(*it); - if (ies) - ies->fillEvalContext(global_eval_context); - - LoadParamsAndSteadyStateStatement *lpass = dynamic_cast(*it); - if (lpass) - lpass->fillEvalContext(global_eval_context); - } - - // Evaluate model local variables - dynamic_model.fillEvalContext(global_eval_context); - - if (!nopreprocessoroutput) - cout << "done" << endl; - - // Check if some symbols are not initialized, and give them a zero value then - for (int id = 0; id <= symbol_table.maxID(); id++) - { - SymbolType type = symbol_table.getType(id); - if ((type == eEndogenous || type == eExogenous || type == eExogenousDet - || type == eParameter || type == eModelLocalVariable) - && global_eval_context.find(id) == global_eval_context.end()) - { - if (warn_uninit) - warnings << "WARNING: Can't find a numeric initial value for " - << symbol_table.getName(id) << ", using zero" << endl; - global_eval_context[id] = 0; - } - } -} - -void -ModFile::addStatement(Statement *st) -{ - statements.push_back(st); -} - -void -ModFile::addStatementAtFront(Statement *st) -{ - statements.insert(statements.begin(), st); -} - -void -ModFile::checkPass(bool nostrict, bool stochastic) -{ - for (vector::iterator it = statements.begin(); - it != statements.end(); it++) - (*it)->checkPass(mod_file_struct, warnings); - - // Check the steady state block - steady_state_model.checkPass(mod_file_struct, warnings); - - if (mod_file_struct.write_latex_steady_state_model_present && - !mod_file_struct.steady_state_model_present) - { - cerr << "ERROR: You cannot have a write_latex_steady_state_model statement without a steady_state_model block." << endl; - exit(EXIT_FAILURE); - } - - // If order option has not been set, default to 2 - if (!mod_file_struct.order_option) - mod_file_struct.order_option = 2; - - param_used_with_lead_lag = dynamic_model.ParamUsedWithLeadLag(); - if (param_used_with_lead_lag) - warnings << "WARNING: A parameter was used with a lead or a lag in the model block" << endl; - - bool stochastic_statement_present = mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present - || mod_file_struct.osr_present - || mod_file_struct.ramsey_policy_present - || mod_file_struct.discretionary_policy_present - || mod_file_struct.calib_smoother_present - || stochastic; - - // Allow empty model only when doing a standalone BVAR estimation - if (dynamic_model.equation_number() == 0 - && (mod_file_struct.check_present - || mod_file_struct.perfect_foresight_solver_present - || stochastic_statement_present)) - { - cerr << "ERROR: At least one model equation must be declared!" << endl; - exit(EXIT_FAILURE); - } - - if ((mod_file_struct.ramsey_model_present || mod_file_struct.ramsey_policy_present) - && mod_file_struct.discretionary_policy_present) - { - cerr << "ERROR: You cannot use the discretionary_policy command when you use either ramsey_model or ramsey_policy and vice versa" << endl; - exit(EXIT_FAILURE); - } - - if (((mod_file_struct.ramsey_model_present || mod_file_struct.discretionary_policy_present) - && !mod_file_struct.planner_objective_present) - || (!(mod_file_struct.ramsey_model_present || mod_file_struct.discretionary_policy_present) - && mod_file_struct.planner_objective_present)) - { - cerr << "ERROR: A planner_objective statement must be used with a ramsey_model, a ramsey_policy or a discretionary_policy statement and vice versa." << endl; - exit(EXIT_FAILURE); - } - - if ((mod_file_struct.osr_present && (!mod_file_struct.osr_params_present || !mod_file_struct.optim_weights_present)) - || ((!mod_file_struct.osr_present || !mod_file_struct.osr_params_present) && mod_file_struct.optim_weights_present) - || ((!mod_file_struct.osr_present || !mod_file_struct.optim_weights_present) && mod_file_struct.osr_params_present)) - { - cerr << "ERROR: The osr statement must be used with osr_params and optim_weights." << endl; - exit(EXIT_FAILURE); - } - - if (mod_file_struct.perfect_foresight_solver_present && stochastic_statement_present) - { - cerr << "ERROR: A .mod file cannot contain both one of {perfect_foresight_solver,simul} and one of {stoch_simul, estimation, osr, ramsey_policy, discretionary_policy}. This is not possible: one cannot mix perfect foresight context with stochastic context in the same file." << endl; - exit(EXIT_FAILURE); - } - - if (mod_file_struct.k_order_solver && byte_code) - { - cerr << "ERROR: 'k_order_solver' (which is implicit if order >= 3), is not yet compatible with 'bytecode'." << endl; - exit(EXIT_FAILURE); - } - - if (use_dll && (block || byte_code)) - { - cerr << "ERROR: In 'model' block, 'use_dll' option is not compatible with 'block' or 'bytecode'" << endl; - exit(EXIT_FAILURE); - } - - if (block || byte_code) - if (dynamic_model.isModelLocalVariableUsed()) - { - cerr << "ERROR: In 'model' block, 'block' or 'bytecode' options are not yet compatible with pound expressions" << endl; - exit(EXIT_FAILURE); - } - - if ((stochastic_statement_present || mod_file_struct.check_present || mod_file_struct.steady_present) && no_static) - { - cerr << "ERROR: no_static option is incompatible with stoch_simul, estimation, osr, ramsey_policy, discretionary_policy, steady and check commands" << endl; - exit(EXIT_FAILURE); - } - - if (mod_file_struct.dsge_var_estimated) - if (!mod_file_struct.dsge_prior_weight_in_estimated_params) - { - cerr << "ERROR: When estimating a DSGE-VAR model and estimating the weight of the prior, dsge_prior_weight must " - << "be referenced in the estimated_params block." << endl; - exit(EXIT_FAILURE); - } - - if (symbol_table.exists("dsge_prior_weight")) - { - if (symbol_table.getType("dsge_prior_weight") != eParameter) - { - cerr << "ERROR: dsge_prior_weight may only be used as a parameter." << endl; - exit(EXIT_FAILURE); - } - else - warnings << "WARNING: When estimating a DSGE-Var, declaring dsge_prior_weight as a " - << "parameter is deprecated. The preferred method is to do this via " - << "the dsge_var option in the estimation statement." << endl; - - if (mod_file_struct.dsge_var_estimated || !mod_file_struct.dsge_var_calibrated.empty()) - { - cerr << "ERROR: dsge_prior_weight can either be declared as a parameter (deprecated) or via the dsge_var option " - << "to the estimation statement (preferred), but not both." << endl; - exit(EXIT_FAILURE); - } - - if (!mod_file_struct.dsge_prior_weight_initialized && !mod_file_struct.dsge_prior_weight_in_estimated_params) - { - cerr << "ERROR: If dsge_prior_weight is declared as a parameter, it must either be initialized or placed in the " - << "estimated_params block." << endl; - exit(EXIT_FAILURE); - } - - if (mod_file_struct.dsge_prior_weight_initialized && mod_file_struct.dsge_prior_weight_in_estimated_params) - { - cerr << "ERROR: dsge_prior_weight cannot be both initialized and estimated." << endl; - exit(EXIT_FAILURE); - } - } - - if (mod_file_struct.dsge_prior_weight_in_estimated_params) - if (!mod_file_struct.dsge_var_estimated && !mod_file_struct.dsge_var_calibrated.empty()) - { - cerr << "ERROR: If dsge_prior_weight is in the estimated_params block, the prior weight cannot be calibrated " - << "via the dsge_var option in the estimation statement." << endl; - exit(EXIT_FAILURE); - } - else if (!mod_file_struct.dsge_var_estimated && !symbol_table.exists("dsge_prior_weight")) - { - cerr << "ERROR: If dsge_prior_weight is in the estimated_params block, it must either be declared as a parameter " - << "(deprecated) or the dsge_var option must be passed to the estimation statement (preferred)." << endl; - exit(EXIT_FAILURE); - } - - if (dynamic_model.staticOnlyEquationsNbr() != dynamic_model.dynamicOnlyEquationsNbr()) - { - cerr << "ERROR: the number of equations marked [static] must be equal to the number of equations marked [dynamic]" << endl; - exit(EXIT_FAILURE); - } - - if (dynamic_model.staticOnlyEquationsNbr() > 0 - && (mod_file_struct.ramsey_model_present || mod_file_struct.discretionary_policy_present)) - { - cerr << "ERROR: marking equations as [static] or [dynamic] is not possible with ramsey_model, ramsey_policy or discretionary_policy" << endl; - exit(EXIT_FAILURE); - } - - if (stochastic_statement_present - && (dynamic_model.isUnaryOpUsed(oSign) - || dynamic_model.isUnaryOpUsed(oAbs) - || dynamic_model.isBinaryOpUsed(oMax) - || dynamic_model.isBinaryOpUsed(oMin) - || dynamic_model.isBinaryOpUsed(oGreater) - || dynamic_model.isBinaryOpUsed(oLess) - || dynamic_model.isBinaryOpUsed(oGreaterEqual) - || dynamic_model.isBinaryOpUsed(oLessEqual) - || dynamic_model.isBinaryOpUsed(oEqualEqual) - || dynamic_model.isBinaryOpUsed(oDifferent))) - warnings << "WARNING: you are using a function (max, min, abs, sign) or an operator (<, >, <=, >=, ==, !=) which is unsuitable for a stochastic context; see the reference manual, section about \"Expressions\", for more details." << endl; - - if (linear - && (dynamic_model.isUnaryOpUsed(oSign) - || dynamic_model.isUnaryOpUsed(oAbs) - || dynamic_model.isBinaryOpUsed(oMax) - || dynamic_model.isBinaryOpUsed(oMin) - || dynamic_model.isBinaryOpUsed(oGreater) - || dynamic_model.isBinaryOpUsed(oLess) - || dynamic_model.isBinaryOpUsed(oGreaterEqual) - || dynamic_model.isBinaryOpUsed(oLessEqual) - || dynamic_model.isBinaryOpUsed(oEqualEqual) - || dynamic_model.isBinaryOpUsed(oDifferent))) - warnings << "WARNING: you have declared your model 'linear' but you are using a function (max, min, abs, sign) or an operator (<, >, <=, >=, ==, !=) which potentially makes it non-linear." << endl; - - // Test if some estimated parameters are used within the values of shocks - // statements (see issue #469) - set parameters_intersect; - set_intersection(mod_file_struct.parameters_within_shocks_values.begin(), - mod_file_struct.parameters_within_shocks_values.end(), - mod_file_struct.estimated_parameters.begin(), - mod_file_struct.estimated_parameters.end(), - inserter(parameters_intersect, parameters_intersect.begin())); - if (parameters_intersect.size() > 0) - { - cerr << "ERROR: some estimated parameters ("; - for (set::const_iterator it = parameters_intersect.begin(); - it != parameters_intersect.end();) - { - cerr << symbol_table.getName(*it); - if (++it != parameters_intersect.end()) - cerr << ", "; - } - cerr << ") also appear in the expressions defining the variance/covariance matrix of shocks; this is not allowed." << endl; - exit(EXIT_FAILURE); - } - - // Check if some exogenous is not used in the model block, Issue #841 - set unusedExo = dynamic_model.findUnusedExogenous(); - if (unusedExo.size() > 0) - { - ostringstream unused_exos; - for (set::iterator it = unusedExo.begin(); it != unusedExo.end(); it++) - unused_exos << symbol_table.getName(*it) << " "; - - if (nostrict) - warnings << "WARNING: " << unused_exos.str() - << "not used in model block, removed by nostrict command-line option" << endl; - else - { - cerr << "ERROR: " << unused_exos.str() << "not used in model block. To bypass this error, use the `nostrict` option. This may lead to crashes or unexpected behavior." << endl; - exit(EXIT_FAILURE); - } - } -} - -void -ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const bool nopreprocessoroutput) -{ - // Save the original model (must be done before any model transformations by preprocessor) - dynamic_model.setLeadsLagsOrig(); - dynamic_model.cloneDynamic(original_model); - - if (nostrict) - { - set unusedEndogs = dynamic_model.findUnusedEndogenous(); - for (set::iterator it = unusedEndogs.begin(); it != unusedEndogs.end(); it++) - { - symbol_table.changeType(*it, eUnusedEndogenous); - warnings << "WARNING: '" << symbol_table.getName(*it) - << "' not used in model block, removed by nostrict command-line option" << endl; - } - } - - if (symbol_table.predeterminedNbr() > 0) - dynamic_model.transformPredeterminedVariables(); - - // Create auxiliary vars for Expectation operator - dynamic_model.substituteExpectation(mod_file_struct.partial_information); - - if (nonstationary_variables) - { - dynamic_model.detrendEquations(); - dynamic_model.cloneDynamic(trend_dynamic_model); - dynamic_model.removeTrendVariableFromEquations(); - } - - mod_file_struct.orig_eq_nbr = dynamic_model.equation_number(); - if (mod_file_struct.ramsey_model_present) - { - StaticModel *planner_objective = NULL; - for (vector::iterator it = statements.begin(); it != statements.end(); it++) - { - PlannerObjectiveStatement *pos = dynamic_cast(*it); - if (pos != NULL) - planner_objective = pos->getPlannerObjective(); - } - assert(planner_objective != NULL); - - /* - clone the model then clone the new equations back to the original because - we have to call computeDerivIDs (in computeRamseyPolicyFOCs and computingPass) - */ - if (linear) - dynamic_model.cloneDynamic(orig_ramsey_dynamic_model); - dynamic_model.cloneDynamic(ramsey_FOC_equations_dynamic_model); - ramsey_FOC_equations_dynamic_model.computeRamseyPolicyFOCs(*planner_objective, nopreprocessoroutput); - ramsey_FOC_equations_dynamic_model.replaceMyEquations(dynamic_model); - mod_file_struct.ramsey_eq_nbr = dynamic_model.equation_number() - mod_file_struct.orig_eq_nbr; - } - - // Workaround for #1193 - if (!mod_file_struct.hist_vals_wrong_lag.empty()) - { - bool err = false; - for (map::const_iterator it = mod_file_struct.hist_vals_wrong_lag.begin(); - it != mod_file_struct.hist_vals_wrong_lag.end(); it++) - if (dynamic_model.minLagForSymbol(it->first) > it->second - 1) - { - cerr << "ERROR: histval: variable " << symbol_table.getName(it->first) - << " does not appear in the model with the lag " << it->second - 1 - << " (see the reference manual for the timing convention in 'histval')" << endl; - err = true; - } - if (err) - exit(EXIT_FAILURE); - } - - if (mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present - || mod_file_struct.osr_present - || mod_file_struct.ramsey_policy_present - || mod_file_struct.discretionary_policy_present - || mod_file_struct.calib_smoother_present - || stochastic ) - { - // In stochastic models, create auxiliary vars for leads and lags greater than 2, on both endos and exos - dynamic_model.substituteEndoLeadGreaterThanTwo(false); - dynamic_model.substituteExoLead(false); - dynamic_model.substituteEndoLagGreaterThanTwo(false); - dynamic_model.substituteExoLag(false); - } - else - { - // In deterministic models, create auxiliary vars for leads and lags endogenous greater than 2, only on endos (useless on exos) - dynamic_model.substituteEndoLeadGreaterThanTwo(true); - dynamic_model.substituteEndoLagGreaterThanTwo(true); - } - - if (differentiate_forward_vars) - dynamic_model.differentiateForwardVars(differentiate_forward_vars_subset); - - if (mod_file_struct.dsge_var_estimated || !mod_file_struct.dsge_var_calibrated.empty()) - try - { - int sid = symbol_table.addSymbol("dsge_prior_weight", eParameter); - if (!mod_file_struct.dsge_var_calibrated.empty()) - addStatementAtFront(new InitParamStatement(sid, - expressions_tree.AddNonNegativeConstant(mod_file_struct.dsge_var_calibrated), - symbol_table)); - } - catch (SymbolTable::AlreadyDeclaredException &e) - { - cerr << "ERROR: dsge_prior_weight should not be declared as a model variable / parameter " - << "when the dsge_var option is passed to the estimation statement." << endl; - exit(EXIT_FAILURE); - } - - // Freeze the symbol table - symbol_table.freeze(); - - if (compute_xrefs) - dynamic_model.computeXrefs(); - - /* - Enforce the same number of equations and endogenous, except in three cases: - - ramsey_model, ramsey_policy or discretionary_policy is used - - a BVAR command is used and there is no equation (standalone BVAR estimation) - - nostrict option is passed and there are more endogs than equations (dealt with before freeze) - */ - if (!(mod_file_struct.ramsey_model_present || mod_file_struct.discretionary_policy_present) - && !(mod_file_struct.bvar_present && dynamic_model.equation_number() == 0) - && !(mod_file_struct.occbin_option) - && (dynamic_model.equation_number() != symbol_table.endo_nbr())) - { - cerr << "ERROR: There are " << dynamic_model.equation_number() << " equations but " << symbol_table.endo_nbr() << " endogenous variables!" << endl; - exit(EXIT_FAILURE); - } - - if (symbol_table.exo_det_nbr() > 0 && mod_file_struct.perfect_foresight_solver_present) - { - cerr << "ERROR: A .mod file cannot contain both one of {perfect_foresight_solver, simul} and varexo_det declaration (all exogenous variables are deterministic in this case)" << endl; - exit(EXIT_FAILURE); - } - - if (mod_file_struct.ramsey_policy_present && symbol_table.exo_det_nbr() > 0) - { - cerr << "ERROR: ramsey_policy is incompatible with deterministic exogenous variables" << endl; - exit(EXIT_FAILURE); - } - - if (mod_file_struct.ramsey_policy_present) - for (vector::iterator it = statements.begin(); it != statements.end(); it++) - { - RamseyPolicyStatement *rps = dynamic_cast(*it); - if (rps != NULL) - rps->checkRamseyPolicyList(); - } - - if (mod_file_struct.identification_present && symbol_table.exo_det_nbr() > 0) - { - cerr << "ERROR: identification is incompatible with deterministic exogenous variables" << endl; - exit(EXIT_FAILURE); - } - - if (!nopreprocessoroutput) - if (!mod_file_struct.ramsey_model_present) - cout << "Found " << dynamic_model.equation_number() << " equation(s)." << endl; - else - { - cout << "Found " << mod_file_struct.orig_eq_nbr << " equation(s)." << endl; - cout << "Found " << dynamic_model.equation_number() << " FOC equation(s) for Ramsey Problem." << endl; - } - - if (symbol_table.exists("dsge_prior_weight")) - if (mod_file_struct.bayesian_irf_present) - { - if (symbol_table.exo_nbr() != symbol_table.observedVariablesNbr()) - { - cerr << "ERROR: When estimating a DSGE-Var and the bayesian_irf option is passed to the estimation " - << "statement, the number of shocks must equal the number of observed variables." << endl; - exit(EXIT_FAILURE); - } - } - else - if (symbol_table.exo_nbr() < symbol_table.observedVariablesNbr()) - { - cerr << "ERROR: When estimating a DSGE-Var, the number of shocks must be " - << "greater than or equal to the number of observed variables." << endl; - exit(EXIT_FAILURE); - } -} - -void -ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_derivs_order, const bool nopreprocessoroutput) -{ - // Mod file may have no equation (for example in a standalone BVAR estimation) - if (dynamic_model.equation_number() > 0) - { - if (nonstationary_variables) - trend_dynamic_model.runTrendTest(global_eval_context); - - // Compute static model and its derivatives - dynamic_model.toStatic(static_model); - if (!no_static) - { - if (mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present || mod_file_struct.osr_present - || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present - || mod_file_struct.calib_smoother_present) - static_model.set_cutoff_to_zero(); - - const bool static_hessian = mod_file_struct.identification_present - || mod_file_struct.estimation_analytic_derivation; - int paramsDerivsOrder = 0; - if (mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation) - paramsDerivsOrder = params_derivs_order; - static_model.computingPass(global_eval_context, no_tmp_terms, static_hessian, - false, paramsDerivsOrder, block, byte_code, nopreprocessoroutput); - } - // Set things to compute for dynamic model - if (mod_file_struct.perfect_foresight_solver_present || mod_file_struct.check_present - || mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present || mod_file_struct.osr_present - || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present - || mod_file_struct.calib_smoother_present) - { - if (mod_file_struct.perfect_foresight_solver_present) - dynamic_model.computingPass(true, false, false, none, global_eval_context, no_tmp_terms, block, use_dll, byte_code, nopreprocessoroutput); - else - { - if (mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present || mod_file_struct.osr_present - || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present - || mod_file_struct.calib_smoother_present) - dynamic_model.set_cutoff_to_zero(); - if (mod_file_struct.order_option < 1 || mod_file_struct.order_option > 3) - { - cerr << "ERROR: Incorrect order option..." << endl; - exit(EXIT_FAILURE); - } - bool hessian = mod_file_struct.order_option >= 2 - || mod_file_struct.identification_present - || mod_file_struct.estimation_analytic_derivation - || linear - || output == second - || output == third; - bool thirdDerivatives = mod_file_struct.order_option == 3 - || mod_file_struct.estimation_analytic_derivation - || output == third; - int paramsDerivsOrder = 0; - if (mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation) - paramsDerivsOrder = params_derivs_order; - dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, use_dll, byte_code, nopreprocessoroutput); - if (linear && mod_file_struct.ramsey_model_present) - orig_ramsey_dynamic_model.computingPass(true, true, false, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, use_dll, byte_code, nopreprocessoroutput); - } - } - else // No computing task requested, compute derivatives up to 2nd order by default - dynamic_model.computingPass(true, true, false, none, global_eval_context, no_tmp_terms, block, use_dll, byte_code, nopreprocessoroutput); - - map eqs; - if (mod_file_struct.ramsey_model_present) - orig_ramsey_dynamic_model.setNonZeroHessianEquations(eqs); - else - dynamic_model.setNonZeroHessianEquations(eqs); - - if (linear && !eqs.empty()) - { - cerr << "ERROR: If the model is declared linear the second derivatives must be equal to zero." << endl - << " The following equations had non-zero second derivatives:" << endl; - for (map::const_iterator it = eqs.begin(); it != eqs.end(); it++) - { - cerr << " * Eq # " << it->first+1; - if (!it->second.empty()) - cerr << " [" << it->second << "]"; - cerr << endl; - } - exit(EXIT_FAILURE); - } - } - - for (vector::iterator it = statements.begin(); - it != statements.end(); it++) - (*it)->computingPass(); -} - -void -ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn, - bool console, bool nograph, bool nointeractive, const ConfigFile &config_file, - bool check_model_changes, bool minimal_workspace, bool compute_xrefs -#if defined(_WIN32) || defined(__CYGWIN32__) - , bool cygwin, bool msvc, bool mingw -#endif - , const bool nopreprocessoroutput - ) const -{ - ofstream mOutputFile; - - if (basename.size()) - { - string fname(basename); - fname += ".m"; - mOutputFile.open(fname.c_str(), ios::out | ios::binary); - if (!mOutputFile.is_open()) - { - cerr << "ERROR: Can't open file " << fname << " for writing" << endl; - exit(EXIT_FAILURE); - } - } - else - { - cerr << "ERROR: Missing file name" << endl; - exit(EXIT_FAILURE); - } - - mOutputFile << "%" << endl - << "% Status : main Dynare file" << endl - << "%" << endl - << "% Warning : this file is generated automatically by Dynare" << endl - << "% from model file (.mod)" << endl << endl; - - if (no_warn) - mOutputFile << "warning off" << endl; // This will be executed *after* function warning_config() - - if (clear_all) - mOutputFile << "if isoctave || matlab_ver_less_than('8.6')" << endl - << " clear all" << endl - << "else" << endl - << " clearvars -global" << endl - << " clear_persistent_variables(fileparts(which('dynare')), false)" << endl - << "end" << endl; - else if (clear_global) - mOutputFile << "clear M_ options_ oo_ estim_params_ bayestopt_ dataset_ dataset_info estimation_info ys0_ ex0_;" << endl; - - mOutputFile << "tic0 = tic;" << endl - << "% Define global variables." << endl - << "global M_ options_ oo_ estim_params_ bayestopt_ dataset_ dataset_info estimation_info ys0_ ex0_" << endl - << "options_ = [];" << endl - << "M_.fname = '" << basename << "';" << endl - << "M_.dynare_version = '" << PACKAGE_VERSION << "';" << endl - << "oo_.dynare_version = '" << PACKAGE_VERSION << "';" << endl - << "options_.dynare_version = '" << PACKAGE_VERSION << "';" << endl - << "%" << endl - << "% Some global variables initialization" << endl - << "%" << endl; - config_file.writeHooks(mOutputFile); - mOutputFile << "global_initialization;" << endl - << "diary off;" << endl; - if (!no_log) - mOutputFile << "diary('" << basename << ".log');" << endl; - - if (minimal_workspace) - mOutputFile << "options_.minimal_workspace = 1;" << endl; - - if (console) - mOutputFile << "options_.console_mode = 1;" << endl - << "options_.nodisplay = 1;" << endl; - if (nograph) - mOutputFile << "options_.nograph = 1;" << endl; - - if (nointeractive) - mOutputFile << "options_.nointeractive = 1;" << endl; - - if (param_used_with_lead_lag) - mOutputFile << "M_.parameter_used_with_lead_lag = true;" << endl; - - if (!nopreprocessoroutput) - cout << "Processing outputs ..." << endl; - - symbol_table.writeOutput(mOutputFile); - - // Initialize M_.Sigma_e, M_.Correlation_matrix, M_.H, and M_.Correlation_matrix_ME - mOutputFile << "M_.Sigma_e = zeros(" << symbol_table.exo_nbr() << ", " - << symbol_table.exo_nbr() << ");" << endl - << "M_.Correlation_matrix = eye(" << symbol_table.exo_nbr() << ", " - << symbol_table.exo_nbr() << ");" << endl; - - if (mod_file_struct.calibrated_measurement_errors) - mOutputFile << "M_.H = zeros(" << symbol_table.observedVariablesNbr() << ", " - << symbol_table.observedVariablesNbr() << ");" << endl - << "M_.Correlation_matrix_ME = eye(" << symbol_table.observedVariablesNbr() << ", " - << symbol_table.observedVariablesNbr() << ");" << endl; - else - mOutputFile << "M_.H = 0;" << endl - << "M_.Correlation_matrix_ME = 1;" << endl; - - // May be later modified by a shocks block - mOutputFile << "M_.sigma_e_is_diagonal = 1;" << endl; - - // Initialize M_.det_shocks - mOutputFile << "M_.det_shocks = [];" << endl; - - if (linear == 1) - mOutputFile << "options_.linear = 1;" << endl; - - mOutputFile << "options_.block=" << block << ";" << endl - << "options_.bytecode=" << byte_code << ";" << endl - << "options_.use_dll=" << use_dll << ";" << endl; - - if (parallel_local_files.size() > 0) - { - mOutputFile << "options_.parallel_info.local_files = {" << endl; - for (size_t i = 0; i < parallel_local_files.size(); i++) - { - size_t j = parallel_local_files[i].find_last_of("/\\"); - if (j == string::npos) - mOutputFile << "'', '" << parallel_local_files[i] << "';" << endl; - else - mOutputFile << "'" << parallel_local_files[i].substr(0, j+1) << "', '" - << parallel_local_files[i].substr(j+1, string::npos) << "';" << endl; - } - mOutputFile << "};" << endl; - } - - mOutputFile << "M_.nonzero_hessian_eqs = "; - if (mod_file_struct.ramsey_model_present) - orig_ramsey_dynamic_model.printNonZeroHessianEquations(mOutputFile); - else - dynamic_model.printNonZeroHessianEquations(mOutputFile); - mOutputFile << ";" << endl - << "M_.hessian_eq_zero = isempty(M_.nonzero_hessian_eqs);" << endl; - - config_file.writeCluster(mOutputFile); - - if (byte_code) - mOutputFile << "if exist('bytecode') ~= 3" << endl - << " error('DYNARE: Can''t find bytecode DLL. Please compile it or remove the ''bytecode'' option.')" << endl - << "end" << endl; - - bool hasModelChanged = !dynamic_model.isChecksumMatching(basename); - if (!check_model_changes) - hasModelChanged = true; - - if (hasModelChanged) - { - // Erase possible remnants of previous runs - unlink((basename + "_dynamic.m").c_str()); - unlink((basename + "_dynamic.cod").c_str()); - unlink((basename + "_dynamic.bin").c_str()); - - unlink((basename + "_static.m").c_str()); - unlink((basename + "_static.cod").c_str()); - unlink((basename + "_static.bin").c_str()); - - unlink((basename + "_steadystate2.m").c_str()); - unlink((basename + "_set_auxiliary_variables.m").c_str()); - } - - if (!use_dll) - { - mOutputFile << "erase_compiled_function('" + basename + "_static');" << endl; - mOutputFile << "erase_compiled_function('" + basename + "_dynamic');" << endl; - } - -#if defined(_WIN32) || defined(__CYGWIN32__) -# if (defined(_MSC_VER) && _MSC_VER < 1700) - // If using USE_DLL with MSVC 10.0 or earlier, check that the user didn't use a function not supported by the compiler (because MSVC <= 10.0 doesn't comply with C99 standard) - if (use_dll && msvc) - { - if (dynamic_model.isUnaryOpUsed(oAcosh)) - { - cerr << "ERROR: acosh() function is not supported with USE_DLL option and older MSVC compilers; use Cygwin, MinGW or upgrade your MSVC compiler to 11.0 (2012) or later." << endl; - exit(EXIT_FAILURE); - } - if (dynamic_model.isUnaryOpUsed(oAsinh)) - { - cerr << "ERROR: asinh() function is not supported with USE_DLL option and older MSVC compilers; use Cygwin, MinGW or upgrade your MSVC compiler to 11.0 (2012) or later." << endl; - exit(EXIT_FAILURE); - } - if (dynamic_model.isUnaryOpUsed(oAtanh)) - { - cerr << "ERROR: atanh() function is not supported with USE_DLL option and older MSVC compilers; use Cygwin, MinGW or upgrade your MSVC compiler to 11.0 (2012) or later." << endl; - exit(EXIT_FAILURE); - } - } -# endif -#endif - - // Compile the dynamic MEX file for use_dll option - // When check_model_changes is true, don't force compile if MEX is fresher than source - if (use_dll) - { -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - if (msvc) - // MATLAB/Windows + Microsoft Visual C++ - mOutputFile << "dyn_mex('msvc', '" << basename << "', " << !check_model_changes << ")" << endl; - else if (cygwin) - // MATLAB/Windows + Cygwin g++ - mOutputFile << "dyn_mex('cygwin', '" << basename << "', " << !check_model_changes << ")" << endl; - else if (mingw) - // MATLAB/Windows + MinGW g++ - mOutputFile << "dyn_mex('mingw', '" << basename << "', " << !check_model_changes << ")" << endl; - else - mOutputFile << "if isoctave" << endl - << " dyn_mex('', '" << basename << "', " << !check_model_changes << ")" << endl - << "else" << endl - << " error('When using the USE_DLL option on Matlab, you must give the ''cygwin'', ''msvc'', or ''mingw'' option to the ''dynare'' command')" << endl - << "end" << endl; -#else - // other configurations - mOutputFile << "dyn_mex('', '" << basename << "', " << !check_model_changes << ")" << endl; -#endif - } - - // Add path for block option with M-files - if (block && !byte_code) - mOutputFile << "addpath " << basename << ";" << endl; - - mOutputFile << "M_.orig_eq_nbr = " << mod_file_struct.orig_eq_nbr << ";" << endl - << "M_.eq_nbr = " << dynamic_model.equation_number() << ";" << endl - << "M_.ramsey_eq_nbr = " << mod_file_struct.ramsey_eq_nbr << ";" << endl - << "M_.set_auxiliary_variables = exist(['./' M_.fname '_set_auxiliary_variables.m'], 'file') == 2;" << endl; - - if (dynamic_model.equation_number() > 0) - { - dynamic_model.writeOutput(mOutputFile, basename, block, byte_code, use_dll, mod_file_struct.order_option, mod_file_struct.estimation_present, compute_xrefs, false); - if (!no_static) - static_model.writeOutput(mOutputFile, block); - } - - // Print statements - for (vector::const_iterator it = statements.begin(); - it != statements.end(); it++) - { - (*it)->writeOutput(mOutputFile, basename, minimal_workspace); - - /* Special treatment for initval block: insert initial values for the - auxiliary variables and initialize exo det */ - InitValStatement *ivs = dynamic_cast(*it); - if (ivs != NULL) - { - static_model.writeAuxVarInitval(mOutputFile, oMatlabOutsideModel); - ivs->writeOutputPostInit(mOutputFile); - } - - // Special treatment for endval block: insert initial values for the auxiliary variables - EndValStatement *evs = dynamic_cast(*it); - if (evs != NULL) - static_model.writeAuxVarInitval(mOutputFile, oMatlabOutsideModel); - - // Special treatment for load params and steady state statement: insert initial values for the auxiliary variables - LoadParamsAndSteadyStateStatement *lpass = dynamic_cast(*it); - if (lpass && !no_static) - static_model.writeAuxVarInitval(mOutputFile, oMatlabOutsideModel); - } - - // Remove path for block option with M-files - if (block && !byte_code) - mOutputFile << "rmpath " << basename << ";" << endl; - - mOutputFile << "save('" << basename << "_results.mat', 'oo_', 'M_', 'options_');" << endl - << "if exist('estim_params_', 'var') == 1" << endl - << " save('" << basename << "_results.mat', 'estim_params_', '-append');" << endl << "end" << endl - << "if exist('bayestopt_', 'var') == 1" << endl - << " save('" << basename << "_results.mat', 'bayestopt_', '-append');" << endl << "end" << endl - << "if exist('dataset_', 'var') == 1" << endl - << " save('" << basename << "_results.mat', 'dataset_', '-append');" << endl << "end" << endl - << "if exist('estimation_info', 'var') == 1" << endl - << " save('" << basename << "_results.mat', 'estimation_info', '-append');" << endl << "end" << endl - << "if exist('dataset_info', 'var') == 1" << endl - << " save('" << basename << "_results.mat', 'dataset_info', '-append');" << endl << "end" << endl - << "if exist('oo_recursive_', 'var') == 1" << endl - << " save('" << basename << "_results.mat', 'oo_recursive_', '-append');" << endl << "end" << endl; - - config_file.writeEndParallel(mOutputFile); - - mOutputFile << endl << endl - << "disp(['Total computing time : ' dynsec2hms(toc(tic0)) ]);" << endl; - - if (!no_warn) - { - if (warnings.countWarnings() > 0) - mOutputFile << "disp('Note: " << warnings.countWarnings() << " warning(s) encountered in the preprocessor')" << endl; - - mOutputFile << "if ~isempty(lastwarn)" << endl - << " disp('Note: warning(s) encountered in MATLAB/Octave code')" << endl - << "end" << endl; - } - - if (!no_log) - mOutputFile << "diary off" << endl; - - mOutputFile.close(); - - if (hasModelChanged) - { - // Create static and dynamic files - if (dynamic_model.equation_number() > 0) - { - if (!no_static) - { - static_model.writeStaticFile(basename, block, byte_code, use_dll, false); - static_model.writeParamsDerivativesFile(basename, false); - } - - dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option, false); - dynamic_model.writeParamsDerivativesFile(basename, false); - } - - // Create steady state file - steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present, false); - } - - if (!nopreprocessoroutput) - cout << "done" << endl; -} - -void -ModFile::writeExternalFiles(const string &basename, FileOutputType output, LanguageOutputType language, const bool nopreprocessoroutput) const -{ - switch (language) - { - case c: - writeExternalFilesC(basename, output); - break; - case cpp: - writeExternalFilesCC(basename, output); - break; - case julia: - writeExternalFilesJulia(basename, output, nopreprocessoroutput); - break; - default: - cerr << "This case shouldn't happen. Contact the authors of Dynare" << endl; - exit(EXIT_FAILURE); - } -} - -void -ModFile::writeExternalFilesC(const string &basename, FileOutputType output) const -{ - writeModelC(basename); - steady_state_model.writeSteadyStateFileC(basename, mod_file_struct.ramsey_model_present); - - dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option, false); - - if (!no_static) - static_model.writeStaticFile(basename, false, false, true, false); - - // static_model.writeStaticCFile(basename, block, byte_code, use_dll); - // static_model.writeParamsDerivativesFileC(basename, cuda); - // static_model.writeAuxVarInitvalC(mOutputFile, oMatlabOutsideModel, cuda); - - dynamic_model.writeResidualsC(basename, cuda); - // dynamic_model.writeParamsDerivativesFileC(basename, cuda); - dynamic_model.writeFirstDerivativesC(basename, cuda); - - if (output == second) - dynamic_model.writeSecondDerivativesC_csr(basename, cuda); - else if (output == third) - { - dynamic_model.writeSecondDerivativesC_csr(basename, cuda); - dynamic_model.writeThirdDerivativesC_csr(basename, cuda); - } -} - -void -ModFile::writeModelC(const string &basename) const -{ - string filename = basename + ".c"; - - ofstream mDriverCFile; - mDriverCFile.open(filename.c_str(), ios::out | ios::binary); - if (!mDriverCFile.is_open()) - { - cerr << "Error: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - mDriverCFile << "/*" << endl - << " * " << filename << " : Driver file for Dynare C code" << endl - << " *" << endl - << " * Warning : this file is generated automatically by Dynare" << endl - << " * from model file (.mod)" << endl - << " */" << endl - << endl - << "#include \"dynare_driver.h\"" << endl - << endl - << "struct" << endl - << "{" << endl; - - // Write basic info - symbol_table.writeCOutput(mDriverCFile); - - mDriverCFile << endl << "params.resize(param_nbr);" << endl; - - if (dynamic_model.equation_number() > 0) - { - dynamic_model.writeCOutput(mDriverCFile, basename, block, byte_code, use_dll, mod_file_struct.order_option, mod_file_struct.estimation_present); - // if (!no_static) - // static_model.writeCOutput(mOutputFile, block); - } - - // Print statements - for (vector::const_iterator it = statements.begin(); - it != statements.end(); it++) - (*it)->writeCOutput(mDriverCFile, basename); - - mDriverCFile << "} DynareInfo;" << endl; - mDriverCFile.close(); - - // Write informational m file - ofstream mOutputFile; - - if (basename.size()) - { - string fname(basename); - fname += ".m"; - mOutputFile.open(fname.c_str(), ios::out | ios::binary); - if (!mOutputFile.is_open()) - { - cerr << "ERROR: Can't open file " << fname - << " for writing" << endl; - exit(EXIT_FAILURE); - } - } - else - { - cerr << "ERROR: Missing file name" << endl; - exit(EXIT_FAILURE); - } - - mOutputFile << "%" << endl - << "% Status : informational m file" << endl - << "%" << endl - << "% Warning : this file is generated automatically by Dynare" << endl - << "% from model file (.mod)" << endl << endl - << "disp('The following C file was successfully created:');" << endl - << "ls preprocessorOutput.c" << endl << endl; - mOutputFile.close(); -} - -void -ModFile::writeExternalFilesCC(const string &basename, FileOutputType output) const -{ - writeModelCC(basename); - steady_state_model.writeSteadyStateFileC(basename, mod_file_struct.ramsey_model_present); - - dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option, false); - - if (!no_static) - static_model.writeStaticFile(basename, false, false, true, false); - - // static_model.writeStaticCFile(basename, block, byte_code, use_dll); - // static_model.writeParamsDerivativesFileC(basename, cuda); - // static_model.writeAuxVarInitvalC(mOutputFile, oMatlabOutsideModel, cuda); - - // dynamic_model.writeResidualsC(basename, cuda); - // dynamic_model.writeParamsDerivativesFileC(basename, cuda); - dynamic_model.writeResidualsC(basename, cuda); - dynamic_model.writeFirstDerivativesC_csr(basename, cuda); - - if (output == second) - dynamic_model.writeSecondDerivativesC_csr(basename, cuda); - else if (output == third) - { - dynamic_model.writeSecondDerivativesC_csr(basename, cuda); - dynamic_model.writeThirdDerivativesC_csr(basename, cuda); - } -} - -void -ModFile::writeModelCC(const string &basename) const -{ - string filename = basename + ".cc"; - - ofstream mDriverCFile; - mDriverCFile.open(filename.c_str(), ios::out | ios::binary); - if (!mDriverCFile.is_open()) - { - cerr << "Error: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - mDriverCFile << "/*" << endl - << " * " << filename << " : Driver file for Dynare C++ code" << endl - << " *" << endl - << " * Warning : this file is generated automatically by Dynare" << endl - << " * from model file (.mod)" << endl - << " */" << endl - << endl - << "#include \"dynare_cpp_driver.hh\"" << endl - << endl - << "DynareInfo::DynareInfo(void)" << endl - << "{" << endl; - - // Write basic info - symbol_table.writeCCOutput(mDriverCFile); - - mDriverCFile << endl << "params.resize(param_nbr);" << endl; - - if (dynamic_model.equation_number() > 0) - { - dynamic_model.writeCCOutput(mDriverCFile, basename, block, byte_code, use_dll, mod_file_struct.order_option, mod_file_struct.estimation_present); - // if (!no_static) - // static_model.writeCOutput(mOutputFile, block); - } - - // Print statements - for (vector::const_iterator it = statements.begin(); - it != statements.end(); it++) - (*it)->writeCOutput(mDriverCFile, basename); - - mDriverCFile << "};" << endl; - mDriverCFile.close(); - - // Write informational m file - ofstream mOutputFile; - - if (basename.size()) - { - string fname(basename); - fname += ".m"; - mOutputFile.open(fname.c_str(), ios::out | ios::binary); - if (!mOutputFile.is_open()) - { - cerr << "ERROR: Can't open file " << fname - << " for writing" << endl; - exit(EXIT_FAILURE); - } - } - else - { - cerr << "ERROR: Missing file name" << endl; - exit(EXIT_FAILURE); - } - - mOutputFile << "%" << endl - << "% Status : informational m file" << endl - << "%" << endl - << "% Warning : this file is generated automatically by Dynare" << endl - << "% from model file (.mod)" << endl << endl - << "disp('The following C++ file was successfully created:');" << endl - << "ls preprocessorOutput.cc" << endl << endl; - mOutputFile.close(); -} - -void -ModFile::writeExternalFilesJulia(const string &basename, FileOutputType output, const bool nopreprocessoroutput) const -{ - ofstream jlOutputFile; - if (basename.size()) - { - string fname(basename); - fname += ".jl"; - jlOutputFile.open(fname.c_str(), ios::out | ios::binary); - if (!jlOutputFile.is_open()) - { - cerr << "ERROR: Can't open file " << fname - << " for writing" << endl; - exit(EXIT_FAILURE); - } - } - else - { - cerr << "ERROR: Missing file name" << endl; - exit(EXIT_FAILURE); - } - - jlOutputFile << "module " << basename << endl - << "#" << endl - << "# NB: this file was automatically generated by Dynare" << endl - << "# from " << basename << ".mod" << endl - << "#" << endl << endl - << "using DynareModel" << endl - << "using DynareOptions" << endl - << "using DynareOutput" << endl << endl - << "using Utils" << endl - << "using SteadyState" << endl << endl - << "using " << basename << "Static" << endl - << "using " << basename << "Dynamic" << endl - << "if isfile(\"" << basename << "SteadyState.jl" "\")" << endl - << " using " << basename << "SteadyState" << endl - << "end" << endl - << "if isfile(\"" << basename << "SteadyState2.jl" "\")" << endl - << " using " << basename << "SteadyState2" << endl - << "end" << endl << endl - << "export model_, options_, oo_" << endl; - - // Write Output - jlOutputFile << endl - << "oo_ = dynare_output()" << endl - << "oo_.dynare_version = \"" << PACKAGE_VERSION << "\"" << endl; - - // Write Options - jlOutputFile << endl - << "options_ = dynare_options()" << endl - << "options_.dynare_version = \"" << PACKAGE_VERSION << "\"" << endl; - if (linear == 1) - jlOutputFile << "options_.linear = true" << endl; - - // Write Model - jlOutputFile << endl - << "model_ = dynare_model()" << endl - << "model_.fname = \"" << basename << "\"" << endl - << "model_.dynare_version = \"" << PACKAGE_VERSION << "\"" << endl - << "model_.sigma_e = zeros(Float64, " << symbol_table.exo_nbr() << ", " - << symbol_table.exo_nbr() << ")" << endl - << "model_.correlation_matrix = ones(Float64, " << symbol_table.exo_nbr() << ", " - << symbol_table.exo_nbr() << ")" << endl - << "model_.orig_eq_nbr = " << mod_file_struct.orig_eq_nbr << endl - << "model_.eq_nbr = " << dynamic_model.equation_number() << endl - << "model_.ramsey_eq_nbr = " << mod_file_struct.ramsey_eq_nbr << endl; - - if (mod_file_struct.calibrated_measurement_errors) - jlOutputFile << "model_.h = zeros(Float64," - << symbol_table.observedVariablesNbr() << ", " - << symbol_table.observedVariablesNbr() << ");" << endl - << "model_.correlation_matrix_me = ones(Float64, " - << symbol_table.observedVariablesNbr() << ", " - << symbol_table.observedVariablesNbr() << ");" << endl; - else - jlOutputFile << "model_.h = zeros(Float64, 1, 1)" << endl - << "model_.correlation_matrix_me = ones(Float64, 1, 1)" << endl; - - if (!nopreprocessoroutput) - cout << "Processing outputs ..." << endl; - symbol_table.writeJuliaOutput(jlOutputFile); - - if (dynamic_model.equation_number() > 0) - { - dynamic_model.writeOutput(jlOutputFile, basename, false, false, false, - mod_file_struct.order_option, - mod_file_struct.estimation_present, false, true); - if (!no_static) - { - static_model.writeStaticFile(basename, false, false, false, true); - static_model.writeParamsDerivativesFile(basename, true); - } - dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, - mod_file_struct.order_option, true); - dynamic_model.writeParamsDerivativesFile(basename, true); - } - steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present, true); - - // Print statements (includes parameter values) - for (vector::const_iterator it = statements.begin(); - it != statements.end(); it++) - (*it)->writeJuliaOutput(jlOutputFile, basename); - - jlOutputFile << "model_.static = " << basename << "Static.static!" << endl - << "model_.dynamic = " << basename << "Dynamic.dynamic!" << endl - << "if isfile(\"" << basename << "SteadyState.jl" "\")" << endl - << " model_.user_written_analytical_steady_state = true" << endl - << " model_.steady_state = " << basename << "SteadyState.steady_state!" << endl - << "end" << endl - << "if isfile(\"" << basename << "SteadyState2.jl" "\")" << endl - << " model_.analytical_steady_state = true" << endl - << " model_.steady_state = " << basename << "SteadyState2.steady_state!" << endl - << "end" << endl - << "if isfile(\"" << basename << "StaticParamsDerivs.jl" "\")" << endl - << " using " << basename << "StaticParamsDerivs" << endl - << " model_.static_params_derivs = " << basename << "StaticParamsDerivs.params_derivs" << endl - << "end" << endl - << "if isfile(\"" << basename << "DynamicParamsDerivs.jl" "\")" << endl - << " using " << basename << "DynamicParamsDerivs" << endl - << " model_.dynamic_params_derivs = " << basename << "DynamicParamsDerivs.params_derivs" << endl - << "end" << endl - << "end" << endl; - jlOutputFile.close(); - if (!nopreprocessoroutput) - cout << "done" << endl; -} - -void -ModFile::writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, const bool nopreprocessoroutput, bool jsonderivsimple) -{ - if (json == nojson) - return; - - if (json == parsing || json == checkpass) - symbol_table.freeze(); - - if (json_output_mode == standardout) - cout << "//-- BEGIN JSON --// " << endl - << "{" << endl; - - writeJsonOutputParsingCheck(basename, json_output_mode, json == transformpass, json == computingpass); - - if (json == parsing || json == checkpass) - symbol_table.unfreeze(); - - if (json == computingpass) - writeJsonComputingPassOutput(basename, json_output_mode, jsonderivsimple); - - if (json_output_mode == standardout) - cout << "}" << endl - << "//-- END JSON --// " << endl; - - if (!nopreprocessoroutput) - switch (json) - { - case parsing: - cout << "JSON written after Parsing step." << endl; - break; - case checkpass: - cout << "JSON written after Check step." << endl; - break; - case transformpass: - cout << "JSON written after Transform step." << endl; - break; - case computingpass: - cout << "JSON written after Computing step." << endl; - break; - case nojson: - cerr << "ModFile::writeJsonOutput: should not arrive here." << endl; - exit(EXIT_FAILURE); - } - - if (onlyjson) - exit(EXIT_SUCCESS); -} - -void -ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType json_output_mode, bool transformpass, bool computingpass) const -{ - ostringstream output; - output << "{" << endl; - - symbol_table.writeJsonOutput(output); - output << ", "; - dynamic_model.writeJsonOutput(output); - - if (!statements.empty()) - { - output << ", \"statements\": ["; - for (vector::const_iterator it = statements.begin(); - it != statements.end(); it++) - { - if (it != statements.begin()) - output << ", " << endl; - (*it)->writeJsonOutput(output); - } - output << "]" << endl; - } - - if (computingpass) - { - output << ","; - dynamic_model.writeJsonDynamicModelInfo(output); - } - output << "}" << endl; - - ostringstream original_model_output; - original_model_output << ""; - if (transformpass || computingpass) - { - original_model_output << "{"; - original_model.writeJsonOriginalModelOutput(original_model_output); - original_model_output << "}" << endl; - } - - ostringstream steady_state_model_output; - steady_state_model_output << ""; - if (dynamic_model.equation_number() > 0) - steady_state_model.writeJsonSteadyStateFile(steady_state_model_output, - transformpass || computingpass); - - if (json_output_mode == standardout) - { - if (transformpass || computingpass) - cout << "\"transformed_modfile\": "; - else - cout << "\"modfile\": "; - cout << output.str(); - if (!original_model_output.str().empty()) - cout << ", \"original_model\": " << original_model_output.str(); - if (!steady_state_model_output.str().empty()) - cout << ", \"steady_state_model\": " << steady_state_model_output.str(); - } - else - { - ofstream jsonOutputFile; - - if (basename.size()) - { - string fname(basename); - fname += ".json"; - jsonOutputFile.open(fname.c_str(), ios::out | ios::binary); - if (!jsonOutputFile.is_open()) - { - cerr << "ERROR: Can't open file " << fname << " for writing" << endl; - exit(EXIT_FAILURE); - } - } - else - { - cerr << "ERROR: Missing file name" << endl; - exit(EXIT_FAILURE); - } - - jsonOutputFile << output.str(); - jsonOutputFile.close(); - - if (!original_model_output.str().empty()) - { - if (basename.size()) - { - string fname(basename); - fname += "_original.json"; - jsonOutputFile.open(fname.c_str(), ios::out | ios::binary); - if (!jsonOutputFile.is_open()) - { - cerr << "ERROR: Can't open file " << fname << " for writing" << endl; - exit(EXIT_FAILURE); - } - } - else - { - cerr << "ERROR: Missing file name" << endl; - exit(EXIT_FAILURE); - } - - jsonOutputFile << original_model_output.str(); - jsonOutputFile.close(); - } - if (!steady_state_model_output.str().empty()) - { - if (basename.size()) - { - string fname(basename); - fname += "_steady_state_model.json"; - jsonOutputFile.open(fname.c_str(), ios::out | ios::binary); - if (!jsonOutputFile.is_open()) - { - cerr << "ERROR: Can't open file " << fname << " for writing" << endl; - exit(EXIT_FAILURE); - } - } - else - { - cerr << "ERROR: Missing file name" << endl; - exit(EXIT_FAILURE); - } - - jsonOutputFile << steady_state_model_output.str(); - jsonOutputFile.close(); - } - } -} - -void -ModFile::writeJsonComputingPassOutput(const string &basename, JsonFileOutputType json_output_mode, bool jsonderivsimple) const -{ - if (basename.empty() && json_output_mode != standardout) - { - cerr << "ERROR: Missing file name" << endl; - exit(EXIT_FAILURE); - } - - ostringstream tmp_out, static_output, dynamic_output, static_paramsd_output, dynamic_paramsd_output; - - static_output << "{"; - static_model.writeJsonComputingPassOutput(static_output, !jsonderivsimple); - static_output << "}"; - - dynamic_output << "{"; - dynamic_model.writeJsonComputingPassOutput(dynamic_output, !jsonderivsimple); - dynamic_output << "}"; - - tmp_out << ""; - static_paramsd_output << ""; - static_model.writeJsonParamsDerivativesFile(tmp_out, !jsonderivsimple); - if (!tmp_out.str().empty()) - static_paramsd_output << "{" << tmp_out.str() << "}" << endl; - - tmp_out.str(""); - dynamic_paramsd_output << ""; - dynamic_model.writeJsonParamsDerivativesFile(tmp_out, !jsonderivsimple); - if (!tmp_out.str().empty()) - dynamic_paramsd_output << "{" << tmp_out.str() << "}" << endl; - - if (json_output_mode == standardout) - { - cout << ", \"static_model\": " << static_output.str() << endl - << ", \"dynamic_model\": " << dynamic_output.str() << endl; - - if (!static_paramsd_output.str().empty()) - cout << ", \"static_params_deriv\": " << static_paramsd_output.str() << endl; - - if (!dynamic_paramsd_output.str().empty()) - cout << ", \"dynamic_params_deriv\": " << dynamic_paramsd_output.str() << endl; - } - else - { - string fname_original, fname_static, fname_dynamic; - fname_static = basename + "_static.json"; - fname_dynamic = basename + "_dynamic.json"; - - writeJsonFileHelper(fname_static, static_output); - writeJsonFileHelper(fname_dynamic, dynamic_output); - - if (!static_paramsd_output.str().empty()) - { - string fname_static_params; - fname_static_params = basename + "_static_params_derivs.json"; - writeJsonFileHelper(fname_static_params, static_paramsd_output); - } - - if (!dynamic_paramsd_output.str().empty()) - { - string fname_dynamic_params; - fname_dynamic_params = basename + "_params_derivs.json"; - writeJsonFileHelper(fname_dynamic_params, dynamic_paramsd_output); - } - } -} - -void -ModFile::writeJsonFileHelper(string &fname, ostringstream &output) const -{ - ofstream jsonOutput; - jsonOutput.open(fname.c_str(), ios::out | ios::binary); - if (!jsonOutput.is_open()) - { - cerr << "ERROR: Can't open file " << fname << " for writing" << endl; - exit(EXIT_FAILURE); - } - jsonOutput << output.str(); - jsonOutput.close(); -} diff --git a/preprocessor/ModFile.hh b/preprocessor/ModFile.hh deleted file mode 100644 index ac678b5b5..000000000 --- a/preprocessor/ModFile.hh +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2006-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 . - */ - -#ifndef _MOD_FILE_HH -#define _MOD_FILE_HH - -using namespace std; - -#include -#include -#include -#include - -#include "SymbolTable.hh" -#include "NumericalConstants.hh" -#include "NumericalInitialization.hh" -#include "StaticModel.hh" -#include "DynamicModel.hh" -#include "SteadyStateModel.hh" -#include "Statement.hh" -#include "ExternalFunctionsTable.hh" -#include "ConfigFile.hh" -#include "WarningConsolidation.hh" -#include "ExtendedPreprocessorTypes.hh" - -// for checksum computation -#ifndef PRIVATE_BUFFER_SIZE -# define PRIVATE_BUFFER_SIZE 1024 -#endif - -//! The abstract representation of a "mod" file -class ModFile -{ -public: - ModFile(WarningConsolidation &warnings_arg); - ~ModFile(); - //! Symbol table - SymbolTable symbol_table; - //! External Functions table - ExternalFunctionsTable external_functions_table; - //! Numerical constants table - NumericalConstants num_constants; - //! Expressions outside model block - DataTree expressions_tree; - //! Original model, as declared in the "model" block, that won't be modified by the preprocessor - DynamicModel original_model; - //! Dynamic model, as declared in the "model" block - DynamicModel dynamic_model; - //! A copy of Dynamic model, for testing trends declared by user - DynamicModel trend_dynamic_model; - //! A model in which to create the FOC for the ramsey problem - DynamicModel ramsey_FOC_equations_dynamic_model; - //! A copy of the original model, used to test model linearity under ramsey problem - DynamicModel orig_ramsey_dynamic_model; - //! Static model, as derived from the "model" block when leads and lags have been removed - StaticModel static_model; - //! Static model, as declared in the "steady_state_model" block if present - SteadyStateModel steady_state_model; - //! Option linear - bool linear; - - //! Is the model block decomposed? - bool block; - - //! Is the model stored in bytecode format (byte_code=true) or in a M-file (byte_code=false) - bool byte_code; - - //! Is the model stored in a MEX file ? (option "use_dll" of "model") - bool use_dll; - - //! Is the static model have to computed (no_static=false) or not (no_static=true). Option of 'model' - bool no_static; - - //! Is the 'differentiate_forward_vars' option used? - bool differentiate_forward_vars; - - /*! If the 'differentiate_forward_vars' option is used, contains the set of - endogenous with respect to which to do the transformation; - if empty, means that the transformation must be applied to all endos - with a lead */ - vector differentiate_forward_vars_subset; - - //! Are nonstationary variables present ? - bool nonstationary_variables; - - //! Global evaluation context - /*! Filled using initval blocks and parameters initializations */ - eval_context_t global_eval_context; - - //! Parameter used with lead/lag - bool param_used_with_lead_lag; - - //! Stores the list of extra files to be transefered during a parallel run - /*! (i.e. option parallel_local_files of model block) */ - vector parallel_local_files; - -private: - //! List of statements - vector statements; - //! Structure of the mod file - ModFileStructure mod_file_struct; - //! Warnings Encountered - WarningConsolidation &warnings; - //! Functions used in writing of JSON outut. See writeJsonOutput - void writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType json_output_mode, bool transformpass, bool computingpass) const; - void writeJsonComputingPassOutput(const string &basename, JsonFileOutputType json_output_mode, bool jsonderivsimple) const; - void writeJsonFileHelper(string &fname, ostringstream &output) const; -public: - //! Add a statement - void addStatement(Statement *st); - //! Add a statement at the front of the statements vector - void addStatementAtFront(Statement *st); - //! Evaluate all the statements - /*! \param warn_uninit Should a warning be displayed for uninitialized endogenous/exogenous/parameters ? */ - void evalAllExpressions(bool warn_uninit, const bool nopreprocessoroutput); - //! Do some checking and fills mod_file_struct - /*! \todo add check for number of equations and endogenous if ramsey_policy is present */ - void checkPass(bool nostrict, bool stochastic); - //! Perform some transformations on the model (creation of auxiliary vars and equations) - /*! \param compute_xrefs if true, equation cross references will be computed */ - void transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const bool nopreprocessoroutput); - //! Execute computations - /*! \param no_tmp_terms if true, no temporary terms will be computed in the static and dynamic files */ - /*! \param params_derivs_order compute this order of derivs wrt parameters */ - void computingPass(bool no_tmp_terms, FileOutputType output, int params_derivs_order, const bool nopreprocessoroutput); - //! Writes Matlab/Octave output files - /*! - \param basename The base name used for writing output files. Should be the name of the mod file without its extension - \param clear_all Should a "clear all" instruction be written to output ? - \param console Are we in console mode ? - \param nograph Should we build the figures? - \param nointeractive Should Dynare request user input? - \param cygwin Should the MEX command of use_dll be adapted for Cygwin? - \param msvc Should the MEX command of use_dll be adapted for MSVC? - \param mingw Should the MEX command of use_dll be adapted for MinGW? - \param compute_xrefs if true, equation cross references will be computed - */ - void writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn, - bool console, bool nograph, bool nointeractive, const ConfigFile &config_file, - bool check_model_changes, bool minimal_workspace, bool compute_xrefs -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - , bool cygwin, bool msvc, bool mingw -#endif - , const bool nopreprocessoroutput - ) const; - void writeExternalFiles(const string &basename, FileOutputType output, LanguageOutputType language, const bool nopreprocessoroutput) const; - void writeExternalFilesC(const string &basename, FileOutputType output) const; - void writeExternalFilesCC(const string &basename, FileOutputType output) const; - void writeExternalFilesJulia(const string &basename, FileOutputType output, const bool nopreprocessoroutput) const; - //! Writes C output files only => No further Matlab processing - void writeCOutputFiles(const string &basename) const; - void writeModelC(const string &basename) const; - //! Writes Cpp output files only => No further Matlab processing - void writeCCOutputFiles(const string &basename) const; - void writeModelCC(const string &basename) const; - - void computeChecksum(); - //! Write JSON representation of ModFile object - //! Initially created to enable Julia to work with .mod files - //! Potentially outputs ModFile after the various parts of processing (parsing, checkPass, transformPass, computingPass) - //! Allows user of other host language platforms (python, fortran, etc) to provide support for dynare .mod files - void writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, const bool nopreprocessoroutput, bool jsonderivsimple = false); -}; - -#endif // ! MOD_FILE_HH diff --git a/preprocessor/ModelTree.cc b/preprocessor/ModelTree.cc deleted file mode 100644 index aea4f6b70..000000000 --- a/preprocessor/ModelTree.cc +++ /dev/null @@ -1,2028 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#include -#include -#include -#include -#include - -#include "ModelTree.hh" -#include "MinimumFeedbackSet.hh" -#include -#include -#include -#include - -using namespace boost; -using namespace MFS; - -bool -ModelTree::computeNormalization(const jacob_map_t &contemporaneous_jacobian, bool verbose) -{ - const int n = equations.size(); - - assert(n == symbol_table.endo_nbr()); - - typedef adjacency_list BipartiteGraph; - - /* - Vertices 0 to n-1 are for endogenous (using type specific ID) - Vertices n to 2*n-1 are for equations (using equation no.) - */ - BipartiteGraph g(2 * n); - - // Fill in the graph - set > endo; - - for (jacob_map_t::const_iterator it = contemporaneous_jacobian.begin(); it != contemporaneous_jacobian.end(); it++) - add_edge(it->first.first + n, it->first.second, g); - - // Compute maximum cardinality matching - vector mate_map(2*n); - -#if 1 - bool check = checked_edmonds_maximum_cardinality_matching(g, &mate_map[0]); -#else // Alternative way to compute normalization, by giving an initial matching using natural normalizations - fill(mate_map.begin(), mate_map.end(), graph_traits::null_vertex()); - - multimap natural_endo2eqs; - computeNormalizedEquations(natural_endo2eqs); - - for (int i = 0; i < symbol_table.endo_nbr(); i++) - { - if (natural_endo2eqs.count(i) == 0) - continue; - - int j = natural_endo2eqs.find(i)->second; - - put(&mate_map[0], i, n+j); - put(&mate_map[0], n+j, i); - } - - edmonds_augmenting_path_finder::type> augmentor(g, &mate_map[0], get(vertex_index, g)); - bool not_maximum_yet = true; - while (not_maximum_yet) - { - not_maximum_yet = augmentor.augment_matching(); - } - augmentor.get_current_matching(&mate_map[0]); - - bool check = maximum_cardinality_matching_verifier::type>::verify_matching(g, &mate_map[0], get(vertex_index, g)); -#endif - - assert(check); - -#ifdef DEBUG - for (int i = 0; i < n; i++) - cout << "Endogenous " << symbol_table.getName(symbol_table.getID(eEndogenous, i)) - << " matched with equation " << (mate_map[i]-n+1) << endl; -#endif - - // Create the resulting map, by copying the n first elements of mate_map, and substracting n to them - endo2eq.resize(equations.size()); - transform(mate_map.begin(), mate_map.begin() + n, endo2eq.begin(), bind2nd(minus(), n)); - -#ifdef DEBUG - multimap natural_endo2eqs; - computeNormalizedEquations(natural_endo2eqs); - - int n1 = 0, n2 = 0; - - for (int i = 0; i < symbol_table.endo_nbr(); i++) - { - if (natural_endo2eqs.count(i) == 0) - continue; - - n1++; - - pair::const_iterator, multimap::const_iterator> x = natural_endo2eqs.equal_range(i); - if (find_if(x.first, x.second, compose1(bind2nd(equal_to(), endo2eq[i]), select2nd::value_type>())) == x.second) - cout << "Natural normalization of variable " << symbol_table.getName(symbol_table.getID(eEndogenous, i)) - << " not used." << endl; - else - n2++; - } - - cout << "Used " << n2 << " natural normalizations out of " << n1 << ", for a total of " << n << " equations." << endl; -#endif - - // Check if all variables are normalized - vector::const_iterator it = find(mate_map.begin(), mate_map.begin() + n, graph_traits::null_vertex()); - if (it != mate_map.begin() + n) - { - if (verbose) - cerr << "ERROR: Could not normalize the model. Variable " - << symbol_table.getName(symbol_table.getID(eEndogenous, it - mate_map.begin())) - << " is not in the maximum cardinality matching." << endl; - check = false; - } - return check; -} - -void -ModelTree::computeNonSingularNormalization(jacob_map_t &contemporaneous_jacobian, double cutoff, jacob_map_t &static_jacobian, dynamic_jacob_map_t &dynamic_jacobian) -{ - bool check = false; - - cout << "Normalizing the model..." << endl; - - int n = equations.size(); - - // compute the maximum value of each row of the contemporaneous Jacobian matrix - //jacob_map normalized_contemporaneous_jacobian; - jacob_map_t normalized_contemporaneous_jacobian(contemporaneous_jacobian); - vector max_val(n, 0.0); - for (jacob_map_t::const_iterator iter = contemporaneous_jacobian.begin(); iter != contemporaneous_jacobian.end(); iter++) - if (fabs(iter->second) > max_val[iter->first.first]) - max_val[iter->first.first] = fabs(iter->second); - - for (jacob_map_t::iterator iter = normalized_contemporaneous_jacobian.begin(); iter != normalized_contemporaneous_jacobian.end(); iter++) - iter->second /= max_val[iter->first.first]; - - //We start with the highest value of the cutoff and try to normalize the model - double current_cutoff = 0.99999999; - - int suppressed = 0; - while (!check && current_cutoff > 1e-19) - { - jacob_map_t tmp_normalized_contemporaneous_jacobian; - int suppress = 0; - for (jacob_map_t::iterator iter = normalized_contemporaneous_jacobian.begin(); iter != normalized_contemporaneous_jacobian.end(); iter++) - if (fabs(iter->second) > max(current_cutoff, cutoff)) - tmp_normalized_contemporaneous_jacobian[make_pair(iter->first.first, iter->first.second)] = iter->second; - else - suppress++; - - if (suppress != suppressed) - check = computeNormalization(tmp_normalized_contemporaneous_jacobian, false); - suppressed = suppress; - if (!check) - { - current_cutoff /= 2; - // In this last case try to normalize with the complete jacobian - if (current_cutoff <= 1e-19) - check = computeNormalization(normalized_contemporaneous_jacobian, false); - } - } - - if (!check) - { - cout << "Normalization failed with cutoff, trying symbolic normalization..." << endl; - //if no non-singular normalization can be found, try to find a normalization even with a potential singularity - jacob_map_t tmp_normalized_contemporaneous_jacobian; - set > endo; - for (int i = 0; i < n; i++) - { - endo.clear(); - equations[i]->collectEndogenous(endo); - for (set >::const_iterator it = endo.begin(); it != endo.end(); it++) - tmp_normalized_contemporaneous_jacobian[make_pair(i, it->first)] = 1; - } - check = computeNormalization(tmp_normalized_contemporaneous_jacobian, true); - if (check) - { - // Update the jacobian matrix - for (jacob_map_t::const_iterator it = tmp_normalized_contemporaneous_jacobian.begin(); it != tmp_normalized_contemporaneous_jacobian.end(); it++) - { - if (static_jacobian.find(make_pair(it->first.first, it->first.second)) == static_jacobian.end()) - static_jacobian[make_pair(it->first.first, it->first.second)] = 0; - if (dynamic_jacobian.find(make_pair(0, make_pair(it->first.first, it->first.second))) == dynamic_jacobian.end()) - dynamic_jacobian[make_pair(0, make_pair(it->first.first, it->first.second))] = 0; - if (contemporaneous_jacobian.find(make_pair(it->first.first, it->first.second)) == contemporaneous_jacobian.end()) - contemporaneous_jacobian[make_pair(it->first.first, it->first.second)] = 0; - try - { - if (first_derivatives.find(make_pair(it->first.first, getDerivID(symbol_table.getID(eEndogenous, it->first.second), 0))) == first_derivatives.end()) - first_derivatives[make_pair(it->first.first, getDerivID(symbol_table.getID(eEndogenous, it->first.second), 0))] = Zero; - } - catch (DataTree::UnknownDerivIDException &e) - { - cerr << "The variable " << symbol_table.getName(symbol_table.getID(eEndogenous, it->first.second)) - << " does not appear at the current period (i.e. with no lead and no lag); this case is not handled by the 'block' option of the 'model' block." << endl; - exit(EXIT_FAILURE); - } - } - } - } - - if (!check) - { - cerr << "No normalization could be computed. Aborting." << endl; - exit(EXIT_FAILURE); - } -} - -void -ModelTree::computeNormalizedEquations(multimap &endo2eqs) const -{ - for (size_t i = 0; i < equations.size(); i++) - { - VariableNode *lhs = dynamic_cast(equations[i]->get_arg1()); - if (lhs == NULL) - continue; - - int symb_id = lhs->get_symb_id(); - if (symbol_table.getType(symb_id) != eEndogenous) - continue; - - set > endo; - equations[i]->get_arg2()->collectEndogenous(endo); - if (endo.find(make_pair(symbol_table.getTypeSpecificID(symb_id), 0)) != endo.end()) - continue; - - endo2eqs.insert(make_pair(symbol_table.getTypeSpecificID(symb_id), (int) i)); - cout << "Endogenous " << symbol_table.getName(symb_id) << " normalized in equation " << (i+1) << endl; - } -} - -void -ModelTree::evaluateAndReduceJacobian(const eval_context_t &eval_context, jacob_map_t &contemporaneous_jacobian, jacob_map_t &static_jacobian, dynamic_jacob_map_t &dynamic_jacobian, double cutoff, bool verbose) -{ - int nb_elements_contemparenous_Jacobian = 0; - set > jacobian_elements_to_delete; - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - int deriv_id = it->first.second; - if (getTypeByDerivID(deriv_id) == eEndogenous) - { - expr_t Id = it->second; - int eq = it->first.first; - int symb = getSymbIDByDerivID(deriv_id); - int var = symbol_table.getTypeSpecificID(symb); - int lag = getLagByDerivID(deriv_id); - double val = 0; - try - { - val = Id->eval(eval_context); - } - catch (ExprNode::EvalExternalFunctionException &e) - { - val = 1; - } - catch (ExprNode::EvalException &e) - { - cerr << "ERROR: evaluation of Jacobian failed for equation " << eq+1 << " (line " << equations_lineno[eq] << ") and variable " << symbol_table.getName(symb) << "(" << lag << ") [" << symb << "] !" << endl; - Id->writeOutput(cerr, oMatlabDynamicModelSparse, temporary_terms); - cerr << endl; - exit(EXIT_FAILURE); - } - if (fabs(val) < cutoff) - { - if (verbose) - cout << "the coefficient related to variable " << var << " with lag " << lag << " in equation " << eq << " is equal to " << val << " and is set to 0 in the incidence matrix (size=" << symbol_table.endo_nbr() << ")" << endl; - jacobian_elements_to_delete.insert(make_pair(eq, deriv_id)); - } - else - { - if (lag == 0) - { - nb_elements_contemparenous_Jacobian++; - contemporaneous_jacobian[make_pair(eq, var)] = val; - } - if (static_jacobian.find(make_pair(eq, var)) != static_jacobian.end()) - static_jacobian[make_pair(eq, var)] += val; - else - static_jacobian[make_pair(eq, var)] = val; - dynamic_jacobian[make_pair(lag, make_pair(eq, var))] = Id; - } - } - } - - // Get rid of the elements of the Jacobian matrix below the cutoff - for (set >::const_iterator it = jacobian_elements_to_delete.begin(); it != jacobian_elements_to_delete.end(); it++) - first_derivatives.erase(*it); - - if (jacobian_elements_to_delete.size() > 0) - { - cout << jacobian_elements_to_delete.size() << " elements among " << first_derivatives.size() << " in the incidence matrices are below the cutoff (" << cutoff << ") and are discarded" << endl - << "The contemporaneous incidence matrix has " << nb_elements_contemparenous_Jacobian << " elements" << endl; - } -} - -void -ModelTree::computePrologueAndEpilogue(const jacob_map_t &static_jacobian_arg, vector &equation_reordered, vector &variable_reordered) -{ - vector eq2endo(equations.size(), 0); - equation_reordered.resize(equations.size()); - variable_reordered.resize(equations.size()); - bool *IM; - int n = equations.size(); - IM = (bool *) calloc(n*n, sizeof(bool)); - int i = 0; - for (vector::const_iterator it = endo2eq.begin(); it != endo2eq.end(); it++, i++) - { - eq2endo[*it] = i; - equation_reordered[i] = i; - variable_reordered[*it] = i; - } - if (cutoff == 0) - { - set > endo; - for (int i = 0; i < n; i++) - { - endo.clear(); - equations[i]->collectEndogenous(endo); - for (set >::const_iterator it = endo.begin(); it != endo.end(); it++) - IM[i * n + endo2eq[it->first]] = true; - } - } - else - for (jacob_map_t::const_iterator it = static_jacobian_arg.begin(); it != static_jacobian_arg.end(); it++) - IM[it->first.first * n + endo2eq[it->first.second]] = true; - bool something_has_been_done = true; - prologue = 0; - int k = 0; - // Find the prologue equations and place first the AR(1) shock equations first - while (something_has_been_done) - { - int tmp_prologue = prologue; - something_has_been_done = false; - for (int i = prologue; i < n; i++) - { - int nze = 0; - for (int j = tmp_prologue; j < n; j++) - if (IM[i * n + j]) - { - nze++; - k = j; - } - if (nze == 1) - { - for (int j = 0; j < n; j++) - { - bool tmp_bool = IM[tmp_prologue * n + j]; - IM[tmp_prologue * n + j] = IM[i * n + j]; - IM[i * n + j] = tmp_bool; - } - int tmp = equation_reordered[tmp_prologue]; - equation_reordered[tmp_prologue] = equation_reordered[i]; - equation_reordered[i] = tmp; - for (int j = 0; j < n; j++) - { - bool tmp_bool = IM[j * n + tmp_prologue]; - IM[j * n + tmp_prologue] = IM[j * n + k]; - IM[j * n + k] = tmp_bool; - } - tmp = variable_reordered[tmp_prologue]; - variable_reordered[tmp_prologue] = variable_reordered[k]; - variable_reordered[k] = tmp; - tmp_prologue++; - something_has_been_done = true; - } - } - prologue = tmp_prologue; - } - - something_has_been_done = true; - epilogue = 0; - // Find the epilogue equations - while (something_has_been_done) - { - int tmp_epilogue = epilogue; - something_has_been_done = false; - for (int i = prologue; i < n - (int) epilogue; i++) - { - int nze = 0; - for (int j = prologue; j < n - tmp_epilogue; j++) - if (IM[j * n + i]) - { - nze++; - k = j; - } - if (nze == 1) - { - for (int j = 0; j < n; j++) - { - bool tmp_bool = IM[(n - 1 - tmp_epilogue) * n + j]; - IM[(n - 1 - tmp_epilogue) * n + j] = IM[k * n + j]; - IM[k * n + j] = tmp_bool; - } - int tmp = equation_reordered[n - 1 - tmp_epilogue]; - equation_reordered[n - 1 - tmp_epilogue] = equation_reordered[k]; - equation_reordered[k] = tmp; - for (int j = 0; j < n; j++) - { - bool tmp_bool = IM[j * n + n - 1 - tmp_epilogue]; - IM[j * n + n - 1 - tmp_epilogue] = IM[j * n + i]; - IM[j * n + i] = tmp_bool; - } - tmp = variable_reordered[n - 1 - tmp_epilogue]; - variable_reordered[n - 1 - tmp_epilogue] = variable_reordered[i]; - variable_reordered[i] = tmp; - tmp_epilogue++; - something_has_been_done = true; - } - } - epilogue = tmp_epilogue; - } - free(IM); -} - -equation_type_and_normalized_equation_t -ModelTree::equationTypeDetermination(const map >, expr_t> &first_order_endo_derivatives, const vector &Index_Var_IM, const vector &Index_Equ_IM, int mfs) const -{ - expr_t lhs; - BinaryOpNode *eq_node; - EquationType Equation_Simulation_Type; - equation_type_and_normalized_equation_t V_Equation_Simulation_Type(equations.size()); - for (unsigned int i = 0; i < equations.size(); i++) - { - int eq = Index_Equ_IM[i]; - int var = Index_Var_IM[i]; - eq_node = equations[eq]; - lhs = eq_node->get_arg1(); - Equation_Simulation_Type = E_SOLVE; - map >, expr_t>::const_iterator derivative = first_order_endo_derivatives.find(make_pair(eq, make_pair(var, 0))); - pair res; - if (derivative != first_order_endo_derivatives.end()) - { - set > result; - derivative->second->collectEndogenous(result); - set >::const_iterator d_endo_variable = result.find(make_pair(var, 0)); - //Determine whether the equation could be evaluated rather than to be solved - if (lhs->isVariableNodeEqualTo(eEndogenous, Index_Var_IM[i], 0) && derivative->second->isNumConstNodeEqualTo(1)) - { - Equation_Simulation_Type = E_EVALUATE; - } - else - { - vector > > List_of_Op_RHS; - res = equations[eq]->normalizeEquation(var, List_of_Op_RHS); - if (mfs == 2) - { - if (d_endo_variable == result.end() && res.second) - Equation_Simulation_Type = E_EVALUATE_S; - } - else if (mfs == 3) - { - if (res.second) // The equation could be solved analytically - Equation_Simulation_Type = E_EVALUATE_S; - } - } - } - V_Equation_Simulation_Type[eq] = make_pair(Equation_Simulation_Type, dynamic_cast(res.second)); - } - return (V_Equation_Simulation_Type); -} - -void -ModelTree::getVariableLeadLagByBlock(const dynamic_jacob_map_t &dynamic_jacobian, const vector &components_set, int nb_blck_sim, lag_lead_vector_t &equation_lead_lag, lag_lead_vector_t &variable_lead_lag, const vector &equation_reordered, const vector &variable_reordered) const -{ - int nb_endo = symbol_table.endo_nbr(); - variable_lead_lag = lag_lead_vector_t(nb_endo, make_pair(0, 0)); - equation_lead_lag = lag_lead_vector_t(nb_endo, make_pair(0, 0)); - vector variable_blck(nb_endo), equation_blck(nb_endo); - for (int i = 0; i < nb_endo; i++) - { - if (i < (int) prologue) - { - variable_blck[variable_reordered[i]] = i; - equation_blck[equation_reordered[i]] = i; - } - else if (i < (int) (components_set.size() + prologue)) - { - variable_blck[variable_reordered[i]] = components_set[i-prologue] + prologue; - equation_blck[equation_reordered[i]] = components_set[i-prologue] + prologue; - } - else - { - variable_blck[variable_reordered[i]] = i- (nb_endo - nb_blck_sim - prologue - epilogue); - equation_blck[equation_reordered[i]] = i- (nb_endo - nb_blck_sim - prologue - epilogue); - } - } - for (dynamic_jacob_map_t::const_iterator it = dynamic_jacobian.begin(); it != dynamic_jacobian.end(); it++) - { - int lag = it->first.first; - int j_1 = it->first.second.first; - int i_1 = it->first.second.second; - if (variable_blck[i_1] == equation_blck[j_1]) - { - if (lag > variable_lead_lag[i_1].second) - variable_lead_lag[i_1] = make_pair(variable_lead_lag[i_1].first, lag); - if (lag < -variable_lead_lag[i_1].first) - variable_lead_lag[i_1] = make_pair(-lag, variable_lead_lag[i_1].second); - if (lag > equation_lead_lag[j_1].second) - equation_lead_lag[j_1] = make_pair(equation_lead_lag[j_1].first, lag); - if (lag < -equation_lead_lag[j_1].first) - equation_lead_lag[j_1] = make_pair(-lag, equation_lead_lag[j_1].second); - } - } -} - -void -ModelTree::computeBlockDecompositionAndFeedbackVariablesForEachBlock(const jacob_map_t &static_jacobian, const dynamic_jacob_map_t &dynamic_jacobian, vector &equation_reordered, vector &variable_reordered, vector > &blocks, const equation_type_and_normalized_equation_t &Equation_Type, bool verbose_, bool select_feedback_variable, int mfs, vector &inv_equation_reordered, vector &inv_variable_reordered, lag_lead_vector_t &equation_lag_lead, lag_lead_vector_t &variable_lag_lead, vector &n_static, vector &n_forward, vector &n_backward, vector &n_mixed) const -{ - int nb_var = variable_reordered.size(); - int n = nb_var - prologue - epilogue; - - AdjacencyList_t G2(n); - - // It is necessary to manually initialize vertex_index property since this graph uses listS and not vecS as underlying vertex container - property_map::type v_index = get(vertex_index, G2); - for (int i = 0; i < n; i++) - put(v_index, vertex(i, G2), i); - - vector reverse_equation_reordered(nb_var), reverse_variable_reordered(nb_var); - - for (int i = 0; i < nb_var; i++) - { - reverse_equation_reordered[equation_reordered[i]] = i; - reverse_variable_reordered[variable_reordered[i]] = i; - } - jacob_map_t tmp_normalized_contemporaneous_jacobian; - if (cutoff == 0) - { - set > endo; - for (int i = 0; i < nb_var; i++) - { - endo.clear(); - equations[i]->collectEndogenous(endo); - for (set >::const_iterator it = endo.begin(); it != endo.end(); it++) - tmp_normalized_contemporaneous_jacobian[make_pair(i, it->first)] = 1; - - } - } - else - tmp_normalized_contemporaneous_jacobian = static_jacobian; - for (jacob_map_t::const_iterator it = tmp_normalized_contemporaneous_jacobian.begin(); it != tmp_normalized_contemporaneous_jacobian.end(); it++) - if (reverse_equation_reordered[it->first.first] >= (int) prologue && reverse_equation_reordered[it->first.first] < (int) (nb_var - epilogue) - && reverse_variable_reordered[it->first.second] >= (int) prologue && reverse_variable_reordered[it->first.second] < (int) (nb_var - epilogue) - && it->first.first != endo2eq[it->first.second]) - add_edge(vertex(reverse_equation_reordered[endo2eq[it->first.second]]-prologue, G2), - vertex(reverse_equation_reordered[it->first.first]-prologue, G2), - G2); - - vector endo2block(num_vertices(G2)), discover_time(num_vertices(G2)); - iterator_property_map::type, int, int &> endo2block_map(&endo2block[0], get(vertex_index, G2)); - - // Compute strongly connected components - int num = strong_components(G2, endo2block_map); - - blocks = vector >(num, make_pair(0, 0)); - - // Create directed acyclic graph associated to the strongly connected components - typedef adjacency_list DirectedGraph; - DirectedGraph dag(num); - - for (unsigned int i = 0; i < num_vertices(G2); i++) - { - AdjacencyList_t::out_edge_iterator it_out, out_end; - AdjacencyList_t::vertex_descriptor vi = vertex(i, G2); - for (tie(it_out, out_end) = out_edges(vi, G2); it_out != out_end; ++it_out) - { - int t_b = endo2block_map[target(*it_out, G2)]; - int s_b = endo2block_map[source(*it_out, G2)]; - if (s_b != t_b) - add_edge(s_b, t_b, dag); - } - } - - // Compute topological sort of DAG (ordered list of unordered SCC) - deque ordered2unordered; - topological_sort(dag, front_inserter(ordered2unordered)); // We use a front inserter because topological_sort returns the inverse order - - // Construct mapping from unordered SCC to ordered SCC - vector unordered2ordered(num); - for (int i = 0; i < num; i++) - unordered2ordered[ordered2unordered[i]] = i; - - //This vector contains for each block: - // - first set = equations belonging to the block, - // - second set = the feeback variables, - // - third vector = the reordered non-feedback variables. - vector, pair, vector > > > components_set(num); - for (unsigned int i = 0; i < endo2block.size(); i++) - { - endo2block[i] = unordered2ordered[endo2block[i]]; - blocks[endo2block[i]].first++; - components_set[endo2block[i]].first.insert(i); - } - - getVariableLeadLagByBlock(dynamic_jacobian, endo2block, num, equation_lag_lead, variable_lag_lead, equation_reordered, variable_reordered); - - vector tmp_equation_reordered(equation_reordered), tmp_variable_reordered(variable_reordered); - int order = prologue; - //Add a loop on vertices which could not be normalized or vertices related to lead variables => force those vertices to belong to the feedback set - if (select_feedback_variable) - { - for (int i = 0; i < n; i++) - if (Equation_Type[equation_reordered[i+prologue]].first == E_SOLVE - || variable_lag_lead[variable_reordered[i+prologue]].second > 0 - || variable_lag_lead[variable_reordered[i+prologue]].first > 0 - || equation_lag_lead[equation_reordered[i+prologue]].second > 0 - || equation_lag_lead[equation_reordered[i+prologue]].first > 0 - || mfs == 0) - add_edge(vertex(i, G2), vertex(i, G2), G2); - } - else - { - for (int i = 0; i < n; i++) - if (Equation_Type[equation_reordered[i+prologue]].first == E_SOLVE || mfs == 0) - add_edge(vertex(i, G2), vertex(i, G2), G2); - } - //Determines the dynamic structure of each equation - n_static = vector(prologue+num+epilogue, 0); - n_forward = vector(prologue+num+epilogue, 0); - n_backward = vector(prologue+num+epilogue, 0); - n_mixed = vector(prologue+num+epilogue, 0); - - for (int i = 0; i < (int) prologue; i++) - { - if (variable_lag_lead[tmp_variable_reordered[i]].first != 0 && variable_lag_lead[tmp_variable_reordered[i]].second != 0) - n_mixed[i]++; - else if (variable_lag_lead[tmp_variable_reordered[i]].first == 0 && variable_lag_lead[tmp_variable_reordered[i]].second != 0) - n_forward[i]++; - else if (variable_lag_lead[tmp_variable_reordered[i]].first != 0 && variable_lag_lead[tmp_variable_reordered[i]].second == 0) - n_backward[i]++; - else if (variable_lag_lead[tmp_variable_reordered[i]].first == 0 && variable_lag_lead[tmp_variable_reordered[i]].second == 0) - n_static[i]++; - } - //For each block, the minimum set of feedback variable is computed - // and the non-feedback variables are reordered to get - // a sub-recursive block without feedback variables - - for (int i = 0; i < num; i++) - { - AdjacencyList_t G = extract_subgraph(G2, components_set[i].first); - set feed_back_vertices; - //Print(G); - AdjacencyList_t G1 = Minimal_set_of_feedback_vertex(feed_back_vertices, G); - property_map::type v_index = get(vertex_index, G); - components_set[i].second.first = feed_back_vertices; - blocks[i].second = feed_back_vertices.size(); - vector Reordered_Vertice; - Reorder_the_recursive_variables(G, feed_back_vertices, Reordered_Vertice); - - //First we have the recursive equations conditional on feedback variables - for (int j = 0; j < 4; j++) - { - for (vector::iterator its = Reordered_Vertice.begin(); its != Reordered_Vertice.end(); its++) - { - bool something_done = false; - if (j == 2 && variable_lag_lead[tmp_variable_reordered[*its +prologue]].first != 0 && variable_lag_lead[tmp_variable_reordered[*its +prologue]].second != 0) - { - n_mixed[prologue+i]++; - something_done = true; - } - else if (j == 3 && variable_lag_lead[tmp_variable_reordered[*its +prologue]].first == 0 && variable_lag_lead[tmp_variable_reordered[*its +prologue]].second != 0) - { - n_forward[prologue+i]++; - something_done = true; - } - else if (j == 1 && variable_lag_lead[tmp_variable_reordered[*its +prologue]].first != 0 && variable_lag_lead[tmp_variable_reordered[*its +prologue]].second == 0) - { - n_backward[prologue+i]++; - something_done = true; - } - else if (j == 0 && variable_lag_lead[tmp_variable_reordered[*its +prologue]].first == 0 && variable_lag_lead[tmp_variable_reordered[*its +prologue]].second == 0) - { - n_static[prologue+i]++; - something_done = true; - } - if (something_done) - { - equation_reordered[order] = tmp_equation_reordered[*its+prologue]; - variable_reordered[order] = tmp_variable_reordered[*its+prologue]; - order++; - } - } - } - components_set[i].second.second = Reordered_Vertice; - //Second we have the equations related to the feedback variables - for (int j = 0; j < 4; j++) - { - for (set::iterator its = feed_back_vertices.begin(); its != feed_back_vertices.end(); its++) - { - bool something_done = false; - if (j == 2 && variable_lag_lead[tmp_variable_reordered[v_index[vertex(*its, G)]+prologue]].first != 0 && variable_lag_lead[tmp_variable_reordered[v_index[vertex(*its, G)]+prologue]].second != 0) - { - n_mixed[prologue+i]++; - something_done = true; - } - else if (j == 3 && variable_lag_lead[tmp_variable_reordered[v_index[vertex(*its, G)]+prologue]].first == 0 && variable_lag_lead[tmp_variable_reordered[v_index[vertex(*its, G)]+prologue]].second != 0) - { - n_forward[prologue+i]++; - something_done = true; - } - else if (j == 1 && variable_lag_lead[tmp_variable_reordered[v_index[vertex(*its, G)]+prologue]].first != 0 && variable_lag_lead[tmp_variable_reordered[v_index[vertex(*its, G)]+prologue]].second == 0) - { - n_backward[prologue+i]++; - something_done = true; - } - else if (j == 0 && variable_lag_lead[tmp_variable_reordered[v_index[vertex(*its, G)]+prologue]].first == 0 && variable_lag_lead[tmp_variable_reordered[v_index[vertex(*its, G)]+prologue]].second == 0) - { - n_static[prologue+i]++; - something_done = true; - } - if (something_done) - { - equation_reordered[order] = tmp_equation_reordered[v_index[vertex(*its, G)]+prologue]; - variable_reordered[order] = tmp_variable_reordered[v_index[vertex(*its, G)]+prologue]; - order++; - } - } - } - } - - for (int i = 0; i < (int) epilogue; i++) - { - if (variable_lag_lead[tmp_variable_reordered[prologue+n+i]].first != 0 && variable_lag_lead[tmp_variable_reordered[prologue+n+i]].second != 0) - n_mixed[prologue+num+i]++; - else if (variable_lag_lead[tmp_variable_reordered[prologue+n+i]].first == 0 && variable_lag_lead[tmp_variable_reordered[prologue+n+i]].second != 0) - n_forward[prologue+num+i]++; - else if (variable_lag_lead[tmp_variable_reordered[prologue+n+i]].first != 0 && variable_lag_lead[tmp_variable_reordered[prologue+n+i]].second == 0) - n_backward[prologue+num+i]++; - else if (variable_lag_lead[tmp_variable_reordered[prologue+n+i]].first == 0 && variable_lag_lead[tmp_variable_reordered[prologue+n+i]].second == 0) - n_static[prologue+num+i]++; - } - - inv_equation_reordered = vector(nb_var); - inv_variable_reordered = vector(nb_var); - for (int i = 0; i < nb_var; i++) - { - inv_variable_reordered[variable_reordered[i]] = i; - inv_equation_reordered[equation_reordered[i]] = i; - } -} - -void -ModelTree::printBlockDecomposition(const vector > &blocks) const -{ - int largest_block = 0; - int Nb_SimulBlocks = 0; - int Nb_feedback_variable = 0; - unsigned int Nb_TotalBlocks = getNbBlocks(); - for (unsigned int block = 0; block < Nb_TotalBlocks; block++) - { - BlockSimulationType simulation_type = getBlockSimulationType(block); - if (simulation_type == SOLVE_FORWARD_COMPLETE || simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE) - { - Nb_SimulBlocks++; - int size = getBlockSize(block); - if (size > largest_block) - { - largest_block = size; - Nb_feedback_variable = getBlockMfs(block); - } - } - } - - int Nb_RecursBlocks = Nb_TotalBlocks - Nb_SimulBlocks; - cout << Nb_TotalBlocks << " block(s) found:" << endl - << " " << Nb_RecursBlocks << " recursive block(s) and " << Nb_SimulBlocks << " simultaneous block(s)." << endl - << " the largest simultaneous block has " << largest_block << " equation(s)" << endl - << " and " << Nb_feedback_variable << " feedback variable(s)." << endl; -} - -block_type_firstequation_size_mfs_t -ModelTree::reduceBlocksAndTypeDetermination(const dynamic_jacob_map_t &dynamic_jacobian, vector > &blocks, const equation_type_and_normalized_equation_t &Equation_Type, const vector &variable_reordered, const vector &equation_reordered, vector &n_static, vector &n_forward, vector &n_backward, vector &n_mixed, vector, pair > > &block_col_type) -{ - int i = 0; - int count_equ = 0, blck_count_simult = 0; - int Blck_Size, MFS_Size; - int Lead, Lag; - block_type_firstequation_size_mfs_t block_type_size_mfs; - BlockSimulationType Simulation_Type, prev_Type = UNKNOWN; - int eq = 0; - unsigned int l_n_static = 0; - unsigned int l_n_forward = 0; - unsigned int l_n_backward = 0; - unsigned int l_n_mixed = 0; - for (i = 0; i < (int) (prologue+blocks.size()+epilogue); i++) - { - int first_count_equ = count_equ; - if (i < (int) prologue) - { - Blck_Size = 1; - MFS_Size = 1; - } - else if (i < (int) (prologue+blocks.size())) - { - Blck_Size = blocks[blck_count_simult].first; - MFS_Size = blocks[blck_count_simult].second; - blck_count_simult++; - } - else if (i < (int) (prologue+blocks.size()+epilogue)) - { - Blck_Size = 1; - MFS_Size = 1; - } - - Lag = Lead = 0; - set > endo; - for (count_equ = first_count_equ; count_equ < Blck_Size+first_count_equ; count_equ++) - { - endo.clear(); - equations[equation_reordered[count_equ]]->collectEndogenous(endo); - for (set >::const_iterator it = endo.begin(); it != endo.end(); it++) - { - int curr_variable = it->first; - int curr_lag = it->second; - vector::const_iterator it1 = find(variable_reordered.begin()+first_count_equ, variable_reordered.begin()+(first_count_equ+Blck_Size), curr_variable); - if (it1 != variable_reordered.begin()+(first_count_equ+Blck_Size)) - if (dynamic_jacobian.find(make_pair(curr_lag, make_pair(equation_reordered[count_equ], curr_variable))) != dynamic_jacobian.end()) - { - if (curr_lag > Lead) - Lead = curr_lag; - else if (-curr_lag > Lag) - Lag = -curr_lag; - } - } - } - if ((Lag > 0) && (Lead > 0)) - { - if (Blck_Size == 1) - Simulation_Type = SOLVE_TWO_BOUNDARIES_SIMPLE; - else - Simulation_Type = SOLVE_TWO_BOUNDARIES_COMPLETE; - } - else if (Blck_Size > 1) - { - if (Lead > 0) - Simulation_Type = SOLVE_BACKWARD_COMPLETE; - else - Simulation_Type = SOLVE_FORWARD_COMPLETE; - } - else - { - if (Lead > 0) - Simulation_Type = SOLVE_BACKWARD_SIMPLE; - else - Simulation_Type = SOLVE_FORWARD_SIMPLE; - } - l_n_static = n_static[i]; - l_n_forward = n_forward[i]; - l_n_backward = n_backward[i]; - l_n_mixed = n_mixed[i]; - if (Blck_Size == 1) - { - if (Equation_Type[equation_reordered[eq]].first == E_EVALUATE || Equation_Type[equation_reordered[eq]].first == E_EVALUATE_S) - { - if (Simulation_Type == SOLVE_BACKWARD_SIMPLE) - Simulation_Type = EVALUATE_BACKWARD; - else if (Simulation_Type == SOLVE_FORWARD_SIMPLE) - Simulation_Type = EVALUATE_FORWARD; - } - if (i > 0) - { - bool is_lead = false, is_lag = false; - int c_Size = (block_type_size_mfs[block_type_size_mfs.size()-1]).second.first; - int first_equation = (block_type_size_mfs[block_type_size_mfs.size()-1]).first.second; - if (c_Size > 0 && ((prev_Type == EVALUATE_FORWARD && Simulation_Type == EVALUATE_FORWARD && !is_lead) - || (prev_Type == EVALUATE_BACKWARD && Simulation_Type == EVALUATE_BACKWARD && !is_lag))) - { - for (int j = first_equation; j < first_equation+c_Size; j++) - { - dynamic_jacob_map_t::const_iterator it = dynamic_jacobian.find(make_pair(-1, make_pair(equation_reordered[eq], variable_reordered[j]))); - if (it != dynamic_jacobian.end()) - is_lag = true; - it = dynamic_jacobian.find(make_pair(+1, make_pair(equation_reordered[eq], variable_reordered[j]))); - if (it != dynamic_jacobian.end()) - is_lead = true; - } - } - if ((prev_Type == EVALUATE_FORWARD && Simulation_Type == EVALUATE_FORWARD && !is_lead) - || (prev_Type == EVALUATE_BACKWARD && Simulation_Type == EVALUATE_BACKWARD && !is_lag)) - { - //merge the current block with the previous one - BlockSimulationType c_Type = (block_type_size_mfs[block_type_size_mfs.size()-1]).first.first; - c_Size++; - block_type_size_mfs[block_type_size_mfs.size()-1] = make_pair(make_pair(c_Type, first_equation), make_pair(c_Size, c_Size)); - if (block_lag_lead[block_type_size_mfs.size()-1].first > Lag) - Lag = block_lag_lead[block_type_size_mfs.size()-1].first; - if (block_lag_lead[block_type_size_mfs.size()-1].second > Lead) - Lead = block_lag_lead[block_type_size_mfs.size()-1].second; - block_lag_lead[block_type_size_mfs.size()-1] = make_pair(Lag, Lead); - pair< pair< unsigned int, unsigned int>, pair > tmp = block_col_type[block_col_type.size()-1]; - block_col_type[block_col_type.size()-1] = make_pair(make_pair(tmp.first.first+l_n_static, tmp.first.second+l_n_forward), make_pair(tmp.second.first+l_n_backward, tmp.second.second+l_n_mixed)); - } - else - { - block_type_size_mfs.push_back(make_pair(make_pair(Simulation_Type, eq), make_pair(Blck_Size, MFS_Size))); - block_lag_lead.push_back(make_pair(Lag, Lead)); - block_col_type.push_back(make_pair(make_pair(l_n_static, l_n_forward), make_pair(l_n_backward, l_n_mixed))); - } - } - else - { - block_type_size_mfs.push_back(make_pair(make_pair(Simulation_Type, eq), make_pair(Blck_Size, MFS_Size))); - block_lag_lead.push_back(make_pair(Lag, Lead)); - block_col_type.push_back(make_pair(make_pair(l_n_static, l_n_forward), make_pair(l_n_backward, l_n_mixed))); - } - } - else - { - block_type_size_mfs.push_back(make_pair(make_pair(Simulation_Type, eq), make_pair(Blck_Size, MFS_Size))); - block_lag_lead.push_back(make_pair(Lag, Lead)); - block_col_type.push_back(make_pair(make_pair(l_n_static, l_n_forward), make_pair(l_n_backward, l_n_mixed))); - } - prev_Type = Simulation_Type; - eq += Blck_Size; - } - return (block_type_size_mfs); -} - -vector -ModelTree::BlockLinear(const blocks_derivatives_t &blocks_derivatives, const vector &variable_reordered) const -{ - unsigned int nb_blocks = getNbBlocks(); - vector blocks_linear(nb_blocks, true); - for (unsigned int block = 0; block < nb_blocks; block++) - { - BlockSimulationType simulation_type = getBlockSimulationType(block); - int block_size = getBlockSize(block); - block_derivatives_equation_variable_laglead_nodeid_t derivatives_block = blocks_derivatives[block]; - int first_variable_position = getBlockFirstEquation(block); - if (simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_FORWARD_COMPLETE) - { - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = derivatives_block.begin(); it != derivatives_block.end(); it++) - { - int lag = it->second.first; - if (lag == 0) - { - expr_t Id = it->second.second; - set > endogenous; - Id->collectEndogenous(endogenous); - if (endogenous.size() > 0) - { - for (int l = 0; l < block_size; l++) - { - if (endogenous.find(make_pair(variable_reordered[first_variable_position+l], 0)) != endogenous.end()) - { - blocks_linear[block] = false; - goto the_end; - } - } - } - } - } - } - else if (simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE) - { - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = derivatives_block.begin(); it != derivatives_block.end(); it++) - { - int lag = it->second.first; - expr_t Id = it->second.second; // - set > endogenous; - Id->collectEndogenous(endogenous); - if (endogenous.size() > 0) - { - for (int l = 0; l < block_size; l++) - { - if (endogenous.find(make_pair(variable_reordered[first_variable_position+l], lag)) != endogenous.end()) - { - blocks_linear[block] = false; - goto the_end; - } - } - } - } - } - the_end: - ; - } - return (blocks_linear); -} - -ModelTree::ModelTree(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg) : - DataTree(symbol_table_arg, num_constants_arg, external_functions_table_arg), - cutoff(1e-15), - mfs(0) - -{ - for (int i = 0; i < 3; i++) - NNZDerivatives[i] = 0; -} - -int -ModelTree::equation_number() const -{ - return (equations.size()); -} - -void -ModelTree::writeDerivative(ostream &output, int eq, int symb_id, int lag, - ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms) const -{ - first_derivatives_t::const_iterator it = first_derivatives.find(make_pair(eq, getDerivID(symb_id, lag))); - if (it != first_derivatives.end()) - (it->second)->writeOutput(output, output_type, temporary_terms); - else - output << 0; -} - -void -ModelTree::computeJacobian(const set &vars) -{ - for (set::const_iterator it = vars.begin(); - it != vars.end(); it++) - { - for (int eq = 0; eq < (int) equations.size(); eq++) - { - expr_t d1 = equations[eq]->getDerivative(*it); - if (d1 == Zero) - continue; - first_derivatives[make_pair(eq, *it)] = d1; - ++NNZDerivatives[0]; - } - } -} - -void -ModelTree::computeHessian(const set &vars) -{ - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - int eq = it->first.first; - int var1 = it->first.second; - expr_t d1 = it->second; - - // Store only second derivatives with var2 <= var1 - for (set::const_iterator it2 = vars.begin(); - it2 != vars.end(); it2++) - { - int var2 = *it2; - if (var2 > var1) - continue; - - expr_t d2 = d1->getDerivative(var2); - if (d2 == Zero) - continue; - second_derivatives[make_pair(eq, make_pair(var1, var2))] = d2; - if (var2 == var1) - ++NNZDerivatives[1]; - else - NNZDerivatives[1] += 2; - } - } -} - -void -ModelTree::computeThirdDerivatives(const set &vars) -{ - for (second_derivatives_t::const_iterator it = second_derivatives.begin(); - it != second_derivatives.end(); it++) - { - int eq = it->first.first; - - int var1 = it->first.second.first; - int var2 = it->first.second.second; - // By construction, var2 <= var1 - - expr_t d2 = it->second; - - // Store only third derivatives such that var3 <= var2 <= var1 - for (set::const_iterator it2 = vars.begin(); - it2 != vars.end(); it2++) - { - int var3 = *it2; - if (var3 > var2) - continue; - - expr_t d3 = d2->getDerivative(var3); - if (d3 == Zero) - continue; - third_derivatives[make_pair(eq, make_pair(var1, make_pair(var2, var3)))] = d3; - if (var3 == var2 && var2 == var1) - ++NNZDerivatives[2]; - else if (var3 == var2 || var2 == var1) - NNZDerivatives[2] += 3; - else - NNZDerivatives[2] += 6; - } - } -} - -void -ModelTree::computeTemporaryTerms(bool is_matlab) -{ - map > reference_count; - temporary_terms.clear(); - temporary_terms_res.clear(); - temporary_terms_g1.clear(); - temporary_terms_g2.clear(); - temporary_terms_g3.clear(); - map temp_terms_map; - temp_terms_map[eResiduals] = temporary_terms_res; - temp_terms_map[eFirstDeriv] = temporary_terms_g1; - temp_terms_map[eSecondDeriv] = temporary_terms_g2; - temp_terms_map[eThirdDeriv] = temporary_terms_g3; - - for (vector::iterator it = equations.begin(); - it != equations.end(); it++) - (*it)->computeTemporaryTerms(reference_count, - temp_terms_map, - is_matlab, eResiduals); - - for (first_derivatives_t::iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - it->second->computeTemporaryTerms(reference_count, - temp_terms_map, - is_matlab, eFirstDeriv); - - for (second_derivatives_t::iterator it = second_derivatives.begin(); - it != second_derivatives.end(); it++) - it->second->computeTemporaryTerms(reference_count, - temp_terms_map, - is_matlab, eSecondDeriv); - - for (third_derivatives_t::iterator it = third_derivatives.begin(); - it != third_derivatives.end(); it++) - it->second->computeTemporaryTerms(reference_count, - temp_terms_map, - is_matlab, eThirdDeriv); - - for (map::const_iterator it = temp_terms_map.begin(); - it != temp_terms_map.end(); it++) - temporary_terms.insert(it->second.begin(), it->second.end()); - - temporary_terms_res = temp_terms_map[eResiduals]; - temporary_terms_g1 = temp_terms_map[eFirstDeriv]; - temporary_terms_g2 = temp_terms_map[eSecondDeriv]; - temporary_terms_g3 = temp_terms_map[eThirdDeriv]; -} - -void -ModelTree::writeTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_t &ttm1, ostream &output, - ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const -{ - // Local var used to keep track of temp nodes already written - temporary_terms_t tt2 = ttm1; - for (temporary_terms_t::const_iterator it = tt.begin(); - it != tt.end(); it++) - if (ttm1.find(*it) == ttm1.end()) - { - if (dynamic_cast(*it) != NULL) - (*it)->writeExternalFunctionOutput(output, output_type, tt2, tef_terms); - - if (IS_C(output_type)) - output << "double "; - else if (IS_JULIA(output_type)) - output << " @inbounds const "; - - (*it)->writeOutput(output, output_type, tt, tef_terms); - output << " = "; - (*it)->writeOutput(output, output_type, tt2, tef_terms); - - if (IS_C(output_type) || IS_MATLAB(output_type)) - output << ";"; - output << endl; - - // Insert current node into tt2 - tt2.insert(*it); - } -} - -void -ModelTree::writeJsonTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_t &ttm1, ostream &output, - deriv_node_temp_terms_t &tef_terms, string &concat) const -{ - // Local var used to keep track of temp nodes already written - bool wrote_term = false; - temporary_terms_t tt2 = ttm1; - - output << "\"external_functions_temporary_terms_" << concat << "\": ["; - for (temporary_terms_t::const_iterator it = tt.begin(); - it != tt.end(); it++) - if (ttm1.find(*it) == ttm1.end()) - { - if (dynamic_cast(*it) != NULL) - { - if (wrote_term) - output << ", "; - vector efout; - (*it)->writeJsonExternalFunctionOutput(efout, tt2, tef_terms); - for (vector::const_iterator it1 = efout.begin(); it1 != efout.end(); it1++) - { - if (it1 != efout.begin()) - output << ", "; - output << *it1; - } - wrote_term = true; - } - tt2.insert(*it); - } - - tt2 = ttm1; - wrote_term = false; - output << "]" - << ", \"temporary_terms_" << concat << "\": ["; - for (temporary_terms_t::const_iterator it = tt.begin(); - it != tt.end(); it++) - if (ttm1.find(*it) == ttm1.end()) - { - if (wrote_term) - output << ", "; - output << "{\"temporary_term\": \""; - (*it)->writeJsonOutput(output, tt, tef_terms); - output << "\"" - << ", \"value\": \""; - (*it)->writeJsonOutput(output, tt2, tef_terms); - output << "\"}" << endl; - wrote_term = true; - - // Insert current node into tt2 - tt2.insert(*it); - } - output << "]"; -} - -void -ModelTree::fixNestedParenthesis(ostringstream &output, map &tmp_paren_vars, bool &message_printed) const -{ - string str = output.str(); - if (!testNestedParenthesis(str)) - return; - int open = 0; - int first_open_paren = 0; - int matching_paren = 0; - bool hit_limit = false; - int i1 = 0; - map::iterator it; - for (size_t i = 0; i < str.length(); i++) - { - if (str.at(i) == '(') - { - if (open == 0) - first_open_paren = i; - open++; - } - else if (str.at(i) == ')') - { - open--; - if (open == 0) - matching_paren = i; - } - if (open > 32) - hit_limit = true; - - if (hit_limit && open == 0) - { - if (!message_printed) - { - cerr << "Warning: A .m file created by Dynare will have more than 32 nested parenthesis. Matlab cannot support this. " << endl - << " We are going to modify, albeit inefficiently, this output to have fewer than 32 nested parenthesis. " << endl - << " It would hence behoove you to use the use_dll option of the model block to circumnavigate this problem." << endl - << " If you have not yet set up a compiler on your system, see the Matlab documentation for doing so." << endl - << " For Windows, see: https://www.mathworks.com/help/matlab/matlab_external/install-mingw-support-package.html" << endl << endl; - message_printed = true; - } - string str1 = str.substr(first_open_paren, matching_paren - first_open_paren + 1); - string repstr = ""; - string varname; - while (testNestedParenthesis(str1)) - { - size_t open_paren_idx = string::npos; - size_t match_paren_idx = string::npos; - size_t last_open_paren = string::npos; - for (size_t j = 0; j < str1.length(); j++) - { - if (str1.at(j) == '(') - { - // don't match, e.g. y(1) - size_t idx = str1.find_last_of("*/-+", j - 1); - if (j == 0 || (idx != string::npos && idx == j - 1)) - open_paren_idx = j; - last_open_paren = j; - } - else if (str1.at(j) == ')') - { - // don't match, e.g. y(1) - size_t idx = str1.find_last_not_of("0123456789", j - 1); - if (idx != string::npos && idx != last_open_paren) - match_paren_idx = j; - } - - if (open_paren_idx != string::npos && match_paren_idx != string::npos) - { - string val = str1.substr(open_paren_idx, match_paren_idx - open_paren_idx + 1); - it = tmp_paren_vars.find(val); - if (it == tmp_paren_vars.end()) - { - ostringstream ptvstr; - ptvstr << i1++; - varname = "paren32_tmp_var_" + ptvstr.str(); - repstr = repstr + varname + " = " + val + ";\n"; - tmp_paren_vars[val] = varname; - } - else - varname = it->second; - str1.replace(open_paren_idx, match_paren_idx - open_paren_idx + 1, varname); - break; - } - } - } - it = tmp_paren_vars.find(str1); - if (it == tmp_paren_vars.end()) - { - ostringstream ptvstr; - ptvstr << i1++; - varname = "paren32_tmp_var_" + ptvstr.str(); - repstr = repstr + varname + " = " + str1 + ";\n"; - } - else - varname = it->second; - str.replace(first_open_paren, matching_paren - first_open_paren + 1, varname); - size_t insertLoc = str.find_last_of("\n", first_open_paren); - str.insert(insertLoc + 1, repstr); - hit_limit = false; - i = -1; - first_open_paren = matching_paren = open = 0; - } - } - output.str(str); -} - -bool -ModelTree::testNestedParenthesis(const string &str) const -{ - int open = 0; - for (size_t i = 0; i < str.length(); i++) - { - if (str.at(i) == '(') - open++; - else if (str.at(i) == ')') - open--; - if (open > 32) - return true; - } - return false; -} - -void -ModelTree::compileTemporaryTerms(ostream &code_file, unsigned int &instruction_number, const temporary_terms_t &tt, map_idx_t map_idx, bool dynamic, bool steady_dynamic) const -{ - // Local var used to keep track of temp nodes already written - temporary_terms_t tt2; - // To store the functions that have already been written in the form TEF* = ext_fun(); - deriv_node_temp_terms_t tef_terms; - for (temporary_terms_t::const_iterator it = tt.begin(); - it != tt.end(); it++) - { - if (dynamic_cast(*it) != NULL) - { - (*it)->compileExternalFunctionOutput(code_file, instruction_number, false, tt2, map_idx, dynamic, steady_dynamic, tef_terms); - } - - FNUMEXPR_ fnumexpr(TemporaryTerm, (int)(map_idx.find((*it)->idx)->second)); - fnumexpr.write(code_file, instruction_number); - (*it)->compile(code_file, instruction_number, false, tt2, map_idx, dynamic, steady_dynamic, tef_terms); - if (dynamic) - { - FSTPT_ fstpt((int)(map_idx.find((*it)->idx)->second)); - fstpt.write(code_file, instruction_number); - } - else - { - FSTPST_ fstpst((int)(map_idx.find((*it)->idx)->second)); - fstpst.write(code_file, instruction_number); - } - // Insert current node into tt2 - tt2.insert(*it); - } -} - -void -ModelTree::writeModelLocalVariables(ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const -{ - /* Collect all model local variables appearing in equations, and print only - them. Printing unused model local variables can lead to a crash (see - ticket #101). */ - set used_local_vars; - - // Use an empty set for the temporary terms - const temporary_terms_t tt; - - for (size_t i = 0; i < equations.size(); i++) - equations[i]->collectVariables(eModelLocalVariable, used_local_vars); - - for (vector::const_iterator it = local_variables_vector.begin(); - it != local_variables_vector.end(); it++) - if (used_local_vars.find(*it) != used_local_vars.end()) - { - int id = *it; - expr_t value = local_variables_table.find(id)->second; - value->writeExternalFunctionOutput(output, output_type, tt, tef_terms); - - if (IS_C(output_type)) - output << "double "; - else if (IS_JULIA(output_type)) - output << " @inbounds "; - - /* We append underscores to avoid name clashes with "g1" or "oo_" (see - also VariableNode::writeOutput) */ - output << symbol_table.getName(id) << "__ = "; - value->writeOutput(output, output_type, tt, tef_terms); - output << ";" << endl; - } -} - -void -ModelTree::writeJsonModelLocalVariables(ostream &output, deriv_node_temp_terms_t &tef_terms) const -{ - /* Collect all model local variables appearing in equations, and print only - them. Printing unused model local variables can lead to a crash (see - ticket #101). */ - set used_local_vars; - - // Use an empty set for the temporary terms - const temporary_terms_t tt; - - for (size_t i = 0; i < equations.size(); i++) - equations[i]->collectVariables(eModelLocalVariable, used_local_vars); - - output << "\"model_local_variables\": ["; - bool printed = false; - for (vector::const_iterator it = local_variables_vector.begin(); - it != local_variables_vector.end(); it++) - if (used_local_vars.find(*it) != used_local_vars.end()) - { - if (printed) - output << ", "; - else - printed = true; - - int id = *it; - vector efout; - expr_t value = local_variables_table.find(id)->second; - value->writeJsonExternalFunctionOutput(efout, tt, tef_terms); - for (vector::const_iterator it1 = efout.begin(); it1 != efout.end(); it1++) - { - if (it1 != efout.begin()) - output << ", "; - output << *it1; - } - - if (!efout.empty()) - output << ", "; - - /* We append underscores to avoid name clashes with "g1" or "oo_" (see - also VariableNode::writeOutput) */ - output << "{\"variable\": \"" << symbol_table.getName(id) << "__\"" - << ", \"value\": \""; - value->writeJsonOutput(output, tt, tef_terms); - output << "\"}" << endl; - } - output << "]"; -} - -void -ModelTree::writeModelEquations(ostream &output, ExprNodeOutputType output_type) const -{ - temporary_terms_t temp_terms; - if (IS_JULIA(output_type)) - temp_terms = temporary_terms_res; - else - temp_terms = temporary_terms; - - for (int eq = 0; eq < (int) equations.size(); eq++) - { - BinaryOpNode *eq_node = equations[eq]; - expr_t lhs = eq_node->get_arg1(); - expr_t rhs = eq_node->get_arg2(); - - // Test if the right hand side of the equation is empty. - double vrhs = 1.0; - try - { - vrhs = rhs->eval(eval_context_t()); - } - catch (ExprNode::EvalException &e) - { - } - - if (vrhs != 0) // The right hand side of the equation is not empty ==> residual=lhs-rhs; - { - if (IS_JULIA(output_type)) - output << " @inbounds "; - output << "lhs ="; - lhs->writeOutput(output, output_type, temp_terms); - output << ";" << endl; - - if (IS_JULIA(output_type)) - output << " @inbounds "; - output << "rhs ="; - rhs->writeOutput(output, output_type, temp_terms); - output << ";" << endl; - - if (IS_JULIA(output_type)) - output << " @inbounds "; - output << "residual" << LEFT_ARRAY_SUBSCRIPT(output_type) - << eq + ARRAY_SUBSCRIPT_OFFSET(output_type) - << RIGHT_ARRAY_SUBSCRIPT(output_type) - << "= lhs-rhs;" << endl; - } - else // The right hand side of the equation is empty ==> residual=lhs; - { - if (IS_JULIA(output_type)) - output << " @inbounds "; - output << "residual" << LEFT_ARRAY_SUBSCRIPT(output_type) - << eq + ARRAY_SUBSCRIPT_OFFSET(output_type) - << RIGHT_ARRAY_SUBSCRIPT(output_type) - << " = "; - lhs->writeOutput(output, output_type, temp_terms); - output << ";" << endl; - } - } -} - -void -ModelTree::compileModelEquations(ostream &code_file, unsigned int &instruction_number, const temporary_terms_t &tt, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const -{ - for (int eq = 0; eq < (int) equations.size(); eq++) - { - BinaryOpNode *eq_node = equations[eq]; - expr_t lhs = eq_node->get_arg1(); - expr_t rhs = eq_node->get_arg2(); - FNUMEXPR_ fnumexpr(ModelEquation, eq); - fnumexpr.write(code_file, instruction_number); - // Test if the right hand side of the equation is empty. - double vrhs = 1.0; - try - { - vrhs = rhs->eval(eval_context_t()); - } - catch (ExprNode::EvalException &e) - { - } - - if (vrhs != 0) // The right hand side of the equation is not empty ==> residual=lhs-rhs; - { - lhs->compile(code_file, instruction_number, false, temporary_terms, map_idx, dynamic, steady_dynamic); - rhs->compile(code_file, instruction_number, false, temporary_terms, map_idx, dynamic, steady_dynamic); - - FBINARY_ fbinary(oMinus); - fbinary.write(code_file, instruction_number); - - FSTPR_ fstpr(eq); - fstpr.write(code_file, instruction_number); - } - else // The right hand side of the equation is empty ==> residual=lhs; - { - lhs->compile(code_file, instruction_number, false, temporary_terms, map_idx, dynamic, steady_dynamic); - FSTPR_ fstpr(eq); - fstpr.write(code_file, instruction_number); - } - } -} - -void -ModelTree::Write_Inf_To_Bin_File(const string &basename, - int &u_count_int, bool &file_open, bool is_two_boundaries, int block_mfs) const -{ - int j; - std::ofstream SaveCode; - const string bin_basename = basename + ".bin"; - if (file_open) - SaveCode.open(bin_basename.c_str(), ios::out | ios::in | ios::binary | ios::ate); - else - SaveCode.open(bin_basename.c_str(), ios::out | ios::binary); - if (!SaveCode.is_open()) - { - cerr << "Error : Can't open file \"" << bin_basename << "\" for writing" << endl; - exit(EXIT_FAILURE); - } - u_count_int = 0; - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); it != first_derivatives.end(); it++) - { - int deriv_id = it->first.second; - if (getTypeByDerivID(deriv_id) == eEndogenous) - { - int eq = it->first.first; - int symb = getSymbIDByDerivID(deriv_id); - int var = symbol_table.getTypeSpecificID(symb); - int lag = getLagByDerivID(deriv_id); - SaveCode.write(reinterpret_cast(&eq), sizeof(eq)); - int varr = var + lag * block_mfs; - SaveCode.write(reinterpret_cast(&varr), sizeof(varr)); - SaveCode.write(reinterpret_cast(&lag), sizeof(lag)); - int u = u_count_int + block_mfs; - SaveCode.write(reinterpret_cast(&u), sizeof(u)); - u_count_int++; - } - } - if (is_two_boundaries) - u_count_int += symbol_table.endo_nbr(); - for (j = 0; j < (int) symbol_table.endo_nbr(); j++) - SaveCode.write(reinterpret_cast(&j), sizeof(j)); - for (j = 0; j < (int) symbol_table.endo_nbr(); j++) - SaveCode.write(reinterpret_cast(&j), sizeof(j)); - SaveCode.close(); -} - -void -ModelTree::writeLatexModelFile(const string &basename, ExprNodeOutputType output_type, const bool write_equation_tags) const -{ - ofstream output, content_output; - string filename = basename + ".tex"; - string content_basename = basename + "_content"; - string content_filename = content_basename + ".tex"; - output.open(filename.c_str(), ios::out | ios::binary); - if (!output.is_open()) - { - cerr << "ERROR: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - content_output.open(content_filename.c_str(), ios::out | ios::binary); - if (!content_output.is_open()) - { - cerr << "ERROR: Can't open file " << content_filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - output << "\\documentclass[10pt,a4paper]{article}" << endl - << "\\usepackage[landscape]{geometry}" << endl - << "\\usepackage{fullpage}" << endl - << "\\usepackage{amsfonts}" << endl - << "\\usepackage{breqn}" << endl - << "\\begin{document}" << endl - << "\\footnotesize" << endl; - - // Write model local variables - for (vector::const_iterator it = local_variables_vector.begin(); - it != local_variables_vector.end(); it++) - { - int id = *it; - expr_t value = local_variables_table.find(id)->second; - - content_output << "\\begin{dmath*}" << endl - << symbol_table.getTeXName(id) << " = "; - // Use an empty set for the temporary terms - value->writeOutput(content_output, output_type); - content_output << endl << "\\end{dmath*}" << endl; - } - - for (int eq = 0; eq < (int) equations.size(); eq++) - { - content_output << "% Equation " << eq + 1 << endl; - bool wrote_eq_tag = false; - if (write_equation_tags) - { - for (vector > >::const_iterator iteqt = equation_tags.begin(); - iteqt != equation_tags.end(); iteqt++) - if (iteqt->first == eq) - { - if (!wrote_eq_tag) - content_output << "\\noindent["; - else - content_output << ", "; - - content_output << iteqt->second.first; - - if (!(iteqt->second.second.empty())) - content_output << "= `" << iteqt->second.second << "'"; - - wrote_eq_tag = true; - } - } - if (wrote_eq_tag) - content_output << "]"; - - content_output << "\\begin{dmath}" << endl; - // Here it is necessary to cast to superclass ExprNode, otherwise the overloaded writeOutput() method is not found - dynamic_cast(equations[eq])->writeOutput(content_output, output_type); - content_output << endl << "\\end{dmath}" << endl; - } - - output << "\\include{" << content_basename << "}" << endl - << "\\end{document}" << endl; - - output.close(); - content_output.close(); -} - -void -ModelTree::addEquation(expr_t eq, int lineno) -{ - BinaryOpNode *beq = dynamic_cast(eq); - assert(beq != NULL && beq->get_op_code() == oEqual); - - equations.push_back(beq); - equations_lineno.push_back(lineno); -} - -void -ModelTree::addEquation(expr_t eq, int lineno, const vector > &eq_tags) -{ - int n = equations.size(); - for (size_t i = 0; i < eq_tags.size(); i++) - equation_tags.push_back(make_pair(n, eq_tags[i])); - addEquation(eq, lineno); -} - -void -ModelTree::addAuxEquation(expr_t eq) -{ - BinaryOpNode *beq = dynamic_cast(eq); - assert(beq != NULL && beq->get_op_code() == oEqual); - - aux_equations.push_back(beq); -} - -void -ModelTree::addTrendVariables(vector trend_vars, expr_t growth_factor) throw (TrendException) -{ - while (!trend_vars.empty()) - if (trend_symbols_map.find(trend_vars.back()) != trend_symbols_map.end()) - throw TrendException(symbol_table.getName(trend_vars.back())); - else - { - trend_symbols_map[trend_vars.back()] = growth_factor; - trend_vars.pop_back(); - } -} - -void -ModelTree::addNonstationaryVariables(vector nonstationary_vars, bool log_deflator, expr_t deflator) throw (TrendException) -{ - while (!nonstationary_vars.empty()) - if (nonstationary_symbols_map.find(nonstationary_vars.back()) != nonstationary_symbols_map.end()) - throw TrendException(symbol_table.getName(nonstationary_vars.back())); - else - { - nonstationary_symbols_map[nonstationary_vars.back()] = make_pair(log_deflator, deflator); - nonstationary_vars.pop_back(); - } -} - -void -ModelTree::initializeVariablesAndEquations() -{ - for (size_t j = 0; j < equations.size(); j++) - { - equation_reordered.push_back(j); - variable_reordered.push_back(j); - } -} - -void -ModelTree::set_cutoff_to_zero() -{ - cutoff = 0; -} - -void -ModelTree::jacobianHelper(ostream &output, int eq_nb, int col_nb, ExprNodeOutputType output_type) const -{ - output << " "; - if (IS_JULIA(output_type)) - output << "@inbounds "; - output << "g1" << LEFT_ARRAY_SUBSCRIPT(output_type); - if (IS_MATLAB(output_type) || IS_JULIA(output_type)) - output << eq_nb + 1 << "," << col_nb + 1; - else - output << eq_nb + col_nb *equations.size(); - output << RIGHT_ARRAY_SUBSCRIPT(output_type); -} - -void -ModelTree::sparseHelper(int order, ostream &output, int row_nb, int col_nb, ExprNodeOutputType output_type) const -{ - output << " v" << order << LEFT_ARRAY_SUBSCRIPT(output_type); - if (IS_MATLAB(output_type) || IS_JULIA(output_type)) - output << row_nb + 1 << "," << col_nb + 1; - else - output << row_nb + col_nb * NNZDerivatives[order-1]; - output << RIGHT_ARRAY_SUBSCRIPT(output_type); -} - -void -ModelTree::computeParamsDerivatives(int paramsDerivsOrder) -{ - if (!(paramsDerivsOrder == 1 || paramsDerivsOrder == 2)) - return; - set deriv_id_set; - addAllParamDerivId(deriv_id_set); - - for (set::const_iterator it = deriv_id_set.begin(); - it != deriv_id_set.end(); it++) - { - const int param = *it; - - for (int eq = 0; eq < (int) equations.size(); eq++) - { - expr_t d1 = equations[eq]->getDerivative(param); - if (d1 == Zero) - continue; - residuals_params_derivatives[make_pair(eq, param)] = d1; - } - - if (paramsDerivsOrder == 2) - for (first_derivatives_t::const_iterator it2 = residuals_params_derivatives.begin(); - it2 != residuals_params_derivatives.end(); it2++) - { - int eq = it2->first.first; - int param1 = it2->first.second; - expr_t d1 = it2->second; - - expr_t d2 = d1->getDerivative(param); - if (d2 == Zero) - continue; - residuals_params_second_derivatives[make_pair(eq, make_pair(param1, param))] = d2; - } - - for (first_derivatives_t::const_iterator it2 = first_derivatives.begin(); - it2 != first_derivatives.end(); it2++) - { - int eq = it2->first.first; - int var = it2->first.second; - expr_t d1 = it2->second; - - expr_t d2 = d1->getDerivative(param); - if (d2 == Zero) - continue; - jacobian_params_derivatives[make_pair(eq, make_pair(var, param))] = d2; - } - - if (paramsDerivsOrder == 2) - { - for (second_derivatives_t::const_iterator it2 = jacobian_params_derivatives.begin(); - it2 != jacobian_params_derivatives.end(); it2++) - { - int eq = it2->first.first; - int var = it2->first.second.first; - int param1 = it2->first.second.second; - expr_t d1 = it2->second; - - expr_t d2 = d1->getDerivative(param); - if (d2 == Zero) - continue; - jacobian_params_second_derivatives[make_pair(eq, make_pair(var, make_pair(param1, param)))] = d2; - } - - for (second_derivatives_t::const_iterator it2 = second_derivatives.begin(); - it2 != second_derivatives.end(); it2++) - { - int eq = it2->first.first; - int var1 = it2->first.second.first; - int var2 = it2->first.second.second; - expr_t d1 = it2->second; - - expr_t d2 = d1->getDerivative(param); - if (d2 == Zero) - continue; - hessian_params_derivatives[make_pair(eq, make_pair(var1, make_pair(var2, param)))] = d2; - } - } - } -} - -void -ModelTree::computeParamsDerivativesTemporaryTerms() -{ - map > reference_count; - params_derivs_temporary_terms.clear(); - map temp_terms_map; - temp_terms_map[eResidualsParamsDeriv] = params_derivs_temporary_terms_res; - temp_terms_map[eJacobianParamsDeriv] = params_derivs_temporary_terms_g1; - temp_terms_map[eResidualsParamsSecondDeriv] = params_derivs_temporary_terms_res2; - temp_terms_map[eJacobianParamsSecondDeriv] = params_derivs_temporary_terms_g12; - temp_terms_map[eHessianParamsDeriv] = params_derivs_temporary_terms_g2; - - for (first_derivatives_t::iterator it = residuals_params_derivatives.begin(); - it != residuals_params_derivatives.end(); it++) - it->second->computeTemporaryTerms(reference_count, - temp_terms_map, - true, eResidualsParamsDeriv); - - for (second_derivatives_t::iterator it = jacobian_params_derivatives.begin(); - it != jacobian_params_derivatives.end(); it++) - it->second->computeTemporaryTerms(reference_count, - temp_terms_map, - true, eJacobianParamsDeriv); - - for (second_derivatives_t::const_iterator it = residuals_params_second_derivatives.begin(); - it != residuals_params_second_derivatives.end(); ++it) - it->second->computeTemporaryTerms(reference_count, - temp_terms_map, - true, eResidualsParamsSecondDeriv); - - for (third_derivatives_t::const_iterator it = jacobian_params_second_derivatives.begin(); - it != jacobian_params_second_derivatives.end(); ++it) - it->second->computeTemporaryTerms(reference_count, - temp_terms_map, - true, eJacobianParamsSecondDeriv); - - for (third_derivatives_t::const_iterator it = hessian_params_derivatives.begin(); - it != hessian_params_derivatives.end(); ++it) - it->second->computeTemporaryTerms(reference_count, - temp_terms_map, - true, eHessianParamsDeriv); - - for (map::const_iterator it = temp_terms_map.begin(); - it != temp_terms_map.end(); it++) - params_derivs_temporary_terms.insert(it->second.begin(), it->second.end()); - - params_derivs_temporary_terms_res = temp_terms_map[eResidualsParamsDeriv]; - params_derivs_temporary_terms_g1 = temp_terms_map[eJacobianParamsDeriv]; - params_derivs_temporary_terms_res2 = temp_terms_map[eResidualsParamsSecondDeriv]; - params_derivs_temporary_terms_g12 = temp_terms_map[eJacobianParamsSecondDeriv]; - params_derivs_temporary_terms_g2 = temp_terms_map[eHessianParamsDeriv]; -} - -bool -ModelTree::isNonstationary(int symb_id) const -{ - return (nonstationary_symbols_map.find(symb_id) - != nonstationary_symbols_map.end()); -} - -void -ModelTree::writeJsonModelEquations(ostream &output, bool residuals) const -{ - deriv_node_temp_terms_t tef_terms; - vector > eqtags; - temporary_terms_t tt_empty; - if (residuals) - output << endl << "\"residuals\":[" << endl; - else - output << endl << "\"model\":[" << endl; - for (int eq = 0; eq < (int) equations.size(); eq++) - { - if (eq > 0) - output << ", "; - - BinaryOpNode *eq_node = equations[eq]; - expr_t lhs = eq_node->get_arg1(); - expr_t rhs = eq_node->get_arg2(); - - if (residuals) - { - output << "{\"residual\": {" - << "\"lhs\": \""; - lhs->writeJsonOutput(output, temporary_terms, tef_terms); - output << "\""; - - output << ", \"rhs\": \""; - rhs->writeJsonOutput(output, temporary_terms, tef_terms); - output << "\""; - try - { - // Test if the right hand side of the equation is empty. - if (rhs->eval(eval_context_t()) != 0) - { - output << ", \"rhs\": \""; - rhs->writeJsonOutput(output, temporary_terms, tef_terms); - output << "\""; - } - } - catch (ExprNode::EvalException &e) - { - } - output << "}"; - } - else - { - output << "{\"lhs\": \""; - lhs->writeJsonOutput(output, tt_empty, tef_terms); - output << "\", \"rhs\": \""; - rhs->writeJsonOutput(output, tt_empty, tef_terms); - output << "\"" - << ", \"line\": " << equations_lineno[eq]; - - for (vector > >::const_iterator it = equation_tags.begin(); - it != equation_tags.end(); it++) - if (it->first == eq) - eqtags.push_back(it->second); - - if (!eqtags.empty()) - { - output << ", \"tags\": {"; - int i = 0; - for (vector >::const_iterator it = eqtags.begin(); it != eqtags.end(); it++, i++) - { - if (i != 0) - output << ", "; - output << "\"" << it->first << "\": \"" << it->second << "\""; - } - output << "}"; - eqtags.clear(); - } - } - output << "}" << endl; - } - output << endl << "]" << endl; -} diff --git a/preprocessor/ModelTree.hh b/preprocessor/ModelTree.hh deleted file mode 100644 index be6b66cbb..000000000 --- a/preprocessor/ModelTree.hh +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#ifndef _MODELTREE_HH -#define _MODELTREE_HH - -using namespace std; - -#include -#include -#include -#include -#include - -#include "DataTree.hh" -#include "ExtendedPreprocessorTypes.hh" - -//! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a expr_t on the new normalized equation -typedef vector > equation_type_and_normalized_equation_t; - -//! Vector describing variables: max_lag in the block, max_lead in the block -typedef vector > lag_lead_vector_t; - -//! for each block contains pair< pair, pair < Block_Size, Recursive_part_Size > > -typedef vector, pair > > block_type_firstequation_size_mfs_t; - -//! for a block contains derivatives pair< pair , pair > -typedef vector< pair, pair< int, expr_t > > > block_derivatives_equation_variable_laglead_nodeid_t; - -//! for all blocks derivatives description -typedef vector blocks_derivatives_t; - -//! Shared code for static and dynamic models -class ModelTree : public DataTree -{ - friend class DynamicModel; - friend class StaticModel; -protected: - //! Stores declared and generated auxiliary equations - vector equations; - - //! Stores line numbers of declared equations; -1 means undefined - vector equations_lineno; - - //! Only stores generated auxiliary equations, in an order meaningful for evaluation - deque aux_equations; - - //! Stores equation tags - vector > > equation_tags; - - //! Number of non-zero derivatives - int NNZDerivatives[3]; - - typedef map, expr_t> first_derivatives_t; - //! First order derivatives - /*! First index is equation number, second is variable w.r. to which is computed the derivative. - Only non-null derivatives are stored in the map. - Variable indices are those of the getDerivID() method. - */ - first_derivatives_t first_derivatives; - - typedef map >, expr_t> second_derivatives_t; - //! Second order derivatives - /*! First index is equation number, second and third are variables w.r. to which is computed the derivative. - Only non-null derivatives are stored in the map. - Contains only second order derivatives where var1 >= var2 (for obvious symmetry reasons). - Variable indices are those of the getDerivID() method. - */ - second_derivatives_t second_derivatives; - - typedef map > >, expr_t> third_derivatives_t; - //! Third order derivatives - /*! First index is equation number, second, third and fourth are variables w.r. to which is computed the derivative. - Only non-null derivatives are stored in the map. - Contains only third order derivatives where var1 >= var2 >= var3 (for obvious symmetry reasons). - Variable indices are those of the getDerivID() method. - */ - third_derivatives_t third_derivatives; - - //! Derivatives of the residuals w.r. to parameters - /*! First index is equation number, second is parameter. - Only non-null derivatives are stored in the map. - Parameter indices are those of the getDerivID() method. - */ - first_derivatives_t residuals_params_derivatives; - - //! Second derivatives of the residuals w.r. to parameters - /*! First index is equation number, second and third indeces are parameters. - Only non-null derivatives are stored in the map. - Parameter indices are those of the getDerivID() method. - */ - second_derivatives_t residuals_params_second_derivatives; - - //! Derivatives of the jacobian w.r. to parameters - /*! First index is equation number, second is endo/exo/exo_det variable, and third is parameter. - Only non-null derivatives are stored in the map. - Variable and parameter indices are those of the getDerivID() method. - */ - second_derivatives_t jacobian_params_derivatives; - - //! Second derivatives of the jacobian w.r. to parameters - /*! First index is equation number, second is endo/exo/exo_det variable, and third and fourth are parameters. - Only non-null derivatives are stored in the map. - Variable and parameter indices are those of the getDerivID() method. - */ - third_derivatives_t jacobian_params_second_derivatives; - - //! Derivatives of the hessian w.r. to parameters - /*! First index is equation number, first and second are endo/exo/exo_det variable, and third is parameter. - Only non-null derivatives are stored in the map. - Variable and parameter indices are those of the getDerivID() method. - */ - third_derivatives_t hessian_params_derivatives; - - //! Temporary terms for the static/dynamic file (those which will be noted Txxxx) - temporary_terms_t temporary_terms; - temporary_terms_t temporary_terms_res; - temporary_terms_t temporary_terms_g1; - temporary_terms_t temporary_terms_g2; - temporary_terms_t temporary_terms_g3; - - //! Temporary terms for the file containing parameters derivatives - temporary_terms_t params_derivs_temporary_terms; - temporary_terms_t params_derivs_temporary_terms_res; - temporary_terms_t params_derivs_temporary_terms_g1; - temporary_terms_t params_derivs_temporary_terms_res2; - temporary_terms_t params_derivs_temporary_terms_g12; - temporary_terms_t params_derivs_temporary_terms_g2; - - //! Trend variables and their growth factors - map trend_symbols_map; - - //! for all trends; the boolean is true if this is a log-trend, false otherwise - typedef map > nonstationary_symbols_map_t; - - //! Nonstationary variables and their deflators - nonstationary_symbols_map_t nonstationary_symbols_map; - - //! vector of block reordered variables and equations - vector equation_reordered, variable_reordered, inv_equation_reordered, inv_variable_reordered; - - //! the file containing the model and the derivatives code - ofstream code_file; - - //! Computes 1st derivatives - /*! \param vars the derivation IDs w.r. to which compute the derivatives */ - void computeJacobian(const set &vars); - //! Computes 2nd derivatives - /*! \param vars the derivation IDs w.r. to which derive the 1st derivatives */ - void computeHessian(const set &vars); - //! Computes 3rd derivatives - /*! \param vars the derivation IDs w.r. to which derive the 2nd derivatives */ - void computeThirdDerivatives(const set &vars); - //! Computes derivatives of the Jacobian and Hessian w.r. to parameters - void computeParamsDerivatives(int paramsDerivsOrder); - //! Write derivative of an equation w.r. to a variable - void writeDerivative(ostream &output, int eq, int symb_id, int lag, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const; - //! Computes temporary terms (for all equations and derivatives) - void computeTemporaryTerms(bool is_matlab); - //! Computes temporary terms for the file containing parameters derivatives - void computeParamsDerivativesTemporaryTerms(); - //! Writes temporary terms - void writeTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_t &ttm1, ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const; - void writeJsonTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_t &ttm1, ostream &output, deriv_node_temp_terms_t &tef_terms, string &concat) const; - //! Compiles temporary terms - void compileTemporaryTerms(ostream &code_file, unsigned int &instruction_number, const temporary_terms_t &tt, map_idx_t map_idx, bool dynamic, bool steady_dynamic) const; - //! Adds informations for simulation in a binary file - void Write_Inf_To_Bin_File(const string &basename, int &u_count_int, bool &file_open, bool is_two_boundaries, int block_mfs) const; - //! Fixes output when there are more than 32 nested parens, Issue #1201 - void fixNestedParenthesis(ostringstream &output, map &tmp_paren_vars, bool &message_printed) const; - //! Tests if string contains more than 32 nested parens, Issue #1201 - bool testNestedParenthesis(const string &str) const; - //! Writes model local variables - /*! No temporary term is used in the output, so that local parameters declarations can be safely put before temporary terms declaration in the output files */ - void writeModelLocalVariables(ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const; - //! Writes model equations - void writeModelEquations(ostream &output, ExprNodeOutputType output_type) const; - //! Writes JSON model equations - //! if residuals = true, we are writing the dynamic/static model. - //! Otherwise, just the model equations (with line numbers, no tmp terms) - void writeJsonModelEquations(ostream &output, bool residuals) const; - void writeJsonModelLocalVariables(ostream &output, deriv_node_temp_terms_t &tef_terms) const; - //! Compiles model equations - void compileModelEquations(ostream &code_file, unsigned int &instruction_number, const temporary_terms_t &tt, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const; - - //! Writes LaTeX model file - void writeLatexModelFile(const string &basename, ExprNodeOutputType output_type, const bool write_equation_tags) const; - - //! Sparse matrix of double to store the values of the Jacobian - /*! First index is equation number, second index is endogenous type specific ID */ - typedef map, double> jacob_map_t; - - //! Sparse matrix of double to store the values of the Jacobian - /*! First index is lag, second index is equation number, third index is endogenous type specific ID */ - typedef map >, expr_t> dynamic_jacob_map_t; - - //! Normalization of equations - /*! Maps endogenous type specific IDs to equation numbers */ - vector endo2eq; - - //! number of equation in the prologue and in the epilogue - unsigned int epilogue, prologue; - - //! for each block contains pair< max_lag, max_lead> - lag_lead_vector_t block_lag_lead; - - //! Compute the matching between endogenous and variable using the jacobian contemporaneous_jacobian - /*! - \param contemporaneous_jacobian Jacobian used as an incidence matrix: all elements declared in the map (even if they are zero), are used as vertices of the incidence matrix - \return True if a complete normalization has been achieved - */ - bool computeNormalization(const jacob_map_t &contemporaneous_jacobian, bool verbose); - - //! Try to compute the matching between endogenous and variable using a decreasing cutoff - /*! - Applied to the jacobian contemporaneous_jacobian and stop when a matching is found. - If no matching is found using a strictly positive cutoff, then a zero cutoff is applied (i.e. use a symbolic normalization); in that case, the method adds zeros in the jacobian matrices to reflect all the edges in the symbolic incidence matrix. - If no matching is found with a zero cutoff close to zero an error message is printout. - */ - void computeNonSingularNormalization(jacob_map_t &contemporaneous_jacobian, double cutoff, jacob_map_t &static_jacobian, dynamic_jacob_map_t &dynamic_jacobian); - - //! Try to normalized each unnormalized equation (matched endogenous variable only on the LHS) - void computeNormalizedEquations(multimap &endo2eqs) const; - //! Evaluate the jacobian and suppress all the elements below the cutoff - void evaluateAndReduceJacobian(const eval_context_t &eval_context, jacob_map_t &contemporaneous_jacobian, jacob_map_t &static_jacobian, dynamic_jacob_map_t &dynamic_jacobian, double cutoff, bool verbose); - //! Search the equations and variables belonging to the prologue and the epilogue of the model - void computePrologueAndEpilogue(const jacob_map_t &static_jacobian, vector &equation_reordered, vector &variable_reordered); - //! Determine the type of each equation of model and try to normalized the unnormalized equation using computeNormalizedEquations - equation_type_and_normalized_equation_t equationTypeDetermination(const map >, expr_t> &first_order_endo_derivatives, const vector &Index_Var_IM, const vector &Index_Equ_IM, int mfs) const; - //! Compute the block decomposition and for a non-recusive block find the minimum feedback set - void computeBlockDecompositionAndFeedbackVariablesForEachBlock(const jacob_map_t &static_jacobian, const dynamic_jacob_map_t &dynamic_jacobian, vector &equation_reordered, vector &variable_reordered, vector > &blocks, const equation_type_and_normalized_equation_t &Equation_Type, bool verbose_, bool select_feedback_variable, int mfs, vector &inv_equation_reordered, vector &inv_variable_reordered, lag_lead_vector_t &equation_lag_lead, lag_lead_vector_t &variable_lag_lead_t, vector &n_static, vector &n_forward, vector &n_backward, vector &n_mixed) const; - //! Reduce the number of block merging the same type equation in the prologue and the epilogue and determine the type of each block - block_type_firstequation_size_mfs_t reduceBlocksAndTypeDetermination(const dynamic_jacob_map_t &dynamic_jacobian, vector > &blocks, const equation_type_and_normalized_equation_t &Equation_Type, const vector &variable_reordered, const vector &equation_reordered, vector &n_static, vector &n_forward, vector &n_backward, vector &n_mixed, vector, pair > > &block_col_type); - //! Determine the maximum number of lead and lag for the endogenous variable in a bloc - void getVariableLeadLagByBlock(const dynamic_jacob_map_t &dynamic_jacobian, const vector &components_set, int nb_blck_sim, lag_lead_vector_t &equation_lead_lag, lag_lead_vector_t &variable_lead_lag, const vector &equation_reordered, const vector &variable_reordered) const; - //! Print an abstract of the block structure of the model - void printBlockDecomposition(const vector > &blocks) const; - //! Determine for each block if it is linear or not - vector BlockLinear(const blocks_derivatives_t &blocks_derivatives, const vector &variable_reordered) const; - - //! Determine the simulation type of each block - virtual BlockSimulationType getBlockSimulationType(int block_number) const = 0; - //! Return the number of blocks - virtual unsigned int getNbBlocks() const = 0; - //! Return the first equation number of a block - virtual unsigned int getBlockFirstEquation(int block_number) const = 0; - //! Return the size of the block block_number - virtual unsigned int getBlockSize(int block_number) const = 0; - //! Return the number of exogenous variable in the block block_number - virtual unsigned int getBlockExoSize(int block_number) const = 0; - //! 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 = 0; - //! Return the number of feedback variable of the block block_number - virtual unsigned int getBlockMfs(int block_number) const = 0; - //! Return the maximum lag in a block - virtual unsigned int getBlockMaxLag(int block_number) const = 0; - //! Return the maximum lead in a block - virtual unsigned int getBlockMaxLead(int block_number) const = 0; - inline void - setBlockLeadLag(int block, int max_lag, int max_lead) - { - block_lag_lead[block] = make_pair(max_lag, max_lead); - }; - - //! Return the type of equation (equation_number) belonging to the block block_number - virtual EquationType getBlockEquationType(int block_number, int equation_number) const = 0; - //! Return true if the equation has been normalized - virtual bool isBlockEquationRenormalized(int block_number, int equation_number) const = 0; - //! 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 = 0; - //! 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 = 0; - //! Return the original number of equation equation_number belonging to the block block_number - virtual int getBlockEquationID(int block_number, int equation_number) const = 0; - //! Return the original number of variable variable_number belonging to the block block_number - virtual int getBlockVariableID(int block_number, int variable_number) const = 0; - //! 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 = 0; - //! 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 = 0; - //! 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 = 0; - //! Return the position of variable_number in the block number belonging to the block block_number - virtual int getBlockInitialExogenousID(int block_number, int variable_number) const = 0; - //! 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 = 0; - //! 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 = 0; - //! Initialize equation_reordered & variable_reordered - void initializeVariablesAndEquations(); -public: - ModelTree(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_arg); - //! Absolute value under which a number is considered to be zero - double cutoff; - //! Compute the minimum feedback set - /*! 0 : all endogenous variables are considered as feedback variables - 1 : the variables belonging to non normalized equation are considered as feedback variables - 2 : the variables belonging to a non linear equation are considered as feedback variables - 3 : the variables belonging to a non normalizable non linear equation are considered as feedback variables - default value = 0 */ - int mfs; - //! Declare a node as an equation of the model; also give its line number - void addEquation(expr_t eq, int lineno); - //! Declare a node as an equation of the model, also giving its tags - void addEquation(expr_t eq, int lineno, const vector > &eq_tags); - //! Declare a node as an auxiliary equation of the model, adding it at the end of the list of auxiliary equations - void addAuxEquation(expr_t eq); - //! Returns the number of equations in the model - int equation_number() const; - //! Adds a trend variable with its growth factor - void addTrendVariables(vector trend_vars, expr_t growth_factor) throw (TrendException); - //! Adds a nonstationary variables with their (common) deflator - void addNonstationaryVariables(vector nonstationary_vars, bool log_deflator, expr_t deflator) throw (TrendException); - //! Is a given variable non-stationary? - bool isNonstationary(int symb_id) const; - void set_cutoff_to_zero(); - //! Helper for writing the Jacobian elements in MATLAB and C - /*! Writes either (i+1,j+1) or [i+j*no_eq] */ - void jacobianHelper(ostream &output, int eq_nb, int col_nb, ExprNodeOutputType output_type) const; - //! Helper for writing the sparse Hessian or third derivatives in MATLAB and C - /*! If order=2, writes either v2(i+1,j+1) or v2[i+j*NNZDerivatives[1]] - If order=3, writes either v3(i+1,j+1) or v3[i+j*NNZDerivatives[2]] */ - void sparseHelper(int order, ostream &output, int row_nb, int col_nb, ExprNodeOutputType output_type) const; - inline static std::string - c_Equation_Type(int type) - { - char c_Equation_Type[4][13] = - { - "E_UNKNOWN ", - "E_EVALUATE ", - "E_EVALUATE_S", - "E_SOLVE " - }; - return (c_Equation_Type[type]); - }; - - inline static std::string - BlockType0(BlockType type) - { - switch (type) - { - case SIMULTANS: - return ("SIMULTANEOUS TIME SEPARABLE "); - break; - case PROLOGUE: - return ("PROLOGUE "); - break; - case EPILOGUE: - return ("EPILOGUE "); - break; - case SIMULTAN: - return ("SIMULTANEOUS TIME UNSEPARABLE"); - break; - default: - return ("UNKNOWN "); - break; - } - }; - - inline static std::string - BlockSim(int type) - { - switch (type) - { - case EVALUATE_FORWARD: - return ("EVALUATE FORWARD "); - break; - case EVALUATE_BACKWARD: - return ("EVALUATE BACKWARD "); - break; - case SOLVE_FORWARD_SIMPLE: - return ("SOLVE FORWARD SIMPLE "); - break; - case SOLVE_BACKWARD_SIMPLE: - return ("SOLVE BACKWARD SIMPLE "); - break; - case SOLVE_TWO_BOUNDARIES_SIMPLE: - return ("SOLVE TWO BOUNDARIES SIMPLE "); - break; - case SOLVE_FORWARD_COMPLETE: - return ("SOLVE FORWARD COMPLETE "); - break; - case SOLVE_BACKWARD_COMPLETE: - return ("SOLVE BACKWARD COMPLETE "); - break; - case SOLVE_TWO_BOUNDARIES_COMPLETE: - return ("SOLVE TWO BOUNDARIES COMPLETE"); - break; - default: - return ("UNKNOWN "); - break; - } - }; -}; - -#endif diff --git a/preprocessor/NumericalConstants.cc b/preprocessor/NumericalConstants.cc deleted file mode 100644 index a2224eae4..000000000 --- a/preprocessor/NumericalConstants.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2003-2012 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 . - */ - -#include -#include -#include -#include -#include - -#include "NumericalConstants.hh" - -int -NumericalConstants::AddNonNegativeConstant(const string &iConst) -{ - map::const_iterator iter = numConstantsIndex.find(iConst); - - if (iter != numConstantsIndex.end()) - return iter->second; - - int id = (int) mNumericalConstants.size(); - mNumericalConstants.push_back(iConst); - numConstantsIndex[iConst] = id; - - double val = strtod(iConst.c_str(), NULL); - - /* Note that we allow underflows (will be converted to 0) and overflows (will - be converted to Inf), as MATLAB and Octave do. */ - - assert(val >= 0 || isnan(val)); // Check we have a positive constant or a NaN - double_vals.push_back(val); - - return id; -} - -string -NumericalConstants::get(int ID) const -{ - assert(ID >= 0 && ID < (int) mNumericalConstants.size()); - return mNumericalConstants[ID]; -} - -double -NumericalConstants::getDouble(int ID) const -{ - assert(ID >= 0 && ID < (int) double_vals.size()); - return (double_vals[ID]); -} diff --git a/preprocessor/NumericalConstants.hh b/preprocessor/NumericalConstants.hh deleted file mode 100644 index b9c601b51..000000000 --- a/preprocessor/NumericalConstants.hh +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2003-2016 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 . - */ - -#ifndef _NUMERICALCONSTANTS_HH -#define _NUMERICALCONSTANTS_HH - -using namespace std; - -#include -#include -#include - -//! Handles non-negative numerical constants -class NumericalConstants -{ -private: - //! Vector of numerical constants - vector mNumericalConstants; - //! Double values of these constants - vector double_vals; - //! Map matching constants to their id - map numConstantsIndex; -public: - //! Adds a non-negative constant (possibly Inf or NaN) and returns its ID - int AddNonNegativeConstant(const string &iConst); - //! Get a constant in string form - string get(int ID) const; - //! Get a constant in double form - double getDouble(int ID) const; -}; - -#endif diff --git a/preprocessor/NumericalInitialization.cc b/preprocessor/NumericalInitialization.cc deleted file mode 100644 index ad199014b..000000000 --- a/preprocessor/NumericalInitialization.cc +++ /dev/null @@ -1,649 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#include -#include -#include -#include - -#include "NumericalInitialization.hh" - -InitParamStatement::InitParamStatement(int symb_id_arg, - const expr_t param_value_arg, - const SymbolTable &symbol_table_arg) : - symb_id(symb_id_arg), - param_value(param_value_arg), - symbol_table(symbol_table_arg) -{ -} - -void -InitParamStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - if (symbol_table.getName(symb_id) == "dsge_prior_weight") - mod_file_struct.dsge_prior_weight_initialized = true; -} - -void -InitParamStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - int id = symbol_table.getTypeSpecificID(symb_id) + 1; - output << "M_.params( " << id << " ) = "; - param_value->writeOutput(output); - output << ";" << endl; - if (!minimal_workspace) - output << symbol_table.getName(symb_id) << " = M_.params( " << id << " );" << endl; -} - -void -InitParamStatement::writeJuliaOutput(ostream &output, const string &basename) -{ - int id = symbol_table.getTypeSpecificID(symb_id) + 1; - output << "model_.params[ " << id << " ] = "; - param_value->writeOutput(output); - output << endl; - // Do we really need this? - // if (!minimal_workspace) - // output << symbol_table.getName(symb_id) << " = model_.params[ " << id << " ]" << endl; -} - -void -InitParamStatement::writeJsonOutput(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - output << "{\"statementName\": \"param_init\", \"name\": \"" << symbol_table.getName(symb_id) << "\", " << "\"value\": \""; - param_value->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"}"; -} - -void -InitParamStatement::writeCOutput(ostream &output, const string &basename) -{ - int id = symbol_table.getTypeSpecificID(symb_id); - output << "params[ " << id << " ] = "; - param_value->writeOutput(output); - output << ";" << endl; - output << "double " << symbol_table.getName(symb_id) << " = params[ " << id << " ];" << endl; -} - -void -InitParamStatement::fillEvalContext(eval_context_t &eval_context) const -{ - try - { - eval_context[symb_id] = param_value->eval(eval_context); - } - catch (ExprNode::EvalException &e) - { - // Do nothing - } -} - -InitOrEndValStatement::InitOrEndValStatement(const init_values_t &init_values_arg, - const SymbolTable &symbol_table_arg, - const bool &all_values_required_arg) : - init_values(init_values_arg), - symbol_table(symbol_table_arg), - all_values_required(all_values_required_arg) -{ -} - -void -InitOrEndValStatement::fillEvalContext(eval_context_t &eval_context) const -{ - for (init_values_t::const_iterator it = init_values.begin(); - it != init_values.end(); it++) - { - try - { - eval_context[it->first] = (it->second)->eval(eval_context); - } - catch (ExprNode::EvalException &e) - { - // Do nothing - } - } -} - -set -InitOrEndValStatement::getUninitializedVariables(SymbolType type) -{ - set unused; - if (!all_values_required) - return unused; - - if (type == eEndogenous) - unused = symbol_table.getEndogenous(); - else if (type == eExogenous) - unused = symbol_table.getExogenous(); - else - { - cerr << "ERROR: Shouldn't arrive here." << endl; - exit(EXIT_FAILURE); - } - - set::iterator sit; - for (init_values_t::const_iterator it = init_values.begin(); - it != init_values.end(); it++) - { - sit = unused.find(it->first); - if (sit != unused.end()) - unused.erase(sit); - } - return unused; -} - -void -InitOrEndValStatement::writeInitValues(ostream &output) const -{ - for (init_values_t::const_iterator it = init_values.begin(); - it != init_values.end(); it++) - { - const int symb_id = it->first; - const expr_t expression = it->second; - - SymbolType type = symbol_table.getType(symb_id); - int tsid = symbol_table.getTypeSpecificID(symb_id) + 1; - - if (type == eEndogenous) - output << "oo_.steady_state"; - else if (type == eExogenous) - output << "oo_.exo_steady_state"; - else if (type == eExogenousDet) - output << "oo_.exo_det_steady_state"; - - output << "( " << tsid << " ) = "; - expression->writeOutput(output); - output << ";" << endl; - } -} - -void -InitOrEndValStatement::writeJsonInitValues(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - for (init_values_t::const_iterator it = init_values.begin(); - it != init_values.end(); it++) - { - if (it != init_values.begin()) - output << ", "; - output << "{\"name\": \"" << symbol_table.getName(it->first) << "\", " << "\"value\": \""; - it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"}"; - } -} - -InitValStatement::InitValStatement(const init_values_t &init_values_arg, - const SymbolTable &symbol_table_arg, - const bool &all_values_required_arg) : - InitOrEndValStatement(init_values_arg, symbol_table_arg, all_values_required_arg) -{ -} - -void -InitValStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - set exogs = getUninitializedVariables(eExogenous); - set endogs = getUninitializedVariables(eEndogenous); - - if (endogs.size() > 0) - { - cerr << "ERROR: You have not set the following endogenous variables in initval:"; - for (set::const_iterator it = endogs.begin(); it != endogs.end(); it++) - cerr << " " << symbol_table.getName(*it); - cerr << endl; - } - - if (exogs.size() > 0) - { - cerr << "ERROR: You have not set the following exogenous variables in initval:"; - for (set::const_iterator it = exogs.begin(); it != exogs.end(); it++) - cerr << " " << symbol_table.getName(*it); - cerr << endl; - } - - if (endogs.size() > 0 || exogs.size() > 0) - exit(EXIT_FAILURE); -} - -void -InitValStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "%" << endl - << "% INITVAL instructions" << endl - << "%" << endl; - // Writing initval block to set initial values for variables - output << "options_.initval_file = 0;" << endl; - - writeInitValues(output); -} - -void -InitValStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"init_val\", \"vals\": ["; - writeJsonInitValues(output); - output << "]}"; -} - -void -InitValStatement::writeOutputPostInit(ostream &output) const -{ - output << "if M_.exo_nbr > 0" << endl - << "\too_.exo_simul = ones(M_.maximum_lag,1)*oo_.exo_steady_state';" << endl - <<"end" << endl - << "if M_.exo_det_nbr > 0" << endl - << "\too_.exo_det_simul = ones(M_.maximum_lag,1)*oo_.exo_det_steady_state';" << endl - <<"end" << endl; -} - -EndValStatement::EndValStatement(const init_values_t &init_values_arg, - const SymbolTable &symbol_table_arg, - const bool &all_values_required_arg) : - InitOrEndValStatement(init_values_arg, symbol_table_arg, all_values_required_arg) -{ -} - -void -EndValStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - set exogs = getUninitializedVariables(eExogenous); - set endogs = getUninitializedVariables(eEndogenous); - - if (endogs.size() > 0) - { - cerr << "ERROR: You have not set the following endogenous variables in endval:"; - for (set::const_iterator it = endogs.begin(); it != endogs.end(); it++) - cerr << " " << symbol_table.getName(*it); - cerr << endl; - } - - if (exogs.size() > 0) - { - cerr << "ERROR: You have not set the following exogenous variables in endval:"; - for (set::const_iterator it = exogs.begin(); it != exogs.end(); it++) - cerr << " " << symbol_table.getName(*it); - cerr << endl; - } - - if (endogs.size() > 0 || exogs.size() > 0) - exit(EXIT_FAILURE); -} - -void -EndValStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "%" << endl - << "% ENDVAL instructions" << endl - << "%" << endl; - // Writing endval block to set terminal values for variables - output << "ys0_= oo_.steady_state;" << endl - << "ex0_ = oo_.exo_steady_state;" << endl; - - writeInitValues(output); -} - -void -EndValStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"end_val\", \"vals\": ["; - writeJsonInitValues(output); - output << "]}"; -} - -HistValStatement::HistValStatement(const hist_values_t &hist_values_arg, - const hist_vals_wrong_lag_t hist_vals_wrong_lag_arg, - const SymbolTable &symbol_table_arg, - const bool &all_values_required_arg) : - hist_values(hist_values_arg), - hist_vals_wrong_lag(hist_vals_wrong_lag_arg), - symbol_table(symbol_table_arg), - all_values_required(all_values_required_arg) -{ -} - -void -HistValStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - if (all_values_required) - { - set unused_endo = symbol_table.getEndogenous(); - set unused_exo = symbol_table.getExogenous(); - - set::iterator sit; - for (hist_values_t::const_iterator it = hist_values.begin(); - it != hist_values.end(); it++) - { - sit = unused_endo.find(it->first.first); - if (sit != unused_endo.end()) - unused_endo.erase(sit); - - sit = unused_exo.find(it->first.first); - if (sit != unused_exo.end()) - unused_exo.erase(sit); - } - - if (unused_endo.size() > 0) - { - cerr << "ERROR: You have not set the following endogenous variables in histval:"; - for (set::const_iterator it = unused_endo.begin(); it != unused_endo.end(); it++) - cerr << " " << symbol_table.getName(*it); - cerr << endl; - } - - if (unused_exo.size() > 0) - { - cerr << "ERROR: You have not set the following exogenous variables in endval:"; - for (set::const_iterator it = unused_exo.begin(); it != unused_exo.end(); it++) - cerr << " " << symbol_table.getName(*it); - cerr << endl; - } - - if (unused_endo.size() > 0 || unused_exo.size() > 0) - exit(EXIT_FAILURE); - } - mod_file_struct.hist_vals_wrong_lag = hist_vals_wrong_lag; -} - -void -HistValStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "%" << endl - << "% HISTVAL instructions" << endl - << "%" << endl - << "M_.endo_histval = zeros(M_.endo_nbr,M_.maximum_lag);" << endl - << "M_.exo_histval = zeros(M_.exo_nbr,M_.maximum_lag);" << endl - << "M_.exo_det_histval = zeros(M_.exo_det_nbr,M_.maximum_lag);" << endl; - - for (hist_values_t::const_iterator it = hist_values.begin(); - it != hist_values.end(); it++) - { - int symb_id = it->first.first; - int lag = it->first.second; - const expr_t expression = it->second; - - SymbolType type = symbol_table.getType(symb_id); - - // For a lag greater than 1 on endo, or for any exo, lookup for auxiliary variable - if ((type == eEndogenous && lag < 0) || type == eExogenous) - { - try - { - // This function call must remain the 1st statement in this block - symb_id = symbol_table.searchAuxiliaryVars(symb_id, lag); - lag = 0; - type = eEndogenous; - } - catch (SymbolTable::SearchFailedException &e) - { - if (type == eEndogenous) - { - cerr << "HISTVAL: internal error of Dynare, please contact the developers"; - exit(EXIT_FAILURE); - } - // We don't fail for exogenous, because they are not replaced by - // auxiliary variables in deterministic mode. - } - } - - int tsid = symbol_table.getTypeSpecificID(symb_id) + 1; - - if (type == eEndogenous) - output << "M_.endo_histval( " << tsid << ", M_.maximum_lag + " << lag << ") = "; - else if (type == eExogenous) - output << "M_.exo_histval( " << tsid << ", M_.maximum_lag + " << lag << ") = "; - else if (type == eExogenousDet) - output << "M_.exo_det_histval( " << tsid << ", M_.maximum_lag + " << lag << ") = "; - - expression->writeOutput(output); - output << ";" << endl; - } -} - -void -HistValStatement::writeJsonOutput(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - output << "{\"statementName\": \"hist_val\", \"vals\": ["; - for (hist_values_t::const_iterator it = hist_values.begin(); - it != hist_values.end(); it++) - { - if (it != hist_values.begin()) - output << ", "; - output << "{ \"name\": \"" << symbol_table.getName(it->first.first) << "\"" - << ", \"lag\": " << it->first.second - << ", \"value\": \""; - it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"}"; - } - output << "]}"; -} - -InitvalFileStatement::InitvalFileStatement(const string &filename_arg) : - filename(filename_arg) -{ -} - -void -InitvalFileStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "%" << endl - << "% INITVAL_FILE statement" << endl - << "%" << endl - << "options_.initval_file = 1;" << endl - << "initvalf('" << filename << "');" << endl; -} - -void -InitvalFileStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"init_val_file\"" - << ", \"filename\": \"" << filename << "\"" - << "}"; -} - -HistvalFileStatement::HistvalFileStatement(const string &filename_arg) : - filename(filename_arg) -{ -} - -void -HistvalFileStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "histvalf('" << filename << "');" << endl; -} - -void -HistvalFileStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"hist_val_file\"" - << ", \"filename\": \"" << filename << "\"" - << "}"; -} - -HomotopyStatement::HomotopyStatement(const homotopy_values_t &homotopy_values_arg, - const SymbolTable &symbol_table_arg) : - homotopy_values(homotopy_values_arg), - symbol_table(symbol_table_arg) -{ -} - -void -HomotopyStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "%" << endl - << "% HOMOTOPY_SETUP instructions" << endl - << "%" << endl - << "options_.homotopy_values = [];" << endl; - - for (homotopy_values_t::const_iterator it = homotopy_values.begin(); - it != homotopy_values.end(); it++) - { - const int &symb_id = it->first; - const expr_t expression1 = it->second.first; - const expr_t expression2 = it->second.second; - - const SymbolType type = symbol_table.getType(symb_id); - const int tsid = symbol_table.getTypeSpecificID(symb_id) + 1; - - output << "options_.homotopy_values = vertcat(options_.homotopy_values, [ " << type << ", " << tsid << ", "; - if (expression1 != NULL) - expression1->writeOutput(output); - else - output << "NaN"; - output << ", "; - expression2->writeOutput(output); - output << "]);" << endl; - } -} - -void -HomotopyStatement::writeJsonOutput(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - output << "{\"statementName\": \"homotopy\", " - << "\"values\": ["; - for (homotopy_values_t::const_iterator it = homotopy_values.begin(); - it != homotopy_values.end(); it++) - { - if (it != homotopy_values.begin()) - output << ", "; - output << "{\"name\": \"" << symbol_table.getName(it->first) << "\"" - << ", \"initial_value\": \""; - if (it->second.first != NULL) - it->second.first->writeJsonOutput(output, temporary_terms_t(), tef_terms); - else - output << "NaN"; - output << "\", \"final_value\": \""; - it->second.second->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"}"; - } - output << "]" - << "}"; -} - -SaveParamsAndSteadyStateStatement::SaveParamsAndSteadyStateStatement(const string &filename_arg) : - filename(filename_arg) -{ -} - -void -SaveParamsAndSteadyStateStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "save_params_and_steady_state('" << filename << "');" << endl; -} - -void -SaveParamsAndSteadyStateStatement::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"save_params_and_steady_state\"" - << ", \"filename\": \"" << filename << "\"" - << "}"; -} - -LoadParamsAndSteadyStateStatement::LoadParamsAndSteadyStateStatement(const string &filename, - const SymbolTable &symbol_table_arg, - WarningConsolidation &warnings) : - symbol_table(symbol_table_arg) -{ - cout << "Reading " << filename << "." << endl; - - ifstream f; - f.open(filename.c_str(), ios::in); - if (f.fail()) - { - cerr << "ERROR: Can't open " << filename << endl; - exit(EXIT_FAILURE); - } - - while (true) - { - string symb_name, value; - f >> symb_name >> value; - if (f.eof()) - break; - - try - { - int symb_id = symbol_table.getID(symb_name); - content[symb_id] = value; - } - catch (SymbolTable::UnknownSymbolNameException &e) - { - warnings << "WARNING: Unknown symbol " << symb_name << " in " << filename << endl; - } - } - f.close(); -} - -void -LoadParamsAndSteadyStateStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - for (map::const_iterator it = content.begin(); - it != content.end(); it++) - { - switch (symbol_table.getType(it->first)) - { - case eParameter: - output << "M_.params"; - break; - case eEndogenous: - output << "oo_.steady_state"; - break; - case eExogenous: - output << "oo_.exo_steady_state"; - break; - case eExogenousDet: - output << "oo_.exo_det_steady_state"; - break; - default: - cerr << "ERROR: Unsupported variable type for " << symbol_table.getName(it->first) << " in load_params_and_steady_state" << endl; - exit(EXIT_FAILURE); - } - - int tsid = symbol_table.getTypeSpecificID(it->first) + 1; - output << "(" << tsid << ") = " << it->second << ";" << endl; - } -} - -void -LoadParamsAndSteadyStateStatement::writeJsonOutput(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - output << "{\"statementName\": \"load_params_and_steady_state\"" - << "\"values\": ["; - for (map::const_iterator it = content.begin(); - it != content.end(); it++) - { - if (it != content.begin()) - output << ", "; - output << "{\"name\": \"" << symbol_table.getName(it->first) << "\"" - << ", \"value\": \"" << it->second << "\"}"; - } - output << "]" - << "}"; -} - -void -LoadParamsAndSteadyStateStatement::fillEvalContext(eval_context_t &eval_context) const -{ - for (map::const_iterator it = content.begin(); - it != content.end(); it++) - eval_context[it->first] = atof(it->second.c_str()); -} diff --git a/preprocessor/NumericalInitialization.hh b/preprocessor/NumericalInitialization.hh deleted file mode 100644 index 16f5acd1d..000000000 --- a/preprocessor/NumericalInitialization.hh +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#ifndef _NUMERICALINITIALIZATION_HH -#define _NUMERICALINITIALIZATION_HH - -using namespace std; - -#include -#include -#include - -#include "SymbolTable.hh" -#include "ExprNode.hh" -#include "Statement.hh" - -class InitParamStatement : public Statement -{ -private: - const int symb_id; - const expr_t param_value; - const SymbolTable &symbol_table; -public: - InitParamStatement(int symb_id_arg, const expr_t param_value_arg, - const SymbolTable &symbol_table_arg); - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJuliaOutput(ostream &output, const string &basename); - virtual void writeCOutput(ostream &output, const string &basename); - virtual void writeJsonOutput(ostream &output) const; - //! Fill eval context with parameter value - void fillEvalContext(eval_context_t &eval_context) const; -}; - -class InitOrEndValStatement : public Statement -{ -public: - /*! - We use a vector instead of a map, since the order of declaration matters: - an initialization can depend on a previously initialized variable inside the block - */ - typedef vector > init_values_t; -protected: - const init_values_t init_values; - const SymbolTable &symbol_table; - const bool all_values_required; -public: - InitOrEndValStatement(const init_values_t &init_values_arg, - const SymbolTable &symbol_table_arg, - const bool &all_values_required_arg); - //! Return set of unused variables by type - set getUninitializedVariables(SymbolType type); - //! Fill eval context with variables values - void fillEvalContext(eval_context_t &eval_context) const; -protected: - void writeInitValues(ostream &output) const; - void writeJsonInitValues(ostream &output) const; -}; - -class InitValStatement : public InitOrEndValStatement -{ -public: - InitValStatement(const init_values_t &init_values_arg, - const SymbolTable &symbol_table_arg, - const bool &all_values_required_arg); - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; - //! Writes initializations for oo_.exo_simul and oo_.exo_det_simul - void writeOutputPostInit(ostream &output) const; -}; - -class EndValStatement : public InitOrEndValStatement -{ -public: - EndValStatement(const init_values_t &init_values_arg, - const SymbolTable &symbol_table_arg, - const bool &all_values_required_arg); - //! Workaround for trac ticket #35 - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class HistValStatement : public Statement -{ -public: - /*! - Contrary to Initval and Endval, we use a map, since it is impossible to reuse - a given initialization value in a second initialization inside the block. - Maps pairs (symbol_id, lag) to expr_t - */ - typedef map, expr_t> hist_values_t; - typedef map hist_vals_wrong_lag_t; -private: - const hist_values_t hist_values; - const hist_vals_wrong_lag_t hist_vals_wrong_lag; - const SymbolTable &symbol_table; - const bool all_values_required; -public: - HistValStatement(const hist_values_t &hist_values_arg, - const hist_vals_wrong_lag_t hist_vals_wrong_lag_arg, - const SymbolTable &symbol_table_arg, - const bool &all_values_required_arg); - //! Workaround for trac ticket #157 - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class InitvalFileStatement : public Statement -{ -private: - const string filename; -public: - InitvalFileStatement(const string &filename_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class HistvalFileStatement : public Statement -{ -private: - const string filename; -public: - HistvalFileStatement(const string &filename_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class HomotopyStatement : public Statement -{ -public: - //! Stores the declarations of homotopy_setup - /*! Order matter so we use a vector. First expr_t can be NULL if no initial value given. */ - typedef vector > > homotopy_values_t; -private: - const homotopy_values_t homotopy_values; - const SymbolTable &symbol_table; -public: - HomotopyStatement(const homotopy_values_t &homotopy_values_arg, - const SymbolTable &symbol_table_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class SaveParamsAndSteadyStateStatement : public Statement -{ -private: - const string filename; -public: - SaveParamsAndSteadyStateStatement(const string &filename_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class LoadParamsAndSteadyStateStatement : public Statement -{ -private: - const SymbolTable &symbol_table; - //! Content of the file - /*! Maps symbol ID to numeric value (stored as string) */ - map content; -public: - LoadParamsAndSteadyStateStatement(const string &filename, - const SymbolTable &symbol_table_arg, - WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - //! Fill eval context with parameters/variables values - void fillEvalContext(eval_context_t &eval_context) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -#endif diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc deleted file mode 100644 index 7a3fbe43e..000000000 --- a/preprocessor/ParsingDriver.cc +++ /dev/null @@ -1,3129 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#include -#include -#include -#include -#include -#include - -#include "ParsingDriver.hh" -#include "Statement.hh" -#include "ExprNode.hh" -#include "WarningConsolidation.hh" - -bool -ParsingDriver::symbol_exists_and_is_not_modfile_local_or_external_function(const char *s) -{ - if (!mod_file->symbol_table.exists(s)) - return false; - - SymbolType type = mod_file->symbol_table.getType(s); - - return (type != eModFileLocalVariable && type != eExternalFunction); -} - -void -ParsingDriver::check_symbol_existence_in_model_block(const string &name) -{ - if (!mod_file->symbol_table.exists(name)) - model_error("Unknown symbol: " + name); -} - -void -ParsingDriver::check_symbol_existence(const string &name) -{ - if (!mod_file->symbol_table.exists(name)) - error("Unknown symbol: " + name); -} - -void -ParsingDriver::check_symbol_is_parameter(string *name) -{ - check_symbol_existence(*name); - int symb_id = mod_file->symbol_table.getID(*name); - if (mod_file->symbol_table.getType(symb_id) != eParameter) - error(*name + " is not a parameter"); -} - -void -ParsingDriver::set_current_data_tree(DataTree *data_tree_arg) -{ - data_tree = data_tree_arg; - model_tree = dynamic_cast(data_tree_arg); - dynamic_model = dynamic_cast(data_tree_arg); -} - -void -ParsingDriver::reset_data_tree() -{ - set_current_data_tree(&mod_file->expressions_tree); -} - -void -ParsingDriver::reset_current_external_function_options() -{ - current_external_function_options.nargs = eExtFunSetDefaultNargs; - current_external_function_options.firstDerivSymbID = eExtFunNotSet; - current_external_function_options.secondDerivSymbID = eExtFunNotSet; - current_external_function_id = eExtFunNotSet; -} - -ModFile * -ParsingDriver::parse(istream &in, bool debug) -{ - mod_file = new ModFile(warnings); - - symbol_list.clear(); - - reset_data_tree(); - estim_params.init(*data_tree); - osr_params.init(*data_tree); - reset_current_external_function_options(); - - lexer = new DynareFlex(&in); - lexer->set_debug(debug); - - Dynare::parser parser(*this); - parser.set_debug_level(debug); - parser.parse(); - - delete lexer; - - return mod_file; -} - -void -ParsingDriver::error(const Dynare::parser::location_type &l, const string &m) -{ - create_error_string(l, m, cerr); - exit(EXIT_FAILURE); -} - -void -ParsingDriver::error(const string &m) -{ - error(location, m); -} - -void -ParsingDriver::create_error_string(const Dynare::parser::location_type &l, const string &m, ostream &stream) -{ - stream << "ERROR: " << *l.begin.filename << ": line " << l.begin.line; - if (l.begin.line == l.end.line) - if (l.begin.column == l.end.column - 1) - stream << ", col " << l.begin.column; - else - stream << ", cols " << l.begin.column << "-" << l.end.column - 1; - else - stream << ", col " << l.begin.column << " -" - << " line " << l.end.line << ", col " << l.end.column - 1; - stream << ": " << m << endl; -} - -void -ParsingDriver::model_error(const string &m) -{ - create_error_string(location, m, model_errors); - model_error_encountered = true; -} - -void -ParsingDriver::warning(const string &m) -{ - warnings << "WARNING: " << location << ": " << m << endl; -} - -void -ParsingDriver::declare_symbol(const string *name, SymbolType type, const string *tex_name, const vector *> *partition_value) -{ - try - { - if (tex_name == NULL && partition_value == NULL) - mod_file->symbol_table.addSymbol(*name, type); - else - if (tex_name == NULL) - mod_file->symbol_table.addSymbol(*name, type, "", partition_value); - else if (partition_value == NULL) - mod_file->symbol_table.addSymbol(*name, type, *tex_name, NULL); - else - mod_file->symbol_table.addSymbol(*name, type, *tex_name, partition_value); - } - catch (SymbolTable::AlreadyDeclaredException &e) - { - if (e.same_type) - warning("Symbol " + *name + " declared twice."); - else - error("Symbol " + *name + " declared twice with different types!"); - } -} - -void -ParsingDriver::declare_endogenous(string *name, string *tex_name, vector *> *partition_value) -{ - declare_symbol(name, eEndogenous, tex_name, partition_value); - delete name; - if (tex_name != NULL) - delete tex_name; - if (partition_value != NULL) - { - for (vector *>::iterator it = partition_value->begin(); - it != partition_value->end(); ++it) - { - delete (*it)->first; - delete (*it)->second; - delete (*it); - } - delete partition_value; - } -} - -void -ParsingDriver::declare_exogenous(string *name, string *tex_name, vector *> *partition_value) -{ - declare_symbol(name, eExogenous, tex_name, partition_value); - delete name; - if (tex_name != NULL) - delete tex_name; - if (partition_value != NULL) - { - for (vector *>::iterator it = partition_value->begin(); - it != partition_value->end(); ++it) - { - delete (*it)->first; - delete (*it)->second; - delete (*it); - } - delete partition_value; - } -} - -void -ParsingDriver::declare_exogenous_det(string *name, string *tex_name, vector *> *partition_value) -{ - declare_symbol(name, eExogenousDet, tex_name, partition_value); - delete name; - if (tex_name != NULL) - delete tex_name; - if (partition_value != NULL) - { - for (vector *>::iterator it = partition_value->begin(); - it != partition_value->end(); ++it) - { - delete (*it)->first; - delete (*it)->second; - delete (*it); - } - delete partition_value; - } -} - -void -ParsingDriver::declare_parameter(string *name, string *tex_name, vector *> *partition_value) -{ - declare_symbol(name, eParameter, tex_name, partition_value); - delete name; - if (tex_name != NULL) - delete tex_name; - if (partition_value != NULL) - { - for (vector *>::iterator it = partition_value->begin(); - it != partition_value->end(); ++it) - { - delete (*it)->first; - delete (*it)->second; - delete (*it); - } - delete partition_value; - } -} - -void -ParsingDriver::declare_statement_local_variable(string *name) -{ - if (mod_file->symbol_table.exists(*name)) - error("Symbol " + *name + " cannot be assigned within a statement " - +"while being assigned elsewhere in the modfile"); - declare_symbol(name, eStatementDeclaredVariable, NULL, NULL); - delete name; -} - -void -ParsingDriver::declare_optimal_policy_discount_factor_parameter(expr_t exprnode) -{ - string *optimalParName_declare = new string("optimal_policy_discount_factor"); - string *optimalParName_init = new string("optimal_policy_discount_factor"); - declare_parameter(optimalParName_declare, NULL); - init_param(optimalParName_init, exprnode); -} - -void -ParsingDriver::begin_trend() -{ - set_current_data_tree(&mod_file->dynamic_model); -} - -void -ParsingDriver::declare_trend_var(bool log_trend, string *name, string *tex_name) -{ - declare_symbol(name, log_trend ? eLogTrend : eTrend, tex_name, NULL); - declared_trend_vars.push_back(mod_file->symbol_table.getID(*name)); - delete name; - if (tex_name != NULL) - delete tex_name; -} - -void -ParsingDriver::end_trend_var(expr_t growth_factor) -{ - try - { - dynamic_model->addTrendVariables(declared_trend_vars, growth_factor); - } - catch (DataTree::TrendException &e) - { - error("Trend variable " + e.name + " was declared twice."); - } - declared_trend_vars.clear(); - reset_data_tree(); -} - -void -ParsingDriver::add_predetermined_variable(string *name) -{ - try - { - int symb_id = mod_file->symbol_table.getID(*name); - if (mod_file->symbol_table.getType(symb_id) != eEndogenous) - error("Predetermined variables must be endogenous variables"); - - mod_file->symbol_table.markPredetermined(symb_id); - } - catch (SymbolTable::UnknownSymbolNameException &e) - { - error("Undeclared symbol name: " + *name); - } - delete name; -} - -void -ParsingDriver::add_equation_tags(string *key, string *value) -{ - eq_tags.push_back(make_pair(*key, *value)); - delete key; - delete value; -} - -expr_t -ParsingDriver::add_non_negative_constant(string *constant) -{ - expr_t id = data_tree->AddNonNegativeConstant(*constant); - delete constant; - return id; -} - -expr_t -ParsingDriver::add_nan_constant() -{ - return data_tree->NaN; -} - -expr_t -ParsingDriver::add_inf_constant() -{ - return data_tree->Infinity; -} - -expr_t -ParsingDriver::add_model_variable(string *name) -{ - check_symbol_existence_in_model_block(*name); - int symb_id; - try - { - symb_id = mod_file->symbol_table.getID(*name); - if (undeclared_model_vars.find(*name) != undeclared_model_vars.end()) - model_error("Unknown symbol: " + *name); - } - catch (SymbolTable::UnknownSymbolNameException &e) - { - // This could be endog or param too. Just declare something to continue parsing, - // knowing that processing will end at the end of parsing of the model block - declare_exogenous(new string(*name)); - undeclared_model_vars.insert(*name); - symb_id = mod_file->symbol_table.getID(*name); - } - delete name; - return add_model_variable(symb_id, 0); -} - -expr_t -ParsingDriver::add_model_variable(int symb_id, int lag) -{ - assert(symb_id >= 0); - SymbolType type = mod_file->symbol_table.getType(symb_id); - - if (type == eModFileLocalVariable) - error("Variable " + mod_file->symbol_table.getName(symb_id) + " not allowed inside model declaration. Its scope is only outside model."); - - if (type == eExternalFunction) - error("Symbol " + mod_file->symbol_table.getName(symb_id) + " is a function name external to Dynare. It cannot be used like a variable without input argument inside model."); - - if (type == eModelLocalVariable && lag != 0) - error("Model local variable " + mod_file->symbol_table.getName(symb_id) + " cannot be given a lead or a lag."); - - if (dynamic_cast(model_tree) != NULL && lag != 0) - error("Leads and lags on variables are forbidden in 'planner_objective'."); - - if (dynamic_cast(model_tree) != NULL && type == eModelLocalVariable) - error("Model local variable " + mod_file->symbol_table.getName(symb_id) + " cannot be used in 'planner_objective'."); - - // It makes sense to allow a lead/lag on parameters: during steady state calibration, endogenous and parameters can be swapped - return model_tree->AddVariable(symb_id, lag); -} - -expr_t -ParsingDriver::add_expression_variable(string *name) -{ - // If symbol doesn't exist, then declare it as a mod file local variable - if (!mod_file->symbol_table.exists(*name)) - mod_file->symbol_table.addSymbol(*name, eModFileLocalVariable); - - // This check must come after the previous one! - if (mod_file->symbol_table.getType(*name) == eModelLocalVariable) - error("Variable " + *name + " not allowed outside model declaration. Its scope is only inside model."); - - if (mod_file->symbol_table.getType(*name) == eTrend - || mod_file->symbol_table.getType(*name) == eLogTrend) - error("Variable " + *name + " not allowed outside model declaration, because it is a trend variable."); - - if (mod_file->symbol_table.getType(*name) == eExternalFunction) - error("Symbol '" + *name + "' is the name of a MATLAB/Octave function, and cannot be used as a variable."); - - int symb_id = mod_file->symbol_table.getID(*name); - expr_t id = data_tree->AddVariable(symb_id); - - delete name; - return id; -} - -void -ParsingDriver::declare_nonstationary_var(string *name, string *tex_name, vector *> *partition_value) -{ - if (tex_name == NULL && partition_value == NULL) - declare_endogenous(new string(*name)); - else - if (tex_name == NULL) - declare_endogenous(new string(*name), NULL, partition_value); - else if (partition_value == NULL) - declare_endogenous(new string(*name), tex_name); - else - declare_endogenous(new string(*name), tex_name, partition_value); - - declared_nonstationary_vars.push_back(mod_file->symbol_table.getID(*name)); - mod_file->nonstationary_variables = true; - delete name; -} - -void -ParsingDriver::end_nonstationary_var(bool log_deflator, expr_t deflator) -{ - try - { - dynamic_model->addNonstationaryVariables(declared_nonstationary_vars, log_deflator, deflator); - } - catch (DataTree::TrendException &e) - { - error("Variable " + e.name + " was listed more than once as following a trend."); - } - - set r; - deflator->collectVariables(eEndogenous, r); - for (set::const_iterator it = r.begin(); it != r.end(); ++it) - if (dynamic_model->isNonstationary(*it)) - error("The deflator contains a non-stationary endogenous variable. This is not allowed. Please use only stationary endogenous and/or {log_}trend_vars."); - - declared_nonstationary_vars.clear(); - reset_data_tree(); -} - -void -ParsingDriver::periods(string *periods) -{ - warning("periods: this command is now deprecated and may be removed in a future version of Dynare. Please use the ''periods'' option of the ''simul'' command instead."); - - int periods_val = atoi(periods->c_str()); - mod_file->addStatement(new PeriodsStatement(periods_val)); - delete periods; -} - -void -ParsingDriver::dsample(string *arg1) -{ - int arg1_val = atoi(arg1->c_str()); - mod_file->addStatement(new DsampleStatement(arg1_val)); - delete arg1; -} - -void -ParsingDriver::dsample(string *arg1, string *arg2) -{ - int arg1_val = atoi(arg1->c_str()); - int arg2_val = atoi(arg2->c_str()); - mod_file->addStatement(new DsampleStatement(arg1_val, arg2_val)); - delete arg1; - delete arg2; -} - -void -ParsingDriver::init_param(string *name, expr_t rhs) -{ - check_symbol_is_parameter(name); - int symb_id = mod_file->symbol_table.getID(*name); - mod_file->addStatement(new InitParamStatement(symb_id, rhs, mod_file->symbol_table)); - delete name; -} - -void -ParsingDriver::init_val(string *name, expr_t rhs) -{ - if (nostrict) - if (!mod_file->symbol_table.exists(*name)) - { - warning("discarding '" + *name + "' as it was not recognized in the initval or endval statement"); - delete name; - return; - } - - check_symbol_existence(*name); - int symb_id = mod_file->symbol_table.getID(*name); - SymbolType type = mod_file->symbol_table.getType(symb_id); - - if (type != eEndogenous - && type != eExogenous - && type != eExogenousDet) - error("initval/endval: " + *name + " should be an endogenous or exogenous variable"); - - init_values.push_back(make_pair(symb_id, rhs)); - - delete name; -} - -void -ParsingDriver::initval_file(string *filename) -{ - mod_file->addStatement(new InitvalFileStatement(*filename)); - delete filename; -} - -void -ParsingDriver::hist_val(string *name, string *lag, expr_t rhs) -{ - check_symbol_existence(*name); - int symb_id = mod_file->symbol_table.getID(*name); - SymbolType type = mod_file->symbol_table.getType(symb_id); - - if (type != eEndogenous - && type != eExogenous - && type != eExogenousDet) - error("histval: " + *name + " should be an endogenous or exogenous variable"); - - int ilag = atoi(lag->c_str()); - if (ilag > 0) - error("histval: the lag on " + *name + " should be less than or equal to 0"); - - pair key(symb_id, ilag); - - if (mod_file->dynamic_model.minLagForSymbol(symb_id) > ilag - 1) - hist_vals_wrong_lag[symb_id] = ilag; - - if (hist_values.find(key) != hist_values.end()) - error("hist_val: (" + *name + ", " + *lag + ") declared twice"); - - hist_values[key] = rhs; - - delete name; - delete lag; -} - -void -ParsingDriver::homotopy_val(string *name, expr_t val1, expr_t val2) -{ - check_symbol_existence(*name); - int symb_id = mod_file->symbol_table.getID(*name); - SymbolType type = mod_file->symbol_table.getType(symb_id); - - if (type != eParameter - && type != eExogenous - && type != eExogenousDet) - error("homotopy_val: " + *name + " should be a parameter or exogenous variable"); - - homotopy_values.push_back(make_pair(symb_id, make_pair(val1, val2))); - - delete name; -} - -void -ParsingDriver::end_generate_irfs() -{ - mod_file->addStatement(new GenerateIRFsStatement(options_list, generate_irf_names, generate_irf_elements)); - - generate_irf_elements.clear(); - generate_irf_names.clear(); - options_list.clear(); -} - -void -ParsingDriver::add_generate_irfs_element(string *name) -{ - for (vector::const_iterator it = generate_irf_names.begin(); - it != generate_irf_names.end(); it++) - if (*it == *name) - error("Names in the generate_irfs block must be unique but you entered '" - + *name + "' more than once."); - - generate_irf_names.push_back(*name); - generate_irf_elements.push_back(generate_irf_exos); - - generate_irf_exos.clear(); - - delete name; -} - -void -ParsingDriver::add_generate_irfs_exog_element(string *exo, string *value) -{ - check_symbol_is_exogenous(exo); - if (generate_irf_exos.find(*exo) != generate_irf_exos.end()) - error("You have set the exogenous variable " + *exo + " twice."); - - generate_irf_exos[*exo] = atof(value->c_str()); - - delete exo; - delete value; -} - -void -ParsingDriver::forecast() -{ - mod_file->addStatement(new ForecastStatement(symbol_list, options_list)); - symbol_list.clear(); - options_list.clear(); -} - -void -ParsingDriver::use_dll() -{ - mod_file->use_dll = true; -} - -void -ParsingDriver::block() -{ - mod_file->block = true; -} - -void -ParsingDriver::no_static() -{ - mod_file->no_static = true; -} - -void -ParsingDriver::byte_code() -{ - mod_file->byte_code = true; -} - -void -ParsingDriver::differentiate_forward_vars_all() -{ - mod_file->differentiate_forward_vars = true; -} - -void -ParsingDriver::differentiate_forward_vars_some() -{ - mod_file->differentiate_forward_vars = true; - mod_file->differentiate_forward_vars_subset = symbol_list.get_symbols(); - for (vector::const_iterator it = mod_file->differentiate_forward_vars_subset.begin(); - it != mod_file->differentiate_forward_vars_subset.end(); ++it) - { - check_symbol_existence(*it); - if (mod_file->symbol_table.getType(*it) != eEndogenous) - error("Symbol " + *it + " is not an endogenous"); - } - symbol_list.clear(); -} - -void -ParsingDriver::cutoff(string *value) -{ - double val = atof(value->c_str()); - mod_file->dynamic_model.cutoff = val; - mod_file->static_model.cutoff = val; - delete value; -} - -void -ParsingDriver::mfs(string *value) -{ - int val = atoi(value->c_str()); - mod_file->dynamic_model.mfs = val; - mod_file->static_model.mfs = val; - delete value; -} - -void -ParsingDriver::end_initval(bool all_values_required) -{ - mod_file->addStatement(new InitValStatement(init_values, mod_file->symbol_table, all_values_required)); - init_values.clear(); -} - -void -ParsingDriver::end_endval(bool all_values_required) -{ - mod_file->addStatement(new EndValStatement(init_values, mod_file->symbol_table, all_values_required)); - init_values.clear(); -} - -void -ParsingDriver::end_histval(bool all_values_required) -{ - mod_file->addStatement(new HistValStatement(hist_values, hist_vals_wrong_lag, mod_file->symbol_table, all_values_required)); - hist_values.clear(); -} - -void -ParsingDriver::end_homotopy() -{ - mod_file->addStatement(new HomotopyStatement(homotopy_values, mod_file->symbol_table)); - homotopy_values.clear(); -} - -void -ParsingDriver::begin_model() -{ - set_current_data_tree(&mod_file->dynamic_model); -} - -void -ParsingDriver::end_model() -{ - if (model_error_encountered) - { - cerr << model_errors.str(); - exit(EXIT_FAILURE); - } - reset_data_tree(); -} - -void -ParsingDriver::end_shocks(bool overwrite) -{ - mod_file->addStatement(new ShocksStatement(overwrite, det_shocks, var_shocks, std_shocks, - covar_shocks, corr_shocks, mod_file->symbol_table)); - det_shocks.clear(); - var_shocks.clear(); - std_shocks.clear(); - covar_shocks.clear(); - corr_shocks.clear(); -} - -void -ParsingDriver::end_mshocks(bool overwrite) -{ - mod_file->addStatement(new MShocksStatement(overwrite, det_shocks, mod_file->symbol_table)); - det_shocks.clear(); -} - -void -ParsingDriver::add_det_shock(string *var, bool conditional_forecast) -{ - check_symbol_existence(*var); - int symb_id = mod_file->symbol_table.getID(*var); - SymbolType type = mod_file->symbol_table.getType(symb_id); - - if (conditional_forecast) - { - if (type != eEndogenous) - error("conditional_forecast_paths: shocks can only be applied to endogenous variables"); - } - else - { - if (type != eExogenous && type != eExogenousDet) - error("shocks: shocks can only be applied to exogenous variables"); - } - - if (det_shocks.find(symb_id) != det_shocks.end()) - error("shocks/conditional_forecast_paths: variable " + *var + " declared twice"); - - if (det_shocks_periods.size() != det_shocks_values.size()) - error("shocks/conditional_forecast_paths: variable " + *var + ": number of periods is different from number of shock values"); - - vector v; - - for (size_t i = 0; i < det_shocks_periods.size(); i++) - { - ShocksStatement::DetShockElement dse; - dse.period1 = det_shocks_periods[i].first; - dse.period2 = det_shocks_periods[i].second; - dse.value = det_shocks_values[i]; - v.push_back(dse); - } - - det_shocks[symb_id] = v; - - det_shocks_periods.clear(); - det_shocks_values.clear(); - delete var; -} - -void -ParsingDriver::add_stderr_shock(string *var, expr_t value) -{ - check_symbol_existence(*var); - int symb_id = mod_file->symbol_table.getID(*var); - - if (var_shocks.find(symb_id) != var_shocks.end() - || std_shocks.find(symb_id) != std_shocks.end()) - error("shocks: variance or stderr of shock on " + *var + " declared twice"); - - std_shocks[symb_id] = value; - - delete var; -} - -void -ParsingDriver::add_var_shock(string *var, expr_t value) -{ - check_symbol_existence(*var); - int symb_id = mod_file->symbol_table.getID(*var); - - if (var_shocks.find(symb_id) != var_shocks.end() - || std_shocks.find(symb_id) != std_shocks.end()) - error("shocks: variance or stderr of shock on " + *var + " declared twice"); - - var_shocks[symb_id] = value; - - delete var; -} - -void -ParsingDriver::add_covar_shock(string *var1, string *var2, expr_t value) -{ - check_symbol_existence(*var1); - check_symbol_existence(*var2); - int symb_id1 = mod_file->symbol_table.getID(*var1); - int symb_id2 = mod_file->symbol_table.getID(*var2); - - pair key(symb_id1, symb_id2), key_inv(symb_id2, symb_id1); - - if (covar_shocks.find(key) != covar_shocks.end() - || covar_shocks.find(key_inv) != covar_shocks.end() - || corr_shocks.find(key) != corr_shocks.end() - || corr_shocks.find(key_inv) != corr_shocks.end()) - error("shocks: covariance or correlation shock on variable pair (" + *var1 + ", " - + *var2 + ") declared twice"); - - covar_shocks[key] = value; - - delete var1; - delete var2; -} - -void -ParsingDriver::add_correl_shock(string *var1, string *var2, expr_t value) -{ - check_symbol_existence(*var1); - check_symbol_existence(*var2); - int symb_id1 = mod_file->symbol_table.getID(*var1); - int symb_id2 = mod_file->symbol_table.getID(*var2); - - pair key(symb_id1, symb_id2), key_inv(symb_id2, symb_id1); - - if (covar_shocks.find(key) != covar_shocks.end() - || covar_shocks.find(key_inv) != covar_shocks.end() - || corr_shocks.find(key) != corr_shocks.end() - || corr_shocks.find(key_inv) != corr_shocks.end()) - error("shocks: covariance or correlation shock on variable pair (" + *var1 + ", " - + *var2 + ") declared twice"); - - corr_shocks[key] = value; - - delete var1; - delete var2; -} - -void -ParsingDriver::add_period(string *p1, string *p2) -{ - int p1_val = atoi(p1->c_str()); - int p2_val = atoi(p2->c_str()); - if (p1_val > p2_val) - error("shocks/conditional_forecast_paths: can't have first period index greater than second index in range specification"); - det_shocks_periods.push_back(make_pair(p1_val, p2_val)); - delete p1; - delete p2; -} - -void -ParsingDriver::add_period(string *p1) -{ - int p1_val = atoi(p1->c_str()); - det_shocks_periods.push_back(make_pair(p1_val, p1_val)); - delete p1; -} - -void -ParsingDriver::add_value(expr_t value) -{ - det_shocks_values.push_back(value); -} - -void -ParsingDriver::add_value(string *v) -{ - expr_t id; - - if (v->at(0) == '-') - id = data_tree->AddUMinus(data_tree->AddNonNegativeConstant(v->substr(1, string::npos))); - else - id = data_tree->AddNonNegativeConstant(*v); - - delete v; - det_shocks_values.push_back(id); -} - -void -ParsingDriver::begin_svar_identification() -{ - svar_upper_cholesky = false; - svar_lower_cholesky = false; - svar_constants_exclusion = false; -} - -void -ParsingDriver::end_svar_identification() -{ - mod_file->addStatement(new SvarIdentificationStatement(svar_ident_restrictions, - svar_upper_cholesky, - svar_lower_cholesky, - svar_constants_exclusion, - mod_file->symbol_table)); - svar_restriction_symbols.clear(); - svar_equation_restrictions.clear(); - svar_ident_restrictions.clear(); - svar_Qi_restriction_nbr.clear(); - svar_Ri_restriction_nbr.clear(); -} - -void -ParsingDriver::combine_lag_and_restriction(string *lag) -{ - int current_lag = atoi(lag->c_str()); - - for (SvarIdentificationStatement::svar_identification_restrictions_t::const_iterator it = svar_ident_restrictions.begin(); - it != svar_ident_restrictions.end(); it++) - if (it->lag == current_lag) - error("lag " + *lag + " used more than once."); - - for (map >::const_iterator it = svar_equation_restrictions.begin(); - it != svar_equation_restrictions.end(); it++) - for (vector::const_iterator it1 = it->second.begin(); - it1 != it->second.end(); it1++) - { - SvarIdentificationStatement::svar_identification_restriction new_restriction; - new_restriction.equation = it->first; - if (current_lag > 0) - new_restriction.restriction_nbr = ++svar_Ri_restriction_nbr[it->first]; - else - new_restriction.restriction_nbr = ++svar_Qi_restriction_nbr[it->first]; - new_restriction.lag = current_lag; - new_restriction.variable = *it1; - new_restriction.value = data_tree->One; - svar_ident_restrictions.push_back(new_restriction); - } - // svar_ident_exclusion_values[make_pair(current_lag, it->first)] = it->second; - - svar_upper_cholesky = false; - svar_lower_cholesky = false; - svar_equation_restrictions.clear(); - delete lag; -} - -void -ParsingDriver::add_restriction_in_equation(string *equation) -{ - int eqn = atoi(equation->c_str()); - if (eqn < 1) - error("equation numbers must be greater than or equal to 1."); - - if (svar_equation_restrictions.count(eqn) > 0) - error("equation number " + *equation + " referenced more than once under a single lag."); - - svar_equation_restrictions[eqn] = svar_restriction_symbols; - - svar_restriction_symbols.clear(); - delete equation; -} - -void -ParsingDriver::add_in_svar_restriction_symbols(string *tmp_var) -{ - check_symbol_existence(*tmp_var); - int symb_id = mod_file->symbol_table.getID(*tmp_var); - - for (vector::const_iterator viit = svar_restriction_symbols.begin(); - viit != svar_restriction_symbols.end(); viit++) - if (symb_id == *viit) - error(*tmp_var + " restriction added twice."); - - svar_restriction_symbols.push_back(symb_id); - delete tmp_var; -} - -void -ParsingDriver::add_restriction_equation_nbr(string *eq_nbr) -{ - svar_equation_nbr = atoi(eq_nbr->c_str()); - svar_left_handside = true; - // reinitialize restriction type that must be set from the first restriction element - svar_restriction_type = ParsingDriver::NOT_SET; -} - -void -ParsingDriver::add_restriction_equal() -{ - if (svar_left_handside) - svar_left_handside = false; - else - error("svar_identification: there are more than one EQUAL sign in a restriction equation"); -} - -void -ParsingDriver::add_positive_restriction_element(expr_t value, string *variable, string *lag) -{ - // if the expression is not on the left handside, change its sign - if (!svar_left_handside) - value = add_uminus(value); - - add_restriction_element(value, variable, lag); -} - -void -ParsingDriver::add_positive_restriction_element(string *variable, string *lag) -{ - expr_t value(data_tree->One); - - // if the expression is not on the left handside, change its sign - if (!svar_left_handside) - value = add_uminus(value); - - add_restriction_element(value, variable, lag); -} - -void -ParsingDriver::add_negative_restriction_element(expr_t value, string *variable, string *lag) -{ - // if the expression is on the left handside, change its sign - if (svar_left_handside) - value = add_uminus(value); - - add_restriction_element(value, variable, lag); -} - -void -ParsingDriver::add_negative_restriction_element(string *variable, string *lag) -{ - expr_t value(data_tree->One); - - // if the expression is on the left handside, change its sign - if (svar_left_handside) - value = add_uminus(value); - - add_restriction_element(value, variable, lag); -} - -void -ParsingDriver::add_restriction_element(expr_t value, string *variable, string *lag) -{ - check_symbol_existence(*variable); - int symb_id = mod_file->symbol_table.getID(*variable); - - int current_lag = atoi(lag->c_str()); - if (svar_restriction_type == ParsingDriver::NOT_SET) - { - if (current_lag == 0) - { - svar_restriction_type = ParsingDriver::Qi_TYPE; - ++svar_Qi_restriction_nbr[svar_equation_nbr]; - } - else - { - svar_restriction_type = ParsingDriver::Ri_TYPE; - ++svar_Ri_restriction_nbr[svar_equation_nbr]; - } - } - else - { - if ((svar_restriction_type == Qi_TYPE && current_lag > 0) - || (svar_restriction_type == Ri_TYPE && current_lag == 0)) - error("SVAR_IDENTIFICATION: a single restrictions must affect either Qi or Ri, but not both"); - } - SvarIdentificationStatement::svar_identification_restriction new_restriction; - new_restriction.equation = svar_equation_nbr; - if (current_lag > 0) - new_restriction.restriction_nbr = svar_Ri_restriction_nbr[svar_equation_nbr]; - else - new_restriction.restriction_nbr = svar_Qi_restriction_nbr[svar_equation_nbr]; - new_restriction.lag = current_lag; - new_restriction.variable = symb_id; - new_restriction.value = value; - - svar_ident_restrictions.push_back(new_restriction); -} - -void -ParsingDriver::check_restriction_expression_constant(expr_t value) -{ - if (value->eval(eval_context_t()) != 0) - error("SVAR_INDENTIFICATION restrictions must be homogenous"); -} - -void -ParsingDriver::add_upper_cholesky() -{ - svar_upper_cholesky = true; -} - -void -ParsingDriver::add_lower_cholesky() -{ - svar_lower_cholesky = true; -} - -void -ParsingDriver::add_constants_exclusion() -{ - svar_constants_exclusion = true; -} - -void -ParsingDriver::add_svar_global_identification_check() -{ - mod_file->addStatement(new SvarGlobalIdentificationCheckStatement); -} - -void -ParsingDriver::do_sigma_e() -{ - warning("Sigma_e: this command is now deprecated and may be removed in a future version of Dynare. Please use the ''shocks'' command instead."); - - try - { - mod_file->addStatement(new SigmaeStatement(sigmae_matrix)); - } - catch (SigmaeStatement::MatrixFormException &e) - { - error("Sigma_e: matrix is neither upper triangular nor lower triangular"); - } - sigmae_matrix.clear(); -} - -void -ParsingDriver::end_of_row() -{ - sigmae_matrix.push_back(sigmae_row); - sigmae_row.clear(); -} - -void -ParsingDriver::add_to_row_const(string *v) -{ - expr_t id; - - if (v->at(0) == '-') - id = data_tree->AddUMinus(data_tree->AddNonNegativeConstant(v->substr(1, string::npos))); - else - id = data_tree->AddNonNegativeConstant(*v); - - delete v; - sigmae_row.push_back(id); -} - -void -ParsingDriver::add_to_row(expr_t v) -{ - sigmae_row.push_back(v); -} - -void -ParsingDriver::steady() -{ - mod_file->addStatement(new SteadyStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::option_num(const string &name_option, string *opt1, string *opt2) -{ - if (options_list.paired_num_options.find(name_option) - != options_list.paired_num_options.end()) - error("option " + name_option + " declared twice"); - - options_list.paired_num_options[name_option] = make_pair(*opt1, *opt2); - delete opt1; - delete opt2; -} - -void -ParsingDriver::option_num(const string &name_option, string *opt) -{ - option_num(name_option, *opt); - delete opt; -} - -void -ParsingDriver::option_num(const string &name_option, const string &opt) -{ - if (options_list.num_options.find(name_option) != options_list.num_options.end()) - error("option " + name_option + " declared twice"); - - options_list.num_options[name_option] = opt; -} - -void -ParsingDriver::option_str(const string &name_option, string *opt) -{ - option_str(name_option, *opt); - delete opt; -} - -void -ParsingDriver::option_str(const string &name_option, const string &opt) -{ - if (options_list.string_options.find(name_option) - != options_list.string_options.end()) - error("option " + name_option + " declared twice"); - - options_list.string_options[name_option] = opt; -} - -void -ParsingDriver::option_date(const string &name_option, string *opt) -{ - option_date(name_option, *opt); - delete opt; -} - -void -ParsingDriver::option_date(const string &name_option, const string &opt) -{ - if (options_list.date_options.find(name_option) - != options_list.date_options.end()) - error("option " + name_option + " declared twice"); - - options_list.date_options[name_option] = opt; -} - -void -ParsingDriver::option_symbol_list(const string &name_option) -{ - if (options_list.symbol_list_options.find(name_option) - != options_list.symbol_list_options.end()) - error("option " + name_option + " declared twice"); - - if (name_option.compare("irf_shocks") == 0) - { - vector shocks = symbol_list.get_symbols(); - for (vector::const_iterator it = shocks.begin(); - it != shocks.end(); it++) - if (mod_file->symbol_table.getType(*it) != eExogenous) - error("Variables passed to irf_shocks must be exogenous. Caused by: " + *it); - } - - if (name_option.compare("ms.parameters") == 0) - { - vector parameters = symbol_list.get_symbols(); - for (vector::const_iterator it = parameters.begin(); - it != parameters.end(); it++) - if (mod_file->symbol_table.getType(*it) != eParameter) - error("Variables passed to the parameters option of the markov_switching statement must be parameters. Caused by: " + *it); - } - - options_list.symbol_list_options[name_option] = symbol_list; - symbol_list.clear(); -} - -void -ParsingDriver::option_vec_int(const string &name_option, const vector *opt) -{ - if (options_list.vector_int_options.find(name_option) - != options_list.vector_int_options.end()) - error("option " + name_option + " declared twice"); - - if ((*opt).empty()) - error("option " + name_option + " was passed an empty vector."); - - options_list.vector_int_options[name_option] = *opt; - delete opt; -} - -void -ParsingDriver::linear() -{ - mod_file->linear = true; -} - -void -ParsingDriver::add_in_symbol_list(string *tmp_var) -{ - if (*tmp_var != ":") - check_symbol_existence(*tmp_var); - symbol_list.addSymbol(*tmp_var); - delete tmp_var; -} - -void -ParsingDriver::rplot() -{ - mod_file->addStatement(new RplotStatement(symbol_list)); - symbol_list.clear(); -} - -void -ParsingDriver::stoch_simul() -{ - mod_file->addStatement(new StochSimulStatement(symbol_list, options_list)); - symbol_list.clear(); - options_list.clear(); -} - -void -ParsingDriver::simul() -{ - mod_file->addStatement(new SimulStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::model_info() -{ - mod_file->addStatement(new ModelInfoStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::check() -{ - mod_file->addStatement(new CheckStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::add_estimated_params_element() -{ - if (estim_params.name != "dsge_prior_weight") - { - check_symbol_existence(estim_params.name); - SymbolType type = mod_file->symbol_table.getType(estim_params.name); - switch (estim_params.type) - { - case 1: - if (type != eEndogenous && type != eExogenous) - error(estim_params.name + " must be an endogenous or an exogenous variable"); - break; - case 2: - check_symbol_is_parameter(&estim_params.name); - break; - case 3: - check_symbol_existence(estim_params.name2); - SymbolType type2 = mod_file->symbol_table.getType(estim_params.name2); - if ((type != eEndogenous && type != eExogenous) || type != type2) - error(estim_params.name + " and " + estim_params.name2 + " must either be both endogenous variables or both exogenous"); - break; - } - } - estim_params_list.push_back(estim_params); - estim_params.init(*data_tree); -} - -void -ParsingDriver::estimated_params() -{ - mod_file->addStatement(new EstimatedParamsStatement(estim_params_list, mod_file->symbol_table)); - estim_params_list.clear(); -} - -void -ParsingDriver::estimated_params_init(bool use_calibration) -{ - mod_file->addStatement(new EstimatedParamsInitStatement(estim_params_list, mod_file->symbol_table, use_calibration)); - estim_params_list.clear(); -} - -void -ParsingDriver::estimated_params_bounds() -{ - mod_file->addStatement(new EstimatedParamsBoundsStatement(estim_params_list, mod_file->symbol_table)); - estim_params_list.clear(); -} - -void -ParsingDriver::add_osr_params_element() -{ - check_symbol_existence(osr_params.name); - SymbolType type = mod_file->symbol_table.getType(osr_params.name); - if (type != eParameter) - error(osr_params.name + " must be a parameter to be used in the osr_bounds block"); - osr_params_list.push_back(osr_params); - osr_params.init(*data_tree); -} - -void -ParsingDriver::osr_params_bounds() -{ - mod_file->addStatement(new OsrParamsBoundsStatement(osr_params_list)); - osr_params_list.clear(); -} - -void -ParsingDriver::set_unit_root_vars() -{ - mod_file->addStatement(new UnitRootVarsStatement()); - warning("''unit_root_vars'' is now obsolete; use the ''diffuse_filter'' option of ''estimation'' instead"); - symbol_list.clear(); -} - -void -ParsingDriver::set_time(string *arg) -{ - option_date("initial_period", arg); - mod_file->addStatement(new SetTimeStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::estimation_data() -{ - mod_file->addStatement(new EstimationDataStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::set_subsamples(string *name1, string *name2) -{ - check_symbol_existence(*name1); - if (!name2->empty()) - check_symbol_existence(*name2); - - mod_file->addStatement(new SubsamplesStatement(*name1, *name2, subsample_declaration_map, - mod_file->symbol_table)); - subsample_declarations[make_pair(*name1, *name2)] = subsample_declaration_map; - subsample_declaration_map.clear(); - delete name1; - delete name2; -} - -void -ParsingDriver::copy_subsamples(string *to_name1, string *to_name2, string *from_name1, string *from_name2) -{ - check_symbol_existence(*to_name1); - check_symbol_existence(*from_name1); - if (!to_name2->empty()) - check_symbol_existence(*to_name2); - if (!from_name2->empty()) - check_symbol_existence(*from_name2); - - if (subsample_declarations.find(make_pair(*from_name1, *from_name2)) == subsample_declarations.end()) - { - string err = *from_name1; - if (!from_name2->empty()) - err.append(",").append(*from_name2); - error(err + " does not have an associated subsample statement."); - } - - mod_file->addStatement(new SubsamplesEqualStatement(*to_name1, *to_name2, *from_name1, *from_name2, - mod_file->symbol_table)); - - subsample_declarations[make_pair(*to_name1, *to_name2)] - = subsample_declarations[make_pair(*from_name1, *from_name2)]; - - delete to_name1; - delete to_name2; - delete from_name1; - delete from_name2; -} - -void -ParsingDriver::check_symbol_is_statement_variable(string *name) -{ - check_symbol_existence(*name); - int symb_id = mod_file->symbol_table.getID(*name); - if (mod_file->symbol_table.getType(symb_id) != eStatementDeclaredVariable) - error(*name + " is not a variable assigned in a statement"); -} - -void -ParsingDriver::set_subsample_name_equal_to_date_range(string *name, string *date1, string *date2) -{ - if (subsample_declaration_map.find(*name) != subsample_declaration_map.end()) - error("Symbol " + *name + " may only be assigned once in a SUBSAMPLE statement"); - subsample_declaration_map[*name] = make_pair(*date1, *date2); - delete name; - delete date1; - delete date2; -} - -void -ParsingDriver::check_subsample_declaration_exists(string *name1, string *subsample_name) -{ - if (subsample_name->empty()) - return; - - string *str_empty = new string(""); - check_subsample_declaration_exists(name1, str_empty, subsample_name); - delete str_empty; -} - -void -ParsingDriver::check_subsample_declaration_exists(string *name1, string *name2, string *subsample_name) -{ - if (subsample_name->empty()) - return; - - check_symbol_existence(*name1); - if (!name2->empty()) - check_symbol_existence(*name2); - - subsample_declarations_t::const_iterator it = subsample_declarations.find(make_pair(*name1, *name2)); - if (it == subsample_declarations.end()) - { - it = subsample_declarations.find(make_pair(*name2, *name1)); - if (it == subsample_declarations.end()) - { - string err = *name1; - if (!name2->empty()) - err.append(",").append(*name2); - error("A subsample statement has not been issued for " + err); - } - } - - SubsamplesStatement::subsample_declaration_map_t tmp_map = it->second; - if (tmp_map.find(*subsample_name) == tmp_map.end()) - error("The subsample name " + *subsample_name + " was not previously declared in a subsample statement."); -} - -void -ParsingDriver::set_prior(string *name, string *subsample_name) -{ - check_symbol_is_parameter(name); - check_subsample_declaration_exists(name, subsample_name); - mod_file->addStatement(new PriorStatement(*name, *subsample_name, prior_shape, prior_variance, options_list)); - options_list.clear(); - set_prior_variance(); - prior_shape = eNoShape; - delete name; - delete subsample_name; -} - -void -ParsingDriver::set_joint_prior(vector *symbol_vec) -{ - for (vector::const_iterator it = symbol_vec->begin(); it != symbol_vec->end(); it++) - add_joint_parameter(*it); - mod_file->addStatement(new JointPriorStatement(joint_parameters, prior_shape, options_list)); - joint_parameters.clear(); - options_list.clear(); - prior_shape = eNoShape; - delete symbol_vec; -} - -void -ParsingDriver::add_joint_parameter(string *name) -{ - check_symbol_is_parameter(name); - joint_parameters.push_back(*name); - delete name; -} - -void -ParsingDriver::set_prior_variance(expr_t variance) -{ - prior_variance = variance; -} - -void -ParsingDriver::copy_prior(string *to_declaration_type, string *to_name1, string *to_name2, string *to_subsample_name, - string *from_declaration_type, string *from_name1, string *from_name2, string *from_subsample_name) -{ - if (strcmp(to_declaration_type->c_str(), "par") == 0) - check_symbol_is_parameter(to_name1); - else - { - check_symbol_is_endogenous_or_exogenous(to_name1); - if (!to_name2->empty()) - check_symbol_is_endogenous_or_exogenous(to_name2); - } - - if (strcmp(from_declaration_type->c_str(), "par") == 0) - check_symbol_is_parameter(from_name1); - else - { - check_symbol_is_endogenous_or_exogenous(from_name1); - if (!from_name2->empty()) - check_symbol_is_endogenous_or_exogenous(from_name2); - } - - mod_file->addStatement(new PriorEqualStatement(*to_declaration_type, *to_name1, *to_name2, *to_subsample_name, - *from_declaration_type, *from_name1, *from_name2, *from_subsample_name, - mod_file->symbol_table)); - - delete to_declaration_type; - delete to_name1; - delete to_name2; - delete to_subsample_name; - delete from_declaration_type; - delete from_name1; - delete from_name2; - delete from_subsample_name; -} - -void -ParsingDriver::set_options(string *name, string *subsample_name) -{ - check_symbol_is_parameter(name); - check_subsample_declaration_exists(name, subsample_name); - mod_file->addStatement(new OptionsStatement(*name, *subsample_name, options_list)); - options_list.clear(); - delete name; - delete subsample_name; -} - -void -ParsingDriver::copy_options(string *to_declaration_type, string *to_name1, string *to_name2, string *to_subsample_name, - string *from_declaration_type, string *from_name1, string *from_name2, string *from_subsample_name) -{ - if (strcmp(to_declaration_type->c_str(), "par") == 0) - check_symbol_is_parameter(to_name1); - else - { - check_symbol_is_endogenous_or_exogenous(to_name1); - if (!to_name2->empty()) - check_symbol_is_endogenous_or_exogenous(to_name2); - } - - if (strcmp(from_declaration_type->c_str(), "par") == 0) - check_symbol_is_parameter(from_name1); - else - { - check_symbol_is_endogenous_or_exogenous(from_name1); - if (!from_name2->empty()) - check_symbol_is_endogenous_or_exogenous(from_name2); - } - - mod_file->addStatement(new OptionsEqualStatement(*to_declaration_type, *to_name1, *to_name2, *to_subsample_name, - *from_declaration_type, *from_name1, *from_name2, *from_subsample_name, - mod_file->symbol_table)); - delete to_declaration_type; - delete to_name1; - delete to_name2; - delete to_subsample_name; - delete from_declaration_type; - delete from_name1; - delete from_name2; - delete from_subsample_name; -} - -void -ParsingDriver::check_symbol_is_endogenous_or_exogenous(string *name) -{ - check_symbol_existence(*name); - int symb_id = mod_file->symbol_table.getID(*name); - switch (mod_file->symbol_table.getType(symb_id)) - { - case eEndogenous: - case eExogenous: - case eExogenousDet: - break; - default: - error(*name + " is neither endogenous or exogenous."); - } -} - -void -ParsingDriver::check_symbol_is_exogenous(string *name) -{ - check_symbol_existence(*name); - int symb_id = mod_file->symbol_table.getID(*name); - switch (mod_file->symbol_table.getType(symb_id)) - { - case eExogenous: - case eExogenousDet: - break; - default: - error(*name + " is not exogenous."); - } -} - -void -ParsingDriver::set_std_prior(string *name, string *subsample_name) -{ - check_symbol_is_endogenous_or_exogenous(name); - check_subsample_declaration_exists(name, subsample_name); - mod_file->addStatement(new StdPriorStatement(*name, *subsample_name, prior_shape, prior_variance, - options_list, mod_file->symbol_table)); - options_list.clear(); - set_prior_variance(); - prior_shape = eNoShape; - delete name; - delete subsample_name; -} - -void -ParsingDriver::set_std_options(string *name, string *subsample_name) -{ - check_symbol_is_endogenous_or_exogenous(name); - check_subsample_declaration_exists(name, subsample_name); - mod_file->addStatement(new StdOptionsStatement(*name, *subsample_name, options_list, mod_file->symbol_table)); - options_list.clear(); - delete name; - delete subsample_name; -} - -void -ParsingDriver::set_corr_prior(string *name1, string *name2, string *subsample_name) -{ - check_symbol_is_endogenous_or_exogenous(name1); - check_symbol_is_endogenous_or_exogenous(name2); - check_subsample_declaration_exists(name1, name2, subsample_name); - mod_file->addStatement(new CorrPriorStatement(*name1, *name2, *subsample_name, prior_shape, prior_variance, - options_list, mod_file->symbol_table)); - options_list.clear(); - set_prior_variance(); - prior_shape = eNoShape; - delete name1; - delete name2; - delete subsample_name; -} - -void -ParsingDriver::set_corr_options(string *name1, string *name2, string *subsample_name) -{ - check_symbol_is_endogenous_or_exogenous(name1); - check_symbol_is_endogenous_or_exogenous(name2); - check_subsample_declaration_exists(name1, name2, subsample_name); - mod_file->addStatement(new CorrOptionsStatement(*name1, *name2, *subsample_name, options_list, mod_file->symbol_table)); - options_list.clear(); - delete name1; - delete name2; - delete subsample_name; -} - -void -ParsingDriver::run_estimation() -{ - mod_file->addStatement(new EstimationStatement(symbol_list, options_list)); - symbol_list.clear(); - options_list.clear(); -} - -void -ParsingDriver::dynare_sensitivity() -{ - mod_file->addStatement(new DynareSensitivityStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::optim_options_helper(const string &name) -{ - if (options_list.string_options.find("optim_opt") == options_list.string_options.end()) - options_list.string_options["optim_opt"] = ""; - else - options_list.string_options["optim_opt"] += ","; - options_list.string_options["optim_opt"] += "''" + name + "'',"; -} - -void -ParsingDriver::optim_options_string(string *name, string *value) -{ - optim_options_helper(*name); - options_list.string_options["optim_opt"] += "''" + *value + "''"; - delete name; - delete value; -} - -void -ParsingDriver::optim_options_num(string *name, string *value) -{ - optim_options_helper(*name); - options_list.string_options["optim_opt"] += *value; - delete name; - delete value; -} - -void -ParsingDriver::sampling_options_helper(const string &name) -{ - if (options_list.string_options.find("posterior_sampler_options.sampling_opt") == - options_list.string_options.end()) - options_list.string_options["posterior_sampler_options.sampling_opt"] = ""; - else - options_list.string_options["posterior_sampler_options.sampling_opt"] += ","; - options_list.string_options["posterior_sampler_options.sampling_opt"] += "''" + name + "'',"; -} - -void -ParsingDriver::sampling_options_string(string *name, string *value) -{ - sampling_options_helper(*name); - options_list.string_options["posterior_sampler_options.sampling_opt"] += "''" + *value + "''"; - delete name; - delete value; -} - -void -ParsingDriver::sampling_options_num(string *name, string *value) -{ - sampling_options_helper(*name); - options_list.string_options["posterior_sampler_options.sampling_opt"] += *value; - delete name; - delete value; -} - -void -ParsingDriver::check_varobs() -{ - if (mod_file->symbol_table.observedVariablesNbr() > 0) - error("varobs: you cannot have several 'varobs' statements in the same MOD file"); -} - -void -ParsingDriver::add_varobs(string *name) -{ - check_symbol_existence(*name); - int symb_id = mod_file->symbol_table.getID(*name); - if (mod_file->symbol_table.getType(symb_id) != eEndogenous) - error("varobs: " + *name + " is not an endogenous variable"); - mod_file->symbol_table.addObservedVariable(symb_id); - delete name; -} - -void -ParsingDriver::set_trends() -{ - mod_file->addStatement(new ObservationTrendsStatement(trend_elements, mod_file->symbol_table)); - trend_elements.clear(); -} - -void -ParsingDriver::set_trend_element(string *arg1, expr_t arg2) -{ - check_symbol_existence(*arg1); - if (trend_elements.find(*arg1) != trend_elements.end()) - error("observation_trends: " + *arg1 + " declared twice"); - trend_elements[*arg1] = arg2; - delete arg1; -} - -void -ParsingDriver::set_optim_weights(string *name, expr_t value) -{ - check_symbol_existence(*name); - if (mod_file->symbol_table.getType(*name) != eEndogenous) - error("optim_weights: " + *name + " isn't an endogenous variable"); - if (var_weights.find(*name) != var_weights.end()) - error("optim_weights: " + *name + " declared twice"); - var_weights[*name] = value; - delete name; -} - -void -ParsingDriver::set_optim_weights(string *name1, string *name2, expr_t value) -{ - check_symbol_existence(*name1); - if (mod_file->symbol_table.getType(*name1) != eEndogenous) - error("optim_weights: " + *name1 + " isn't an endogenous variable"); - - check_symbol_existence(*name2); - if (mod_file->symbol_table.getType(*name2) != eEndogenous) - error("optim_weights: " + *name2 + " isn't an endogenous variable"); - - pair covar_key(*name1, *name2); - - if (covar_weights.find(covar_key) != covar_weights.end()) - error("optim_weights: pair of variables (" + *name1 + ", " + *name2 - + ") declared twice"); - - covar_weights[covar_key] = value; - delete name1; - delete name2; -} - -void -ParsingDriver::optim_weights() -{ - mod_file->addStatement(new OptimWeightsStatement(var_weights, covar_weights, mod_file->symbol_table)); - var_weights.clear(); - covar_weights.clear(); -} - -void -ParsingDriver::set_osr_params() -{ - mod_file->addStatement(new OsrParamsStatement(symbol_list, mod_file->symbol_table)); - symbol_list.clear(); -} - -void -ParsingDriver::run_osr() -{ - mod_file->addStatement(new OsrStatement(symbol_list, options_list)); - symbol_list.clear(); - options_list.clear(); -} - -void -ParsingDriver::run_dynatype(string *filename) -{ - mod_file->addStatement(new DynaTypeStatement(symbol_list, *filename)); - symbol_list.clear(); - delete filename; -} - -void -ParsingDriver::run_dynasave(string *filename) -{ - mod_file->addStatement(new DynaSaveStatement(symbol_list, *filename)); - symbol_list.clear(); - delete filename; -} - -void -ParsingDriver::run_load_params_and_steady_state(string *filename) -{ - mod_file->addStatement(new LoadParamsAndSteadyStateStatement(*filename, mod_file->symbol_table, warnings)); - delete filename; -} - -void -ParsingDriver::run_save_params_and_steady_state(string *filename) -{ - mod_file->addStatement(new SaveParamsAndSteadyStateStatement(*filename)); - delete filename; -} - -void -ParsingDriver::run_identification() -{ - mod_file->addStatement(new IdentificationStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::add_mc_filename(string *filename, string *prior) -{ - for (ModelComparisonStatement::filename_list_t::iterator it = filename_list.begin(); - it != filename_list.end(); it++) - if ((*it).first == *filename) - error("model_comparison: filename " + *filename + " declared twice"); - filename_list.push_back(make_pair(*filename, *prior)); - delete filename; - delete prior; -} - -void -ParsingDriver::run_model_comparison() -{ - mod_file->addStatement(new ModelComparisonStatement(filename_list, options_list)); - filename_list.clear(); - options_list.clear(); -} - -void -ParsingDriver::begin_planner_objective() -{ - set_current_data_tree(new StaticModel(mod_file->symbol_table, mod_file->num_constants, mod_file->external_functions_table)); -} - -void -ParsingDriver::end_planner_objective(expr_t expr) -{ - // Add equation corresponding to expression - expr_t eq = model_tree->AddEqual(expr, model_tree->Zero); - model_tree->addEquation(eq, location.begin.line); - - mod_file->addStatement(new PlannerObjectiveStatement(dynamic_cast(model_tree))); - - reset_data_tree(); -} - -void -ParsingDriver::ramsey_model() -{ - if (!mod_file->symbol_table.exists("optimal_policy_discount_factor")) - declare_optimal_policy_discount_factor_parameter(data_tree->One); - mod_file->addStatement(new RamseyModelStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::ramsey_policy() -{ - if (!mod_file->symbol_table.exists("optimal_policy_discount_factor")) - declare_optimal_policy_discount_factor_parameter(data_tree->One); - mod_file->addStatement(new RamseyPolicyStatement(mod_file->symbol_table, ramsey_policy_list, options_list)); - options_list.clear(); - ramsey_policy_list.clear(); -} - -void -ParsingDriver::add_to_ramsey_policy_list(string *name) -{ - ramsey_policy_list.push_back(*name); - delete name; -} - -void -ParsingDriver::discretionary_policy() -{ - if (!mod_file->symbol_table.exists("optimal_policy_discount_factor")) - declare_optimal_policy_discount_factor_parameter(data_tree->One); - mod_file->addStatement(new DiscretionaryPolicyStatement(symbol_list, options_list)); - symbol_list.clear(); - options_list.clear(); -} - -void -ParsingDriver::write_latex_dynamic_model(bool write_equation_tags) -{ - mod_file->addStatement(new WriteLatexDynamicModelStatement(mod_file->dynamic_model, write_equation_tags)); -} - -void -ParsingDriver::write_latex_static_model(bool write_equation_tags) -{ - mod_file->addStatement(new WriteLatexStaticModelStatement(mod_file->static_model, write_equation_tags)); -} - -void -ParsingDriver::write_latex_original_model(bool write_equation_tags) -{ - mod_file->addStatement(new WriteLatexOriginalModelStatement(mod_file->original_model, write_equation_tags)); -} - -void -ParsingDriver::write_latex_steady_state_model() -{ - mod_file->addStatement(new WriteLatexSteadyStateModelStatement(mod_file->steady_state_model)); -} - -void -ParsingDriver::bvar_density(string *maxnlags) -{ - mod_file->addStatement(new BVARDensityStatement(atoi(maxnlags->c_str()), options_list)); - options_list.clear(); - delete maxnlags; -} - -void -ParsingDriver::bvar_forecast(string *nlags) -{ - mod_file->addStatement(new BVARForecastStatement(atoi(nlags->c_str()), options_list)); - options_list.clear(); - delete nlags; -} - -void -ParsingDriver::sbvar() -{ - mod_file->addStatement(new SBVARStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::ms_estimation() -{ - mod_file->addStatement(new MSSBVAREstimationStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::ms_simulation() -{ - mod_file->addStatement(new MSSBVARSimulationStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::ms_compute_mdd() -{ - mod_file->addStatement(new MSSBVARComputeMDDStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::ms_compute_probabilities() -{ - mod_file->addStatement(new MSSBVARComputeProbabilitiesStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::ms_irf() -{ - mod_file->addStatement(new MSSBVARIrfStatement(symbol_list, options_list)); - symbol_list.clear(); - options_list.clear(); -} - -void -ParsingDriver::ms_forecast() -{ - mod_file->addStatement(new MSSBVARForecastStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::ms_variance_decomposition() -{ - mod_file->addStatement(new MSSBVARVarianceDecompositionStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::svar() -{ - OptionsList::string_options_t::const_iterator it0, it1, it2; - OptionsList::num_options_t::const_iterator itn; - OptionsList::vec_int_options_t::const_iterator itv; - - it0 = options_list.string_options.find("ms.coefficients"); - it1 = options_list.string_options.find("ms.variances"); - it2 = options_list.string_options.find("ms.constants"); - if (it0 == options_list.string_options.end() - && it1 == options_list.string_options.end() - && it2 == options_list.string_options.end()) - error("You must pass one of 'coefficients', 'variances', or 'constants'."); - - if ((it0 != options_list.string_options.end() - && it1 != options_list.string_options.end()) - || (it1 != options_list.string_options.end() - && it2 != options_list.string_options.end()) - || (it0 != options_list.string_options.end() - && it2 != options_list.string_options.end())) - error("You may only pass one of 'coefficients', 'variances', or 'constants'."); - - itn = options_list.num_options.find("ms.chain"); - if (itn == options_list.num_options.end()) - error("A chain option must be passed to the svar statement."); - else if (atoi(itn->second.c_str()) <= 0) - error("The value passed to the chain option must be greater than zero."); - - itv = options_list.vector_int_options.find("ms.equations"); - if (itv != options_list.vector_int_options.end()) - for (vector::const_iterator viit = itv->second.begin(); viit != itv->second.end(); viit++) - if (*viit <= 0) - error("The value(s) passed to the equation option must be greater than zero."); - - mod_file->addStatement(new SvarStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::markov_switching() -{ - OptionsList::num_options_t::const_iterator it0; - - it0 = options_list.num_options.find("ms.chain"); - if (it0 == options_list.num_options.end()) - error("A chain option must be passed to the markov_switching statement."); - else if (atoi(it0->second.c_str()) <= 0) - error("The value passed to the chain option must be greater than zero."); - - it0 = options_list.num_options.find("ms.number_of_regimes"); - if (it0 == options_list.num_options.end()) - error("A number_of_regimes option must be passed to the markov_switching statement."); - else if (atoi(it0->second.c_str()) <= 0) - error("The value passed to the number_of_regimes option must be greater than zero."); - - it0 = options_list.num_options.find("ms.duration"); - if (it0 == options_list.num_options.end()) - error("A duration option must be passed to the markov_switching statement."); - - mod_file->addStatement(new MarkovSwitchingStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::shock_decomposition() -{ - mod_file->addStatement(new ShockDecompositionStatement(symbol_list, options_list)); - symbol_list.clear(); - options_list.clear(); -} - -void -ParsingDriver::realtime_shock_decomposition() -{ - mod_file->addStatement(new RealtimeShockDecompositionStatement(symbol_list, options_list)); - symbol_list.clear(); - options_list.clear(); -} - -void -ParsingDriver::plot_shock_decomposition() -{ - mod_file->addStatement(new PlotShockDecompositionStatement(symbol_list, options_list)); - symbol_list.clear(); - options_list.clear(); -} - -void -ParsingDriver::initial_condition_decomposition() -{ - mod_file->addStatement(new InitialConditionDecompositionStatement(symbol_list, options_list)); - symbol_list.clear(); - options_list.clear(); -} - -void -ParsingDriver::conditional_forecast() -{ - mod_file->addStatement(new ConditionalForecastStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::plot_conditional_forecast(string *periods) -{ - int nperiods; - if (periods == NULL) - nperiods = -1; - else - { - nperiods = atoi(periods->c_str()); - delete periods; - } - mod_file->addStatement(new PlotConditionalForecastStatement(nperiods, symbol_list)); - symbol_list.clear(); -} - -void -ParsingDriver::conditional_forecast_paths() -{ - mod_file->addStatement(new ConditionalForecastPathsStatement(det_shocks, mod_file->symbol_table)); - det_shocks.clear(); -} - -void -ParsingDriver::calib_smoother() -{ - mod_file->addStatement(new CalibSmootherStatement(symbol_list, options_list)); - symbol_list.clear(); - options_list.clear(); -} - -void -ParsingDriver::extended_path() -{ - mod_file->addStatement(new ExtendedPathStatement(options_list)); - options_list.clear(); -} - -expr_t -ParsingDriver::add_model_equal(expr_t arg1, expr_t arg2) -{ - expr_t id = model_tree->AddEqual(arg1, arg2); - - // Detect if the equation is tagged [static] - bool is_static_only = false; - for (vector >::const_iterator it = eq_tags.begin(); - it != eq_tags.end(); ++it) - if (it->first == "static") - { - is_static_only = true; - break; - } - - if (is_static_only) - { - if (!id->isInStaticForm()) - error("An equation tagged [static] cannot contain leads, lags, expectations or STEADY_STATE operators"); - - dynamic_model->addStaticOnlyEquation(id, location.begin.line, eq_tags); - } - else - model_tree->addEquation(id, location.begin.line, eq_tags); - - eq_tags.clear(); - return id; -} - -expr_t -ParsingDriver::add_model_equal_with_zero_rhs(expr_t arg) -{ - return add_model_equal(arg, model_tree->Zero); -} - -void -ParsingDriver::declare_model_local_variable(string *name, string *tex_name) -{ - declare_symbol(name, eModelLocalVariable, tex_name, NULL); - delete name; - if (tex_name != NULL) - delete tex_name; -} - -void -ParsingDriver::declare_and_init_model_local_variable(string *name, expr_t rhs) -{ - int symb_id; - try - { - symb_id = mod_file->symbol_table.addSymbol(*name, eModelLocalVariable); - } - catch (SymbolTable::AlreadyDeclaredException &e) - { - // It can have already been declared in a steady_state_model block, check that it is indeed a ModelLocalVariable - symb_id = mod_file->symbol_table.getID(*name); - if (mod_file->symbol_table.getType(symb_id) != eModelLocalVariable) - error(*name + " has wrong type or was already used on the right-hand side. You cannot use it on the left-hand side of a pound ('#') expression"); - } - - try - { - model_tree->AddLocalVariable(symb_id, rhs); - } - catch (DataTree::LocalVariableException &e) - { - error("Local model variable " + *name + " declared twice."); - } - delete name; -} - -void -ParsingDriver::change_type(SymbolType new_type, vector *var_list) -{ - for (vector::iterator it = var_list->begin(); - it != var_list->end(); it++) - { - int id; - try - { - id = mod_file->symbol_table.getID(**it); - } - catch (SymbolTable::UnknownSymbolNameException &e) - { - error("Unknown variable " + **it); - } - - // Check if symbol already used in a VariableNode - if (mod_file->expressions_tree.isSymbolUsed(id) - || mod_file->dynamic_model.isSymbolUsed(id)) - error("You cannot modify the type of symbol " + **it + " after having used it in an expression"); - - mod_file->symbol_table.changeType(id, new_type); - - delete *it; - } - delete var_list; -} - -expr_t -ParsingDriver::add_plus(expr_t arg1, expr_t arg2) -{ - return data_tree->AddPlus(arg1, arg2); -} - -expr_t -ParsingDriver::add_minus(expr_t arg1, expr_t arg2) -{ - return data_tree->AddMinus(arg1, arg2); -} - -expr_t -ParsingDriver::add_uminus(expr_t arg1) -{ - return data_tree->AddUMinus(arg1); -} - -expr_t -ParsingDriver::add_times(expr_t arg1, expr_t arg2) -{ - return data_tree->AddTimes(arg1, arg2); -} - -expr_t -ParsingDriver::add_divide(expr_t arg1, expr_t arg2) -{ - try - { - return data_tree->AddDivide(arg1, arg2); - } - catch (DataTree::DivisionByZeroException) - { - error("Division by zero error encountered when reading model from .mod file"); - } -} - -expr_t -ParsingDriver::add_less(expr_t arg1, expr_t arg2) -{ - return data_tree->AddLess(arg1, arg2); -} - -expr_t -ParsingDriver::add_greater(expr_t arg1, expr_t arg2) -{ - return data_tree->AddGreater(arg1, arg2); -} - -expr_t -ParsingDriver::add_less_equal(expr_t arg1, expr_t arg2) -{ - return data_tree->AddLessEqual(arg1, arg2); -} - -expr_t -ParsingDriver::add_greater_equal(expr_t arg1, expr_t arg2) -{ - return data_tree->AddGreaterEqual(arg1, arg2); -} - -expr_t -ParsingDriver::add_equal_equal(expr_t arg1, expr_t arg2) -{ - return data_tree->AddEqualEqual(arg1, arg2); -} - -expr_t -ParsingDriver::add_different(expr_t arg1, expr_t arg2) -{ - return data_tree->AddDifferent(arg1, arg2); -} - -expr_t -ParsingDriver::add_power(expr_t arg1, expr_t arg2) -{ - return data_tree->AddPower(arg1, arg2); -} - -expr_t -ParsingDriver::add_expectation(string *arg1, expr_t arg2) -{ - expr_t expectationNode; - expectationNode = data_tree->AddExpectation(atoi(arg1->c_str()), arg2); - delete arg1; - return expectationNode; -} - -expr_t -ParsingDriver::add_exp(expr_t arg1) -{ - return data_tree->AddExp(arg1); -} - -expr_t -ParsingDriver::add_log(expr_t arg1) -{ - return data_tree->AddLog(arg1); -} - -expr_t -ParsingDriver::add_log10(expr_t arg1) -{ - return data_tree->AddLog10(arg1); -} - -expr_t -ParsingDriver::add_cos(expr_t arg1) -{ - return data_tree->AddCos(arg1); -} - -expr_t -ParsingDriver::add_sin(expr_t arg1) -{ - return data_tree->AddSin(arg1); -} - -expr_t -ParsingDriver::add_tan(expr_t arg1) -{ - return data_tree->AddTan(arg1); -} - -expr_t -ParsingDriver::add_acos(expr_t arg1) -{ - return data_tree->AddAcos(arg1); -} - -expr_t -ParsingDriver::add_asin(expr_t arg1) -{ - return data_tree->AddAsin(arg1); -} - -expr_t -ParsingDriver::add_atan(expr_t arg1) -{ - return data_tree->AddAtan(arg1); -} - -expr_t -ParsingDriver::add_cosh(expr_t arg1) -{ - return data_tree->AddCosh(arg1); -} - -expr_t -ParsingDriver::add_sinh(expr_t arg1) -{ - return data_tree->AddSinh(arg1); -} - -expr_t -ParsingDriver::add_tanh(expr_t arg1) -{ - return data_tree->AddTanh(arg1); -} - -expr_t -ParsingDriver::add_acosh(expr_t arg1) -{ - return data_tree->AddAcosh(arg1); -} - -expr_t -ParsingDriver::add_asinh(expr_t arg1) -{ - return data_tree->AddAsinh(arg1); -} - -expr_t -ParsingDriver::add_atanh(expr_t arg1) -{ - return data_tree->AddAtanh(arg1); -} - -expr_t -ParsingDriver::add_sqrt(expr_t arg1) -{ - return data_tree->AddSqrt(arg1); -} - -expr_t -ParsingDriver::add_abs(expr_t arg1) -{ - return data_tree->AddAbs(arg1); -} - -expr_t -ParsingDriver::add_sign(expr_t arg1) -{ - return data_tree->AddSign(arg1); -} - -expr_t -ParsingDriver::add_max(expr_t arg1, expr_t arg2) -{ - return data_tree->AddMax(arg1, arg2); -} - -expr_t -ParsingDriver::add_min(expr_t arg1, expr_t arg2) -{ - return data_tree->AddMin(arg1, arg2); -} - -expr_t -ParsingDriver::add_normcdf(expr_t arg1, expr_t arg2, expr_t arg3) -{ - return data_tree->AddNormcdf(arg1, arg2, arg3); -} - -expr_t -ParsingDriver::add_normcdf(expr_t arg) -{ - return add_normcdf(arg, data_tree->Zero, data_tree->One); -} - -expr_t -ParsingDriver::add_normpdf(expr_t arg1, expr_t arg2, expr_t arg3) -{ - return data_tree->AddNormpdf(arg1, arg2, arg3); -} - -expr_t -ParsingDriver::add_normpdf(expr_t arg) -{ - return add_normpdf(arg, data_tree->Zero, data_tree->One); -} - -expr_t -ParsingDriver::add_erf(expr_t arg1) -{ - return data_tree->AddErf(arg1); -} - -expr_t -ParsingDriver::add_steady_state(expr_t arg1) -{ - return data_tree->AddSteadyState(arg1); -} - -void -ParsingDriver::external_function_option(const string &name_option, string *opt) -{ - external_function_option(name_option, *opt); - delete opt; -} - -void -ParsingDriver::external_function_option(const string &name_option, const string &opt) -{ - if (name_option == "name") - { - if (opt.empty()) - error("An argument must be passed to the 'name' option of the external_function() statement."); - declare_symbol(&opt, eExternalFunction, NULL, NULL); - current_external_function_id = mod_file->symbol_table.getID(opt); - } - else if (name_option == "first_deriv_provided") - { - if (opt.empty()) - current_external_function_options.firstDerivSymbID = eExtFunSetButNoNameProvided; - else - { - declare_symbol(&opt, eExternalFunction, NULL, NULL); - current_external_function_options.firstDerivSymbID = mod_file->symbol_table.getID(opt); - } - } - else if (name_option == "second_deriv_provided") - { - if (opt.empty()) - current_external_function_options.secondDerivSymbID = eExtFunSetButNoNameProvided; - else - { - declare_symbol(&opt, eExternalFunction, NULL, NULL); - current_external_function_options.secondDerivSymbID = mod_file->symbol_table.getID(opt); - } - } - else if (name_option == "nargs") - current_external_function_options.nargs = atoi(opt.c_str()); - else - error("Unexpected error in ParsingDriver::external_function_option(): Please inform Dynare Team."); -} - -void -ParsingDriver::external_function() -{ - if (current_external_function_id == eExtFunNotSet) - error("The 'name' option must be passed to external_function()."); - - if (current_external_function_options.secondDerivSymbID >= 0 - && current_external_function_options.firstDerivSymbID == eExtFunNotSet) - error("If the second derivative is provided to the external_function command, the first derivative must also be provided."); - - if (current_external_function_options.secondDerivSymbID == eExtFunSetButNoNameProvided - && current_external_function_options.firstDerivSymbID != eExtFunSetButNoNameProvided) - error("If the second derivative is provided in the top-level function, the first derivative must also be provided in that function."); - - mod_file->external_functions_table.addExternalFunction(current_external_function_id, current_external_function_options, true); - reset_current_external_function_options(); -} - -void -ParsingDriver::push_external_function_arg_vector_onto_stack() -{ - vector emptyvec; - stack_external_function_args.push(emptyvec); -} - -void -ParsingDriver::add_external_function_arg(expr_t arg) -{ - stack_external_function_args.top().push_back(arg); -} - -pair -ParsingDriver::is_there_one_integer_argument() const -{ - if (stack_external_function_args.top().size() != 1) - return make_pair(false, 0); - - NumConstNode *numNode = dynamic_cast(stack_external_function_args.top().front()); - UnaryOpNode *unaryNode = dynamic_cast(stack_external_function_args.top().front()); - - if (numNode == NULL && unaryNode == NULL) - return make_pair(false, 0); - - eval_context_t ectmp; - double model_var_arg; - if (unaryNode == NULL) - { - try - { - model_var_arg = numNode->eval(ectmp); - } - catch (ExprNode::EvalException &e) - { - return make_pair(false, 0); - } - } - else - if (unaryNode->get_op_code() != oUminus) - return make_pair(false, 0); - else - { - try - { - model_var_arg = unaryNode->eval(ectmp); - } - catch (ExprNode::EvalException &e) - { - return make_pair(false, 0); - } - } - - if (model_var_arg != floor(model_var_arg)) - return make_pair(false, 0); - return make_pair(true, model_var_arg); -} - -expr_t -ParsingDriver::add_model_var_or_external_function(string *function_name, bool in_model_block) -{ - expr_t nid; - if (mod_file->symbol_table.exists(*function_name)) - { - if (mod_file->symbol_table.getType(*function_name) != eExternalFunction) - { - if (!in_model_block) - { - if (stack_external_function_args.top().size() > 0) - error(string("Symbol ") + *function_name + string(" cannot take arguments.")); - else - return add_expression_variable(function_name); - } - else - { // e.g. model_var(lag) => ADD MODEL VARIABLE WITH LEAD (NumConstNode)/LAG (UnaryOpNode) - if (undeclared_model_vars.find(*function_name) != undeclared_model_vars.end()) - model_error("Unknown symbol: " + *function_name); - - pair rv = is_there_one_integer_argument(); - if (!rv.first) - model_error(string("Symbol ") + *function_name + string(" is being treated as if it were a function (i.e., takes an argument that is not an integer).")); - - nid = add_model_variable(mod_file->symbol_table.getID(*function_name), (int) rv.second); - stack_external_function_args.pop(); - delete function_name; - return nid; - } - } - else - { // e.g. this function has already been referenced (either ad hoc or through the external_function() statement - // => check that the information matches previously declared info - int symb_id = mod_file->symbol_table.getID(*function_name); - if (!mod_file->external_functions_table.exists(symb_id)) - error("Using a derivative of an external function (" + *function_name + ") in the model block is currently not allowed."); - - if (in_model_block) - if (mod_file->external_functions_table.getNargs(symb_id) == eExtFunNotSet) - error("Before using " + *function_name - +"() in the model block, you must first declare it via the external_function() statement"); - else if ((int) (stack_external_function_args.top().size()) != mod_file->external_functions_table.getNargs(symb_id)) - error("The number of arguments passed to " + *function_name - +"() does not match those of a previous call or declaration of this function."); - } - } - else - { //First time encountering this external function i.e., not previously declared or encountered - if (in_model_block) - { - // Continue processing, noting that it was not declared - // Paring will end at the end of the model block - undeclared_model_vars.insert(*function_name); - model_error("Unknown symbol: " + *function_name); - pair rv = is_there_one_integer_argument(); - if (rv.first) - { - // assume it's a lead/lagged variable - declare_exogenous(new string(*function_name)); - return add_model_variable(mod_file->symbol_table.getID(*function_name), (int) rv.second); - } - else - error("To use an external function (" + *function_name + ") within the model block, you must first declare it via the external_function() statement."); - } - declare_symbol(function_name, eExternalFunction, NULL, NULL); - current_external_function_options.nargs = stack_external_function_args.top().size(); - mod_file->external_functions_table.addExternalFunction(mod_file->symbol_table.getID(*function_name), - current_external_function_options, in_model_block); - reset_current_external_function_options(); - } - - //By this point, we're sure that this function exists in the External Functions Table and is not a mod var - int symb_id = mod_file->symbol_table.getID(*function_name); - nid = data_tree->AddExternalFunction(symb_id, stack_external_function_args.top()); - stack_external_function_args.pop(); - delete function_name; - return nid; -} - -void -ParsingDriver::add_native(const string &s) -{ - mod_file->addStatement(new NativeStatement(s)); -} - -void -ParsingDriver::add_native_remove_charset(const char *s, const string &token) -{ - string str = string(s); - size_t found = str.find(token); - - assert(found != string::npos); - str.resize(found); - add_native(str); -} - -void -ParsingDriver::add_verbatim(const string &s) -{ - mod_file->addStatement(new VerbatimStatement(s)); -} - -void -ParsingDriver::add_verbatim_remove_charset(const char *s, const string &token) -{ - string str = string(s); - size_t found = str.find(token); - - assert(found != string::npos); - str.resize(found); - add_verbatim(str); -} - -void -ParsingDriver::begin_steady_state_model() -{ - set_current_data_tree(&mod_file->steady_state_model); -} - -void -ParsingDriver::add_steady_state_model_equal(string *varname, expr_t expr) -{ - int id; - try - { - id = mod_file->symbol_table.getID(*varname); - } - catch (SymbolTable::UnknownSymbolNameException &e) - { - // Unknown symbol, declare it as a ModFileLocalVariable - id = mod_file->symbol_table.addSymbol(*varname, eModFileLocalVariable); - } - - SymbolType type = mod_file->symbol_table.getType(id); - if (type != eEndogenous && type != eModFileLocalVariable && type != eParameter) - error(*varname + " has incorrect type"); - - mod_file->steady_state_model.addDefinition(id, expr); - - delete varname; -} - -void -ParsingDriver::add_steady_state_model_equal_multiple(expr_t expr) -{ - const vector &symbs = symbol_list.get_symbols(); - vector ids; - - for (size_t i = 0; i < symbs.size(); i++) - { - int id; - try - { - id = mod_file->symbol_table.getID(symbs[i]); - } - catch (SymbolTable::UnknownSymbolNameException &e) - { - // Unknown symbol, declare it as a ModFileLocalVariable - id = mod_file->symbol_table.addSymbol(symbs[i], eModFileLocalVariable); - } - SymbolType type = mod_file->symbol_table.getType(id); - if (type != eEndogenous && type != eModFileLocalVariable && type != eParameter) - error(symbs[i] + " has incorrect type"); - ids.push_back(id); - } - - mod_file->steady_state_model.addMultipleDefinitions(ids, expr); - - symbol_list.clear(); -} - -void -ParsingDriver::add_graph_format(const string &name) -{ - graph_formats.addSymbol(name); -} - -void -ParsingDriver::process_graph_format_option() -{ - options_list.symbol_list_options["graph_format"] = graph_formats; - graph_formats.clear(); -} - -void -ParsingDriver::plot_shock_decomp_process_graph_format_option() -{ - options_list.symbol_list_options["plot_shock_decomp.graph_format"] = graph_formats; - graph_formats.clear(); -} - -void -ParsingDriver::model_diagnostics() -{ - mod_file->addStatement(new ModelDiagnosticsStatement()); -} - -void -ParsingDriver::add_parallel_local_file(string *filename) -{ - mod_file->parallel_local_files.push_back(*filename); - delete filename; -} - -void -ParsingDriver::add_moment_calibration_item(string *endo1, string *endo2, string *lags, vector *range) -{ - MomentCalibration::Constraint c; - - check_symbol_existence(*endo1); - c.endo1 = mod_file->symbol_table.getID(*endo1); - if (mod_file->symbol_table.getType(*endo1) != eEndogenous) - error("Variable " + *endo1 + " is not an endogenous."); - delete endo1; - - check_symbol_existence(*endo2); - c.endo2 = mod_file->symbol_table.getID(*endo2); - if (mod_file->symbol_table.getType(*endo2) != eEndogenous) - error("Variable " + *endo2 + " is not an endogenous."); - delete endo2; - - c.lags = *lags; - delete lags; - - assert(range->size() == 2); - c.lower_bound = *((*range)[0]); - c.upper_bound = *((*range)[1]); - delete (*range)[0]; - delete (*range)[1]; - delete range; - - moment_calibration_constraints.push_back(c); -} - -void -ParsingDriver::end_moment_calibration() -{ - mod_file->addStatement(new MomentCalibration(moment_calibration_constraints, - mod_file->symbol_table)); - moment_calibration_constraints.clear(); -} - -void -ParsingDriver::add_irf_calibration_item(string *endo, string *periods, string *exo, vector *range) -{ - IrfCalibration::Constraint c; - - check_symbol_existence(*endo); - c.endo = mod_file->symbol_table.getID(*endo); - if (mod_file->symbol_table.getType(*endo) != eEndogenous) - error("Variable " + *endo + " is not an endogenous."); - delete endo; - - c.periods = *periods; - delete periods; - - check_symbol_existence(*exo); - c.exo = mod_file->symbol_table.getID(*exo); - if (mod_file->symbol_table.getType(*exo) != eExogenous) - error("Variable " + *endo + " is not an exogenous."); - delete exo; - - assert(range->size() == 2); - c.lower_bound = *((*range)[0]); - c.upper_bound = *((*range)[1]); - delete (*range)[0]; - delete (*range)[1]; - delete range; - - irf_calibration_constraints.push_back(c); -} - -void -ParsingDriver::end_irf_calibration() -{ - mod_file->addStatement(new IrfCalibration(irf_calibration_constraints, - mod_file->symbol_table, - options_list)); - irf_calibration_constraints.clear(); -} - -void -ParsingDriver::smoother2histval() -{ - mod_file->addStatement(new Smoother2histvalStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::histval_file(string *filename) -{ - mod_file->addStatement(new HistvalFileStatement(*filename)); - delete filename; -} - -void -ParsingDriver::perfect_foresight_setup() -{ - mod_file->addStatement(new PerfectForesightSetupStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::perfect_foresight_solver() -{ - mod_file->addStatement(new PerfectForesightSolverStatement(options_list)); - options_list.clear(); -} - -void -ParsingDriver::gmm_estimation() -{ - mod_file->addStatement(new GMMEstimationStatement(symbol_list, options_list)); - symbol_list.clear(); - options_list.clear(); -} - -void -ParsingDriver::smm_estimation() -{ - mod_file->addStatement(new SMMEstimationStatement(symbol_list, options_list)); - symbol_list.clear(); - options_list.clear(); -} - -void -ParsingDriver::prior_posterior_function(bool prior_func) -{ - mod_file->addStatement(new PriorPosteriorFunctionStatement((bool) prior_func, options_list)); - options_list.clear(); -} - -void -ParsingDriver::add_ramsey_constraints_statement() -{ - mod_file->addStatement(new RamseyConstraintsStatement(mod_file->symbol_table, ramsey_constraints)); - ramsey_constraints.clear(); -} - -void -ParsingDriver::ramsey_constraint_add_less(const string *name, const expr_t rhs) -{ - add_ramsey_constraint(name, oLess, rhs); -} - -void -ParsingDriver::ramsey_constraint_add_greater(const string *name, const expr_t rhs) -{ - add_ramsey_constraint(name, oGreater, rhs); -} - -void -ParsingDriver::ramsey_constraint_add_less_equal(const string *name, const expr_t rhs) -{ - add_ramsey_constraint(name, oLessEqual, rhs); -} - -void -ParsingDriver::ramsey_constraint_add_greater_equal(const string *name, const expr_t rhs) -{ - add_ramsey_constraint(name, oGreaterEqual, rhs); -} - -void -ParsingDriver::add_ramsey_constraint(const string *name, BinaryOpcode op_code, const expr_t rhs) -{ - check_symbol_existence(*name); - int symb_id = mod_file->symbol_table.getID(*name); - SymbolType type = mod_file->symbol_table.getType(symb_id); - - if (type != eEndogenous) - error("ramsey_constraints: " + *name + " should be an endogenous variable"); - - RamseyConstraintsStatement::Constraint C; - C.endo = symb_id; - C.code = op_code; - C.expression = rhs; - ramsey_constraints.push_back(C); - - delete name; -} - -void -ParsingDriver::add_shock_group_element(string *name) -{ - check_symbol_existence(*name); - int symb_id = mod_file->symbol_table.getID(*name); - SymbolType type = mod_file->symbol_table.getType(symb_id); - - if (type != eExogenous) - error("shock_groups: " + *name + " should be an exogenous variable"); - - shock_group.push_back(*name); - - delete name; -} - -void -ParsingDriver::add_shock_group(string *name) -{ - ShockGroupsStatement::Group G; - G.name = *name; - G.list = shock_group; - shock_groups.push_back(G); - - shock_group.clear(); -} - -void -ParsingDriver::end_shock_groups(const string *name) -{ - mod_file->addStatement(new ShockGroupsStatement(shock_groups, *name)); - shock_groups.clear(); -} diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh deleted file mode 100644 index 4386bbcdf..000000000 --- a/preprocessor/ParsingDriver.hh +++ /dev/null @@ -1,780 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#ifndef _PARSING_DRIVER_HH -#define _PARSING_DRIVER_HH - -#ifdef _MACRO_DRIVER_HH -# error Impossible to include both ParsingDriver.hh and MacroDriver.hh -#endif - -#include -#include -#include -#include - -#include "ModFile.hh" -#include "SymbolList.hh" - -class ParsingDriver; -#include "ExprNode.hh" -#include "DynareBison.hh" - -#include "ComputingTasks.hh" -#include "Shocks.hh" -#include "SigmaeInitialization.hh" -#include "NumericalInitialization.hh" -#include "DynamicModel.hh" - -using namespace std; - -// Declare DynareFlexLexer class -#ifndef __FLEX_LEXER_H -# define yyFlexLexer DynareFlexLexer -# include -# undef yyFlexLexer -#endif - -//! The lexer class -/*! Actually it was necessary to subclass the DynareFlexLexer class generated by Flex, - since the prototype for DynareFlexLexer::yylex() was not convenient. -*/ -class DynareFlex : public DynareFlexLexer -{ -public: - DynareFlex(istream *in = 0, ostream *out = 0); - - //! The main lexing function - Dynare::parser::token_type lex(Dynare::parser::semantic_type *yylval, - Dynare::parser::location_type *yylloc, - ParsingDriver &driver); - - //! The filename being parsed - /*! The bison parser locations (begin and end) contain a pointer to that string */ - string filename; - - //! Increment the location counter given a token - void location_increment(Dynare::parser::location_type *yylloc, const char *yytext); - - //! Count parens in dates statement - int dates_parens_nb; -}; - -//! Drives the scanning and parsing of the .mod file, and constructs its abstract representation -/*! It is built along the guidelines given in Bison 2.3 manual. */ -class ParsingDriver -{ -private: - //! Checks that a given symbol exists, and stops with an error message if it doesn't - void check_symbol_existence(const string &name); - - //! Checks that a given symbol exists and is a parameter, and stops with an error message if it isn't - void check_symbol_is_parameter(string *name); - - //! Checks that a given symbol was assigned within a Statement - void check_symbol_is_statement_variable(string *name); - - //! Checks that a given symbol exists and is a endogenous or exogenous, and stops with an error message if it isn't - void check_symbol_is_endogenous_or_exogenous(string *name); - - //! Checks that a given symbol exists and is a exogenous, and stops with an error message if it isn't - void check_symbol_is_exogenous(string *name); - - //! Checks for symbol existence in model block. If it doesn't exist, an error message is stored to be printed at - //! the end of the model block - void check_symbol_existence_in_model_block(const string &name); - - //! Helper to add a symbol declaration - void declare_symbol(const string *name, SymbolType type, const string *tex_name, const vector *> *partition_value); - - //! Creates option "optim_opt" in OptionsList if it doesn't exist, else add a comma, and adds the option name - void optim_options_helper(const string &name); - void sampling_options_helper(const string &name); - - //! Stores temporary symbol table - SymbolList symbol_list; - - //! The data tree in which to add expressions currently parsed - DataTree *data_tree; - - //! The model tree in which to add expressions currently parsed - /*! It is only a dynamic cast of data_tree pointer, and is therefore null if data_tree is not a ModelTree instance */ - ModelTree *model_tree; - - //! The dynamic model tree in which to add expressions currently parsed - /*! It is only a dynamic cast of data_tree pointer, and is therefore null if data_tree is not a DynamicModel instance */ - DynamicModel *dynamic_model; - - //! Sets data_tree and model_tree pointers - void set_current_data_tree(DataTree *data_tree_arg); - - //! Stores options lists - OptionsList options_list; - //! Temporary storage for trend elements - ObservationTrendsStatement::trend_elements_t trend_elements; - //! Temporary storage for filename list of ModelComparison (contains weights) - ModelComparisonStatement::filename_list_t filename_list; - //! Temporary storage for list of EstimationParams (from estimated_params* statements) - vector estim_params_list; - //! Temporary storage for list of OsrParams (from osr_params_block statements) - vector osr_params_list; - //! Temporary storage of variances from optim_weights - OptimWeightsStatement::var_weights_t var_weights; - //! Temporary storage of covariances from optim_weights - OptimWeightsStatement::covar_weights_t covar_weights; - //! Temporary storage for deterministic shocks - ShocksStatement::det_shocks_t det_shocks; - //! Temporary storage for periods of deterministic shocks - vector > det_shocks_periods; - //! Temporary storage for values of deterministic shocks - vector det_shocks_values; - //! Temporary storage for variances of shocks - ShocksStatement::var_and_std_shocks_t var_shocks; - //! Temporary storage for standard errors of shocks - ShocksStatement::var_and_std_shocks_t std_shocks; - //! Temporary storage for covariances of shocks - ShocksStatement::covar_and_corr_shocks_t covar_shocks; - //! Temporary storage for correlations of shocks - ShocksStatement::covar_and_corr_shocks_t corr_shocks; - //! Temporary storage for Sigma_e rows - SigmaeStatement::row_t sigmae_row; - //! Temporary storage for Sigma_e matrix - SigmaeStatement::matrix_t sigmae_matrix; - //! Temporary storage for initval/endval blocks - InitOrEndValStatement::init_values_t init_values; - //! Temporary storage for histval blocks - HistValStatement::hist_values_t hist_values; - //! Temporary storage for histval blocks - HistValStatement::hist_vals_wrong_lag_t hist_vals_wrong_lag; - //! Temporary storage for homotopy_setup blocks - HomotopyStatement::homotopy_values_t homotopy_values; - //! Temporary storage for moment_calibration - MomentCalibration::constraints_t moment_calibration_constraints; - //! Temporary storage for irf_calibration - IrfCalibration::constraints_t irf_calibration_constraints; - //! Temporary storage for ramsey_constraints - RamseyConstraintsStatement::constraints_t ramsey_constraints; - //! Temporary storage for svar_identification blocks - SvarIdentificationStatement::svar_identification_restrictions_t svar_ident_restrictions; - //! Temporary storage for mapping the equation number to the restrictions within an svar_identification block - map > svar_equation_restrictions; - //! Temporary storage for restrictions in an equation within an svar_identification block - vector svar_restriction_symbols; - //! Temporary storage for constants exculsion within an svar_identification - bool svar_constants_exclusion; - //! Temporary storage for upper cholesky within an svar_identification block - bool svar_upper_cholesky; - //! Temporary storage for lower cholesky within an svar_identification block - bool svar_lower_cholesky; - //! Temporary storage for equation number for a restriction within an svar_identification block - int svar_equation_nbr; - //! Temporary storage for left/right handside of a restriction equation within an svar_identificaton block - bool svar_left_handside; - //! Temporary storage for current restriction number in svar_identification block - map svar_Qi_restriction_nbr; - map svar_Ri_restriction_nbr; - //! Stores undeclared model variables - set undeclared_model_vars; - //! Temporary storage for restriction type - enum SvarRestrictionType - { - NOT_SET, - Qi_TYPE, - Ri_TYPE - }; - SvarRestrictionType svar_restriction_type; - //! Temporary storage for generate_irfs - vector generate_irf_names; - vector > generate_irf_elements; - map generate_irf_exos; - //! Temporary storage for argument list of external function - stack > stack_external_function_args; - //! Temporary storage for parameters in joint prior statement - vector joint_parameters; - //! Temporary storage for the symb_id associated with the "name" symbol of the current external_function statement - int current_external_function_id; - //! Temporary storage for option list provided to external_function() - ExternalFunctionsTable::external_function_options current_external_function_options; - //! Temporary storage for declaring trend variables - vector declared_trend_vars; - //! Temporary storage for declaring nonstationary variables - vector declared_nonstationary_vars; - //! Temporary storage for a variance declared in the prior statement - expr_t prior_variance; - SubsamplesStatement::subsample_declaration_map_t subsample_declaration_map; - //! Temporary storage for subsample statement: map>, subsample_declaration_map > - typedef map, SubsamplesStatement::subsample_declaration_map_t > subsample_declarations_t; - subsample_declarations_t subsample_declarations; - //! Temporary storage for shock_groups - vector shock_group; - vector shock_groups; - //! Temporary storage for ramsey policy. Workaround for issue #1355 - vector ramsey_policy_list; - //! reset the values for temporary storage - void reset_current_external_function_options(); - //! Adds a model lagged variable to ModelTree and VariableTable - expr_t add_model_variable(int symb_id, int lag); - //! For parsing the graph_format option - SymbolList graph_formats; - //! Temporary storage for equation tags - vector > eq_tags; - - //! The mod file representation constructed by this ParsingDriver - ModFile *mod_file; - - WarningConsolidation &warnings; - - bool nostrict; - - bool model_error_encountered; - - ostringstream model_errors; - -public: - ParsingDriver(WarningConsolidation &warnings_arg, bool nostrict_arg) : warnings(warnings_arg), nostrict(nostrict_arg), model_error_encountered(false) - { - }; - - //! Starts parsing, and constructs the MOD file representation - /*! The returned pointer should be deleted after use */ - ModFile *parse(istream &in, bool debug); - - //! Reference to the lexer - class DynareFlex *lexer; - - //! Copy of parsing location, maintained by YYLLOC_DEFAULT macro in DynareBison.yy - Dynare::parser::location_type location; - - //! Estimation parameters - EstimationParams estim_params; - - //! OSR parameters - OsrParams osr_params; - - //! Temporary storage for the prior shape - PriorDistributions prior_shape; - - //! Error handler with explicit location - void error(const Dynare::parser::location_type &l, const string &m) __attribute__ ((noreturn)); - //! Error handler using saved location - void error(const string &m) __attribute__ ((noreturn)); - //! Warning handler using saved location - void warning(const string &m); - - //! Error handler with explicit location (used in model block, accumulating error messages to be printed later) - void model_error(const string &m); - - //! Code shared between model_error() and error() - void create_error_string(const Dynare::parser::location_type &l, const string &m, ostream &stream); - - //! Check if a given symbol exists in the parsing context, and is not a mod file local variable - bool symbol_exists_and_is_not_modfile_local_or_external_function(const char *s); - //! Sets mode of ModelTree class to use C output - void use_dll(); - //! the modelis block decomposed - void block(); - //! the model is stored in a binary file - void byte_code(); - //! the static model is not computed - void no_static(); - //! the differentiate_forward_vars option is enabled (for all vars) - void differentiate_forward_vars_all(); - //! the differentiate_forward_vars option is enabled (for a subset of vars) - void differentiate_forward_vars_some(); - //! cutoff option of model block - void cutoff(string *value); - //! mfs option of model block - void mfs(string *value); - //! Sets the FILENAME for the initial value in initval - void initval_file(string *filename); - //! Declares an endogenous variable - void declare_endogenous(string *name, string *tex_name = NULL, vector *> *partition_value = NULL); - //! Declares an exogenous variable - void declare_exogenous(string *name, string *tex_name = NULL, vector *> *partition_value = NULL); - //! Declares an exogenous deterministic variable - void declare_exogenous_det(string *name, string *tex_name = NULL, vector *> *partition_value = NULL); - //! Declares a parameter - void declare_parameter(string *name, string *tex_name = NULL, vector *> *partition_value = NULL); - //! Declares a model local variable - void declare_model_local_variable(string *name, string *tex_name = NULL); - //! Declares a statement local variable - void declare_statement_local_variable(string *name); - //! Completes a subsample statement - void set_subsamples(string *name1, string *name2); - //! Declares a subsample, assigning the value to name - void set_subsample_name_equal_to_date_range(string *name, string *date1, string *date2); - //! Checks that a subsample statement (and given name) were provided for the pair name1 & name2 - void check_subsample_declaration_exists(string *name1, string *subsample_name); - void check_subsample_declaration_exists(string *name1, string *name2, string *subsample_name); - //! Copies the set of subsamples from_name to_name - void copy_subsamples(string *to_name1, string *to_name2, string *from_name1, string *from_name2); - //! Declares declare_optimal_policy_discount_factor as a parameter and initializes it to exprnode - void declare_optimal_policy_discount_factor_parameter(expr_t exprnode); - //! Adds a predetermined_variable - void add_predetermined_variable(string *name); - //! Declares and initializes a local parameter - void declare_and_init_model_local_variable(string *name, expr_t rhs); - //! Changes type of a symbol - void change_type(SymbolType new_type, vector *var_list); - //! Adds a list of tags for the current equation - void add_equation_tags(string *key, string *value); - //! Adds a non-negative constant to DataTree - expr_t add_non_negative_constant(string *constant); - //! Adds a NaN constant to DataTree - expr_t add_nan_constant(); - //! Adds an Inf constant to DataTree - expr_t add_inf_constant(); - //! Adds a model variable to ModelTree and VariableTable - expr_t add_model_variable(string *name); - //! Adds an Expression's variable - expr_t add_expression_variable(string *name); - //! Adds a "periods" statement - void periods(string *periods); - //! Adds a "dsample" statement - void dsample(string *arg1); - //! Adds a "dsample" statement - void dsample(string *arg1, string *arg2); - //! Writes parameter intitialisation expression - void init_param(string *name, expr_t rhs); - //! Writes an initval block - void init_val(string *name, expr_t rhs); - //! Writes an histval block - void hist_val(string *name, string *lag, expr_t rhs); - //! Adds an entry in a homotopy_setup block - /*! Second argument "val1" can be NULL if no initial value provided */ - void homotopy_val(string *name, expr_t val1, expr_t val2); - //! Writes end of an initval block - void end_initval(bool all_values_required); - //! Writes end of an endval block - void end_endval(bool all_values_required); - //! Writes end of an histval block - void end_histval(bool all_values_required); - //! Writes end of an homotopy_setup block - void end_homotopy(); - //! Begin a model block - void begin_model(); - //! End a model block, printing errors that were encountered in parsing - void end_model(); - //! Writes a shocks statement - void end_shocks(bool overwrite); - //! Writes a mshocks statement - void end_mshocks(bool overwrite); - //! Adds a deterministic shock or a path element inside a conditional_forecast_paths block - void add_det_shock(string *var, bool conditional_forecast); - //! Adds a std error chock - void add_stderr_shock(string *var, expr_t value); - //! Adds a variance chock - void add_var_shock(string *var, expr_t value); - //! Adds a covariance chock - void add_covar_shock(string *var1, string *var2, expr_t value); - //! Adds a correlated chock - void add_correl_shock(string *var1, string *var2, expr_t value); - //! Adds a shock period range - void add_period(string *p1, string *p2); - //! Adds a shock period - void add_period(string *p1); - //! Adds a deterministic shock value - void add_value(expr_t value); - //! Adds a deterministic shock value - /*! \param v a string containing a (possibly negative) numeric constant */ - void add_value(string *v); - //! Writes a Sigma_e block - void do_sigma_e(); - //! Ends row of Sigma_e block - void end_of_row(); - //! Adds a constant element to current row of Sigma_e - void add_to_row_const(string *v); - //! Adds an expression element to current row of Sigma_e - void add_to_row(expr_t v); - //! Write a steady command - void steady(); - //! Sets an option to a numerical value - void option_num(const string &name_option, string *opt); - //! Sets an option to a numerical value - void option_num(const string &name_option, const string &opt); - //! Sets an option to a numerical value - void option_num(const string &name_option, string *opt1, string *opt2); - //! Sets an option to a string value - void option_str(const string &name_option, string *opt); - //! Sets an option to a string value - void option_str(const string &name_option, const string &opt); - //! Sets an option to a date value - void option_date(const string &name_option, string *opt); - //! Sets an option to a date value - void option_date(const string &name_option, const string &opt); - //! Sets an option to a list of symbols (used in conjunction with add_in_symbol_list()) - void option_symbol_list(const string &name_option); - //! Sets an option to a vector of integers - void option_vec_int(const string &name_option, const vector *opt); - //! Indicates that the model is linear - void linear(); - //! Adds a variable to temporary symbol list - void add_in_symbol_list(string *tmp_var); - //! Writes a rplot() command - void rplot(); - //! Writes a stock_simul command - void stoch_simul(); - //! Writes a simul command - void simul(); - //! Writes check command - void check(); - //! Writes model_info command - void model_info(); - //! Writes estimated params command - void estimated_params(); - //! Writes estimated params init command - void estimated_params_init(bool use_calibration = false); - //! Writes estimated params bound command - void estimated_params_bounds(); - //! Adds a declaration for a user-defined external function - void external_function(); - //! Sets an external_function option to a string value - void external_function_option(const string &name_option, string *opt); - //! Sets an external_function option to a string value - void external_function_option(const string &name_option, const string &opt); - //! Add a line in an estimated params block - void add_estimated_params_element(); - //! Writes osr params bounds command - void osr_params_bounds(); - //! Add a line in an osr params block - void add_osr_params_element(); - //! Sets the frequency of the data - void set_time(string *arg); - //! Estimation Data - void estimation_data(); - //! Sets the prior for a parameter - void set_prior(string *arg1, string *arg2); - //! Sets the joint prior for a set of parameters - void set_joint_prior(vector *symbol_vec); - //! Adds a parameters to the list of joint parameters - void add_joint_parameter(string *name); - //! Adds the variance option to its temporary holding place - void set_prior_variance(expr_t variance = NULL); - //! Copies the prior from_name to_name - void copy_prior(string *to_declaration_type, string *to_name1, string *to_name2, string *to_subsample_name, - string *from_declaration_type, string *from_name1, string *from_name2, string *from_subsample_name); - //! Sets the options for a parameter - void set_options(string *arg1, string *arg2); - //! Copies the options from_name to_name - void copy_options(string *to_declaration_type, string *to_name1, string *to_name2, string *to_subsample_name, - string *from_declaration_type, string *from_name1, string *from_name2, string *from_subsample_name); - //! Sets the prior for estimated std dev - void set_std_prior(string *arg1, string *arg2); - //! Sets the options for estimated std dev - void set_std_options(string *arg1, string *arg2); - //! Sets the prior for estimated correlation - void set_corr_prior(string *arg1, string *arg2, string *arg3); - //! Sets the options for estimated correlation - void set_corr_options(string *arg1, string *arg2, string *arg3); - //! Runs estimation process - void run_estimation(); - //! Runs dynare_sensitivy() - void dynare_sensitivity(); - //! Adds an optimization option (string value) - void optim_options_string(string *name, string *value); - //! Adds an optimization option (numeric value) - void optim_options_num(string *name, string *value); - //! Adds an sampling option (string value) - void sampling_options_string(string *name, string *value); - //! Adds an sampling option (numeric value) - void sampling_options_num(string *name, string *value); - //! Check that no observed variable has yet be defined - void check_varobs(); - //! Add a new observed variable - void add_varobs(string *name); - //! Svar_Identification Statement - void begin_svar_identification(); - void end_svar_identification(); - //! Svar_Identification Statement: match list of restrictions and equation number with lag - void combine_lag_and_restriction(string *lag); - //! Svar_Identification Statement: match list of restrictions with equation number - void add_restriction_in_equation(string *equation); - //! Svar_Identification Statement: add list of restriction symbol ids - void add_in_svar_restriction_symbols(string *name); - //! Svar_Identification Statement: add exclusions of constants - void add_constants_exclusion(); - //! Svar_Identification Statement: add equation number for following restriction equations - void add_restriction_equation_nbr(string *eq_nbr); - //! Svar_Identification Statement: record presence of equal sign - void add_restriction_equal(); - //! Svar_Idenditification Statement: add coefficient of a linear restriction (positive value) - void add_positive_restriction_element(expr_t value, string *variable, string *lag); - //! Svar_Idenditification Statement: add unit coefficient of a linear restriction - void add_positive_restriction_element(string *variable, string *lag); - //! Svar_Idenditification Statement: add coefficient of a linear restriction (negative value) - void add_negative_restriction_element(expr_t value, string *variable, string *lag); - //! Svar_Idenditification Statement: add negative unit coefficient of a linear restriction - void add_negative_restriction_element(string *variable, string *lag); - //! Svar_Idenditification Statement: add restriction element - void add_restriction_element(expr_t value, string *variable, string *lag); - //! Svar_Identification Statement: check that restriction is homogenous - void check_restriction_expression_constant(expr_t value); - //! Svar_Identification Statement: restriction of form upper cholesky - void add_upper_cholesky(); - //! Svar_Identification Statement: restriction of form lower cholesky - void add_lower_cholesky(); - //! Svar_Global_Identification_Check Statement - void add_svar_global_identification_check(); - //! generate_irfs Block - void end_generate_irfs(); - void add_generate_irfs_element(string *name); - void add_generate_irfs_exog_element(string *exo, string *value); - //! Forecast Statement - void forecast(); - void set_trends(); - void set_trend_element(string *arg1, expr_t arg2); - void set_unit_root_vars(); - void optim_weights(); - void set_optim_weights(string *name, expr_t value); - void set_optim_weights(string *name1, string *name2, expr_t value); - void set_osr_params(); - void run_osr(); - void run_dynasave(string *filename); - void run_dynatype(string *filename); - void run_load_params_and_steady_state(string *filename); - void run_save_params_and_steady_state(string *filename); - void run_identification(); - void add_mc_filename(string *filename, string *prior = new string ("1")); - void run_model_comparison(); - //! Begin a planner_objective statement - void begin_planner_objective(); - //! End a planner objective statement - void end_planner_objective(expr_t expr); - //! Ramsey model statement - void ramsey_model(); - //! Ramsey constraints statement - void add_ramsey_constraints_statement(); - //! Ramsey less constraint - void ramsey_constraint_add_less(const string *name, const expr_t rhs); - //! Ramsey greater constraint - void ramsey_constraint_add_greater(const string *name, const expr_t rhs); - //! Ramsey less or equal constraint - void ramsey_constraint_add_less_equal(const string *name, const expr_t rhs); - //! Ramsey greater or equal constraint - void ramsey_constraint_add_greater_equal(const string *name, const expr_t rhs); - //! Ramsey constraint helper function - void add_ramsey_constraint(const string *name, BinaryOpcode op_code, const expr_t rhs); - //! Ramsey policy statement - void ramsey_policy(); - //! Discretionary policy statement - void discretionary_policy(); - //! Adds a write_latex_dynamic_model statement - void write_latex_dynamic_model(bool write_equation_tags); - //! Adds a write_latex_static_model statement - void write_latex_static_model(bool write_equation_tags); - //! Adds a write_latex_original_model statement - void write_latex_original_model(bool write_equation_tags); - //! Adds a write_latex_steady_state_model statement - void write_latex_steady_state_model(); - //! BVAR marginal density - void bvar_density(string *maxnlags); - //! BVAR forecast - void bvar_forecast(string *nlags); - //! SBVAR statement - void sbvar(); - //! Markov Switching Statement: Estimation - void ms_estimation(); - //! Markov Switching Statement: Simulation - void ms_simulation(); - //! Markov Switching Statement: MDD - void ms_compute_mdd(); - //! Markov Switching Statement: Probabilities - void ms_compute_probabilities(); - //! Markov Switching Statement: IRF - void ms_irf(); - //! Markov Switching Statement: Forecast - void ms_forecast(); - //! Markov Switching Statement: Variance Decomposition - void ms_variance_decomposition(); - //! Svar statement - void svar(); - //! MarkovSwitching statement - void markov_switching(); - //! Shock decomposition - void shock_decomposition(); - //! Realtime Shock decomposition - void realtime_shock_decomposition(); - //! Plot Shock decomposition - void plot_shock_decomposition(); - //! Initial Condition decomposition - void initial_condition_decomposition(); - //! Conditional forecast statement - void conditional_forecast(); - //! Conditional forecast paths block - void conditional_forecast_paths(); - //! Plot conditional forecast statement - void plot_conditional_forecast(string *periods = NULL); - //! Smoother on calibrated models - void calib_smoother(); - //! Extended path - void extended_path(); - //! Writes token "arg1=arg2" to model tree - expr_t add_model_equal(expr_t arg1, expr_t arg2); - //! Writes token "arg=0" to model tree - expr_t add_model_equal_with_zero_rhs(expr_t arg); - //! Writes token "arg1+arg2" to model tree - expr_t add_plus(expr_t arg1, expr_t arg2); - //! Writes token "arg1-arg2" to model tree - expr_t add_minus(expr_t arg1, expr_t arg2); - //! Writes token "-arg1" to model tree - expr_t add_uminus(expr_t arg1); - //! Writes token "arg1*arg2" to model tree - expr_t add_times(expr_t arg1, expr_t arg2); - //! Writes token "arg1/arg2" to model tree - expr_t add_divide(expr_t arg1, expr_t arg2); - //! Writes token "arg1arg2" to model treeexpr_t - expr_t add_greater(expr_t arg1, expr_t arg2); - //! Writes token "arg1<=arg2" to model treeexpr_t - expr_t add_less_equal(expr_t arg1, expr_t arg2); - //! Writes token "arg1>=arg2" to model treeexpr_t - expr_t add_greater_equal(expr_t arg1, expr_t arg2); - //! Writes token "arg1==arg2" to model treeexpr_texpr_t - expr_t add_equal_equal(expr_t arg1, expr_t arg2); - //! Writes token "arg1!=arg2" to model treeexpr_texpr_t - expr_t add_different(expr_t arg1, expr_t arg2); - //! Writes token "arg1^arg2" to model tree - expr_t add_power(expr_t arg1, expr_t arg2); - //! Writes token "E(arg1)(arg2)" to model tree - expr_t add_expectation(string *arg1, expr_t arg2); - //! Writes token "exp(arg1)" to model tree - expr_t add_exp(expr_t arg1); - //! Writes token "log(arg1)" to model tree - expr_t add_log(expr_t arg1); - //! Writes token "log10(arg1)" to model tree - expr_t add_log10(expr_t arg1); - //! Writes token "cos(arg1)" to model tree - expr_t add_cos(expr_t arg1); - //! Writes token "sin(arg1)" to model tree - expr_t add_sin(expr_t arg1); - //! Writes token "tan(arg1)" to model tree - expr_t add_tan(expr_t arg1); - //! Writes token "acos(arg1)" to model tree - expr_t add_acos(expr_t arg1); - //! Writes token "asin(arg1)" to model tree - expr_t add_asin(expr_t arg1); - //! Writes token "atan(arg1)" to model tree - expr_t add_atan(expr_t arg1); - //! Writes token "cosh(arg1)" to model tree - expr_t add_cosh(expr_t arg1); - //! Writes token "sinh(arg1)" to model tree - expr_t add_sinh(expr_t arg1); - //! Writes token "tanh(arg1)" to model tree - expr_t add_tanh(expr_t arg1); - //! Writes token "acosh(arg1)" to model tree - expr_t add_acosh(expr_t arg1); - //! Writes token "asin(arg1)" to model tree - expr_t add_asinh(expr_t arg1); - //! Writes token "atanh(arg1)" to model tree - expr_t add_atanh(expr_t arg1); - //! Writes token "sqrt(arg1)" to model tree - expr_t add_sqrt(expr_t arg1); - //! Writes token "abs(arg1)" to model tree - expr_t add_abs(expr_t arg1); - //! Writes token "sign(arg1)" to model tree - expr_t add_sign(expr_t arg1); - //! Writes token "max(arg1,arg2)" to model tree - expr_t add_max(expr_t arg1, expr_t arg2); - //! Writes token "min(arg1,arg2)" to model tree - expr_t add_min(expr_t arg1, expr_t arg2); - //! Writes token "normcdf(arg1,arg2,arg3)" to model tree - expr_t add_normcdf(expr_t arg1, expr_t arg2, expr_t arg3); - //! Writes token "normcdf(arg,0,1)" to model tree - expr_t add_normcdf(expr_t arg); - //! Writes token "normpdf(arg1,arg2,arg3)" to model tree - expr_t add_normpdf(expr_t arg1, expr_t arg2, expr_t arg3); - //! Writes token "normpdf(arg,0,1)" to model tree - expr_t add_normpdf(expr_t arg); - //! Writes token "erf(arg)" to model tree - expr_t add_erf(expr_t arg); - //! Writes token "steadyState(arg1)" to model tree - expr_t add_steady_state(expr_t arg1); - //! Pushes empty vector onto stack when a symbol is encountered (mod_var or ext_fun) - void push_external_function_arg_vector_onto_stack(); - //! Adds an external function argument - void add_external_function_arg(expr_t arg); - //! Test to see if model/external function has exactly one integer argument - pair is_there_one_integer_argument() const; - //! Adds an external function call node - expr_t add_model_var_or_external_function(string *function_name, bool in_model_block); - //! Adds a native statement - void add_native(const string &s); - //! Adds a native statement, first removing the set of characters passed in token (and everything after) - void add_native_remove_charset(const char *s, const string &token); - //! Adds a verbatim statement - void add_verbatim(const string &s); - //! Adds a verbatim statement, first removing the set of characters passed in token (and everything after) - void add_verbatim_remove_charset(const char *s, const string &token); - //! Resets data_tree and model_tree pointers to default (i.e. mod_file->expressions_tree) - void reset_data_tree(); - //! Begin a steady_state_model block - void begin_steady_state_model(); - //! Add an assignment equation in steady_state_model block - void add_steady_state_model_equal(string *varname, expr_t expr); - //! Add a multiple assignment equation in steady_state_model block - void add_steady_state_model_equal_multiple(expr_t expr); - //! Switches datatree - void begin_trend(); - //! Declares a trend variable with its growth factor - void declare_trend_var(bool log_trend, string *name, string *tex_name = NULL); - //! Ends declaration of trend variable - void end_trend_var(expr_t growth_factor); - //! Declares a nonstationary variable with its deflator - void declare_nonstationary_var(string *name, string *tex_name = NULL, vector *> *partition_value = NULL); - //! Ends declaration of nonstationary variable - void end_nonstationary_var(bool log_deflator, expr_t deflator); - //! Add a graph format to the list of formats requested - void add_graph_format(const string &name); - //! Add the graph_format option to the OptionsList structure - void process_graph_format_option(); - //! Add the graph_format option to the plot_shock_decomp substructure of the OptionsList structure - void plot_shock_decomp_process_graph_format_option(); - //! Model diagnostics - void model_diagnostics(); - //! Processing the parallel_local_files option - void add_parallel_local_file(string *filename); - //! Add an item of a moment_calibration statement - void add_moment_calibration_item(string *endo1, string *endo2, string *lags, vector *range); - //! End a moment_calibration statement - void end_moment_calibration(); - //! Add an item of an irf_calibration statement - void add_irf_calibration_item(string *endo, string *periods, string *exo, vector *range); - //! End a moment_calibration statement - void end_irf_calibration(); - //! Add a shock to a group - void add_shock_group_element(string *name); - //! Add a set of shock groups - void add_shock_group(string *name); - //! End shock groups declaration - void end_shock_groups(const string *name); - //! Add an element to the ramsey policy list - void add_to_ramsey_policy_list(string *name); - void smoother2histval(); - void histval_file(string *filename); - void perfect_foresight_setup(); - void perfect_foresight_solver(); - void prior_posterior_function(bool prior_func); - //! GMM Estimation statement - void gmm_estimation(); - //! SMM Estimation statement - void smm_estimation(); -}; - -#endif // ! PARSING_DRIVER_HH diff --git a/preprocessor/Shocks.cc b/preprocessor/Shocks.cc deleted file mode 100644 index 5a9320610..000000000 --- a/preprocessor/Shocks.cc +++ /dev/null @@ -1,631 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#include -#include -#include - -#include "Shocks.hh" - -AbstractShocksStatement::AbstractShocksStatement(bool mshocks_arg, - bool overwrite_arg, - const det_shocks_t &det_shocks_arg, - const SymbolTable &symbol_table_arg) : - mshocks(mshocks_arg), - overwrite(overwrite_arg), - det_shocks(det_shocks_arg), - symbol_table(symbol_table_arg) -{ -} - -void -AbstractShocksStatement::writeDetShocks(ostream &output) const -{ - int exo_det_length = 0; - - for (det_shocks_t::const_iterator it = det_shocks.begin(); - it != det_shocks.end(); it++) - { - int id = symbol_table.getTypeSpecificID(it->first) + 1; - bool exo_det = (symbol_table.getType(it->first) == eExogenousDet); - - for (size_t i = 0; i < it->second.size(); i++) - { - const int &period1 = it->second[i].period1; - const int &period2 = it->second[i].period2; - const expr_t value = it->second[i].value; - - output << "M_.det_shocks = [ M_.det_shocks;" << endl - << "struct('exo_det'," << (int) exo_det - << ",'exo_id'," << id - << ",'multiplicative'," << (int) mshocks - << ",'periods'," << period1 << ":" << period2 - << ",'value',"; - value->writeOutput(output); - output << ") ];" << endl; - - if (exo_det && (period2 > exo_det_length)) - exo_det_length = period2; - } - } - output << "M_.exo_det_length = " << exo_det_length << ";\n"; -} - -void -AbstractShocksStatement::writeJsonDetShocks(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - output << "\"deterministic_shocks\": ["; - for (det_shocks_t::const_iterator it = det_shocks.begin(); - it != det_shocks.end(); it++) - { - if (it != det_shocks.begin()) - output << ", "; - output << "{\"var\": \"" << symbol_table.getName(it->first) << "\", " - << "\"values\": ["; - for (vector::const_iterator it1 = it->second.begin(); - it1 != it->second.end(); it1++) - { - if (it1 != it->second.begin()) - output << ", "; - output << "{\"period1\": " << it1->period1 << ", " - << "\"period2\": " << it1->period2 << ", " - << "\"value\": \""; - it1->value->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"}"; - } - output << "]}"; - } - output << "]"; -} - -ShocksStatement::ShocksStatement(bool overwrite_arg, - const det_shocks_t &det_shocks_arg, - const var_and_std_shocks_t &var_shocks_arg, - const var_and_std_shocks_t &std_shocks_arg, - const covar_and_corr_shocks_t &covar_shocks_arg, - const covar_and_corr_shocks_t &corr_shocks_arg, - const SymbolTable &symbol_table_arg) : - AbstractShocksStatement(false, overwrite_arg, det_shocks_arg, symbol_table_arg), - var_shocks(var_shocks_arg), - std_shocks(std_shocks_arg), - covar_shocks(covar_shocks_arg), - corr_shocks(corr_shocks_arg) -{ -} - -void -ShocksStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "%" << endl - << "% SHOCKS instructions" << endl - << "%" << endl; - - if (overwrite) - { - output << "M_.det_shocks = [];" << endl; - - output << "M_.Sigma_e = zeros(" << symbol_table.exo_nbr() << ", " - << symbol_table.exo_nbr() << ");" << endl - << "M_.Correlation_matrix = eye(" << symbol_table.exo_nbr() << ", " - << symbol_table.exo_nbr() << ");" << endl; - - if (has_calibrated_measurement_errors()) - output << "M_.H = zeros(" << symbol_table.observedVariablesNbr() << ", " - << symbol_table.observedVariablesNbr() << ");" << endl - << "M_.Correlation_matrix_ME = eye(" << symbol_table.observedVariablesNbr() << ", " - << symbol_table.observedVariablesNbr() << ");" << endl; - else - output << "M_.H = 0;" << endl - << "M_.Correlation_matrix_ME = 1;" << endl; - - } - - writeDetShocks(output); - writeVarAndStdShocks(output); - writeCovarAndCorrShocks(output); - - /* M_.sigma_e_is_diagonal is initialized to 1 by ModFile.cc. - If there are no off-diagonal elements, and we are not in overwrite mode, - then we don't reset it to 1, since there might be previous shocks blocks - with off-diagonal elements. */ - if (covar_shocks.size()+corr_shocks.size() > 0) - output << "M_.sigma_e_is_diagonal = 0;" << endl; - else if (overwrite) - output << "M_.sigma_e_is_diagonal = 1;" << endl; -} - -void -ShocksStatement::writeJsonOutput(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - output << "{\"statementName\": \"shocks\"" - << ", \"overwrite\": "; - if (overwrite) - output << "true"; - else - output << "false"; - if (!det_shocks.empty()) - { - output << ", "; - writeJsonDetShocks(output); - } - output<< ", \"variance\": ["; - for (var_and_std_shocks_t::const_iterator it = var_shocks.begin(); it != var_shocks.end(); it++) - { - if (it != var_shocks.begin()) - output << ", "; - output << "{\"name\": \"" << symbol_table.getName(it->first) << "\", " - << "\"variance\": \""; - it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"}"; - } - output << "]" - << ", \"stderr\": ["; - for (var_and_std_shocks_t::const_iterator it = std_shocks.begin(); it != std_shocks.end(); it++) - { - if (it != std_shocks.begin()) - output << ", "; - output << "{\"name\": \"" << symbol_table.getName(it->first) << "\", " - << "\"stderr\": \""; - it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"}"; - } - output << "]" - << ", \"covariance\": ["; - for (covar_and_corr_shocks_t::const_iterator it = covar_shocks.begin(); it != covar_shocks.end(); it++) - { - if (it != covar_shocks.begin()) - output << ", "; - output << "{" - << "\"name\": \"" << symbol_table.getName(it->first.first) << "\", " - << "\"name2\": \"" << symbol_table.getName(it->first.second) << "\", " - << "\"covariance\": \""; - it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"}"; - } - output << "]" - << ", \"correlation\": ["; - for (covar_and_corr_shocks_t::const_iterator it = corr_shocks.begin(); it != corr_shocks.end(); it++) - { - if (it != corr_shocks.begin()) - output << ", "; - output << "{" - << "\"name\": \"" << symbol_table.getName(it->first.first) << "\", " - << "\"name2\": \"" << symbol_table.getName(it->first.second) << "\", " - << "\"correlation\": \""; - it->second->writeJsonOutput(output, temporary_terms_t(), tef_terms); - output << "\"}"; - } - output << "]" - << "}"; -} - -void -ShocksStatement::writeVarOrStdShock(ostream &output, var_and_std_shocks_t::const_iterator &it, - bool stddev) const -{ - SymbolType type = symbol_table.getType(it->first); - assert(type == eExogenous || symbol_table.isObservedVariable(it->first)); - - int id; - if (type == eExogenous) - { - output << "M_.Sigma_e("; - id = symbol_table.getTypeSpecificID(it->first) + 1; - } - else - { - output << "M_.H("; - id = symbol_table.getObservedVariableIndex(it->first) + 1; - } - - output << id << ", " << id << ") = "; - if (stddev) - output << "("; - it->second->writeOutput(output); - if (stddev) - output << ")^2"; - output << ";" << endl; -} - -void -ShocksStatement::writeVarAndStdShocks(ostream &output) const -{ - var_and_std_shocks_t::const_iterator it; - - for (it = var_shocks.begin(); it != var_shocks.end(); it++) - writeVarOrStdShock(output, it, false); - - for (it = std_shocks.begin(); it != std_shocks.end(); it++) - writeVarOrStdShock(output, it, true); -} - -void -ShocksStatement::writeCovarOrCorrShock(ostream &output, covar_and_corr_shocks_t::const_iterator &it, - bool corr) const -{ - SymbolType type1 = symbol_table.getType(it->first.first); - SymbolType type2 = symbol_table.getType(it->first.second); - assert((type1 == eExogenous && type2 == eExogenous) - || (symbol_table.isObservedVariable(it->first.first) && symbol_table.isObservedVariable(it->first.second))); - string matrix, corr_matrix; - int id1, id2; - if (type1 == eExogenous) - { - matrix = "M_.Sigma_e"; - corr_matrix = "M_.Correlation_matrix"; - id1 = symbol_table.getTypeSpecificID(it->first.first) + 1; - id2 = symbol_table.getTypeSpecificID(it->first.second) + 1; - } - else - { - matrix = "M_.H"; - corr_matrix = "M_.Correlation_matrix_ME"; - id1 = symbol_table.getObservedVariableIndex(it->first.first) + 1; - id2 = symbol_table.getObservedVariableIndex(it->first.second) + 1; - } - - output << matrix << "(" << id1 << ", " << id2 << ") = "; - it->second->writeOutput(output); - if (corr) - output << "*sqrt(" << matrix << "(" << id1 << ", " << id1 << ")*" - << matrix << "(" << id2 << ", " << id2 << "))"; - output << ";" << endl - << matrix << "(" << id2 << ", " << id1 << ") = " - << matrix << "(" << id1 << ", " << id2 << ");" << endl; - - if (corr) - { - output << corr_matrix << "(" << id1 << ", " << id2 << ") = "; - it->second->writeOutput(output); - output << ";" << endl - << corr_matrix << "(" << id2 << ", " << id1 << ") = " - << corr_matrix << "(" << id1 << ", " << id2 << ");" << endl; - } -} - -void -ShocksStatement::writeCovarAndCorrShocks(ostream &output) const -{ - covar_and_corr_shocks_t::const_iterator it; - - for (it = covar_shocks.begin(); it != covar_shocks.end(); it++) - writeCovarOrCorrShock(output, it, false); - - for (it = corr_shocks.begin(); it != corr_shocks.end(); it++) - writeCovarOrCorrShock(output, it, true); -} - -void -ShocksStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - /* Error out if variables are not of the right type. This must be done here - and not at parsing time (see #448). - Also Determine if there is a calibrated measurement error */ - for (var_and_std_shocks_t::const_iterator it = var_shocks.begin(); - it != var_shocks.end(); it++) - { - if (symbol_table.getType(it->first) != eExogenous - && !symbol_table.isObservedVariable(it->first)) - { - cerr << "shocks: setting a variance on '" - << symbol_table.getName(it->first) << "' is not allowed, because it is neither an exogenous variable nor an observed endogenous variable" << endl; - exit(EXIT_FAILURE); - } - } - - for (var_and_std_shocks_t::const_iterator it = std_shocks.begin(); - it != std_shocks.end(); it++) - { - if (symbol_table.getType(it->first) != eExogenous - && !symbol_table.isObservedVariable(it->first)) - { - cerr << "shocks: setting a standard error on '" - << symbol_table.getName(it->first) << "' is not allowed, because it is neither an exogenous variable nor an observed endogenous variable" << endl; - exit(EXIT_FAILURE); - } - } - - for (covar_and_corr_shocks_t::const_iterator it = covar_shocks.begin(); - it != covar_shocks.end(); it++) - { - int symb_id1 = it->first.first; - int symb_id2 = it->first.second; - - if (!((symbol_table.getType(symb_id1) == eExogenous - && symbol_table.getType(symb_id2) == eExogenous) - || (symbol_table.isObservedVariable(symb_id1) - && symbol_table.isObservedVariable(symb_id2)))) - { - cerr << "shocks: setting a covariance between '" - << symbol_table.getName(symb_id1) << "' and '" - << symbol_table.getName(symb_id2) << "'is not allowed; covariances can only be specified for exogenous or observed endogenous variables of same type" << endl; - exit(EXIT_FAILURE); - } - } - - for (covar_and_corr_shocks_t::const_iterator it = corr_shocks.begin(); - it != corr_shocks.end(); it++) - { - int symb_id1 = it->first.first; - int symb_id2 = it->first.second; - - if (!((symbol_table.getType(symb_id1) == eExogenous - && symbol_table.getType(symb_id2) == eExogenous) - || (symbol_table.isObservedVariable(symb_id1) - && symbol_table.isObservedVariable(symb_id2)))) - { - cerr << "shocks: setting a correlation between '" - << symbol_table.getName(symb_id1) << "' and '" - << symbol_table.getName(symb_id2) << "'is not allowed; correlations can only be specified for exogenous or observed endogenous variables of same type" << endl; - exit(EXIT_FAILURE); - } - } - - // Determine if there is a calibrated measurement error - mod_file_struct.calibrated_measurement_errors |= has_calibrated_measurement_errors(); - - // Fill in mod_file_struct.parameters_with_shocks_values (related to #469) - for (var_and_std_shocks_t::const_iterator it = var_shocks.begin(); - it != var_shocks.end(); ++it) - it->second->collectVariables(eParameter, mod_file_struct.parameters_within_shocks_values); - for (var_and_std_shocks_t::const_iterator it = std_shocks.begin(); - it != std_shocks.end(); ++it) - it->second->collectVariables(eParameter, mod_file_struct.parameters_within_shocks_values); - for (covar_and_corr_shocks_t::const_iterator it = covar_shocks.begin(); - it != covar_shocks.end(); ++it) - it->second->collectVariables(eParameter, mod_file_struct.parameters_within_shocks_values); - for (covar_and_corr_shocks_t::const_iterator it = corr_shocks.begin(); - it != corr_shocks.end(); ++it) - it->second->collectVariables(eParameter, mod_file_struct.parameters_within_shocks_values); - -} - -bool -ShocksStatement::has_calibrated_measurement_errors() const -{ - for (var_and_std_shocks_t::const_iterator it = var_shocks.begin(); - it != var_shocks.end(); it++) - if (symbol_table.isObservedVariable(it->first)) - return true; - - for (var_and_std_shocks_t::const_iterator it = std_shocks.begin(); - it != std_shocks.end(); it++) - if (symbol_table.isObservedVariable(it->first)) - return true; - - for (covar_and_corr_shocks_t::const_iterator it = covar_shocks.begin(); - it != covar_shocks.end(); it++) - if (symbol_table.isObservedVariable(it->first.first) - || symbol_table.isObservedVariable(it->first.second)) - return true; - - for (covar_and_corr_shocks_t::const_iterator it = corr_shocks.begin(); - it != corr_shocks.end(); it++) - if (symbol_table.isObservedVariable(it->first.first) - || symbol_table.isObservedVariable(it->first.second)) - return true; - - return false; -} - -MShocksStatement::MShocksStatement(bool overwrite_arg, - const det_shocks_t &det_shocks_arg, - const SymbolTable &symbol_table_arg) : - AbstractShocksStatement(true, overwrite_arg, det_shocks_arg, symbol_table_arg) -{ -} - -void -MShocksStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "%" << endl - << "% MSHOCKS instructions" << endl - << "%" << endl; - - if (overwrite) - output << "M_.det_shocks = [];" << endl; - - writeDetShocks(output); -} - -ConditionalForecastPathsStatement::ConditionalForecastPathsStatement(const AbstractShocksStatement::det_shocks_t &paths_arg, - const SymbolTable &symbol_table_arg) : - paths(paths_arg), - symbol_table(symbol_table_arg), - path_length(-1) -{ -} - -void -ConditionalForecastPathsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - for (AbstractShocksStatement::det_shocks_t::const_iterator it = paths.begin(); - it != paths.end(); it++) - { - int this_path_length = 0; - const vector &elems = it->second; - for (int i = 0; i < (int) elems.size(); i++) - // Period1 < Period2, as enforced in ParsingDriver::add_period() - this_path_length = max(this_path_length, elems[i].period2); - if (path_length == -1) - path_length = this_path_length; - else if (path_length != this_path_length) - { - cerr << "conditional_forecast_paths: all constrained paths must have the same length!" << endl; - exit(EXIT_FAILURE); - } - } -} - -void -ConditionalForecastPathsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - assert(path_length > 0); - output << "constrained_vars_ = [];" << endl - << "constrained_paths_ = zeros(" << paths.size() << ", " << path_length << ");" << endl; - - int k = 1; - for (AbstractShocksStatement::det_shocks_t::const_iterator it = paths.begin(); - it != paths.end(); it++, k++) - { - if (it == paths.begin()) - output << "constrained_vars_ = " << symbol_table.getTypeSpecificID(it->first) + 1 << ";" << endl; - else - output << "constrained_vars_ = [constrained_vars_; " << symbol_table.getTypeSpecificID(it->first) + 1 << "];" << endl; - - const vector &elems = it->second; - for (int i = 0; i < (int) elems.size(); i++) - for (int j = elems[i].period1; j <= elems[i].period2; j++) - { - output << "constrained_paths_(" << k << "," << j << ")="; - elems[i].value->writeOutput(output); - output << ";" << endl; - } - } -} - -MomentCalibration::MomentCalibration(const constraints_t &constraints_arg, - const SymbolTable &symbol_table_arg) - : constraints(constraints_arg), symbol_table(symbol_table_arg) -{ -} - -void -MomentCalibration::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - output << "options_.endogenous_prior_restrictions.moment = {" << endl; - for (size_t i = 0; i < constraints.size(); i++) - { - const Constraint &c = constraints[i]; - output << "'" << symbol_table.getName(c.endo1) << "', " - << "'" << symbol_table.getName(c.endo2) << "', " - << c.lags << ", " - << "[ " << c.lower_bound << ", " << c.upper_bound << " ];" - << endl; - } - output << "};" << endl; -} - -void -MomentCalibration::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"moment_calibration\"" - << ", \"moment_calibration_criteria\": ["; - for (constraints_t::const_iterator it = constraints.begin(); it != constraints.end(); it++) - { - if (it != constraints.begin()) - output << ", "; - output << "{\"endogenous1\": \"" << symbol_table.getName(it->endo1) << "\"" - << ", \"endogenous2\": \"" << symbol_table.getName(it->endo2) << "\"" - << ", \"lags\": \"" << it->lags << "\"" - << ", \"lower_bound\": \"" << it->lower_bound << "\"" - << ", \"upper_bound\": \"" << it->upper_bound << "\"" - << "}"; - } - output << "]" - << "}"; -} - -IrfCalibration::IrfCalibration(const constraints_t &constraints_arg, - const SymbolTable &symbol_table_arg, - const OptionsList &options_list_arg) - : constraints(constraints_arg), symbol_table(symbol_table_arg), options_list(options_list_arg) -{ -} - -void -IrfCalibration::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - options_list.writeOutput(output); - - output << "options_.endogenous_prior_restrictions.irf = {" << endl; - for (size_t i = 0; i < constraints.size(); i++) - { - const Constraint &c = constraints[i]; - output << "'" << symbol_table.getName(c.endo) << "', " - << "'" << symbol_table.getName(c.exo) << "', " - << c.periods << ", " - << "[ " << c.lower_bound << ", " << c.upper_bound << " ];" - << endl; - } - output << "};" << endl; -} - -void -IrfCalibration::writeJsonOutput(ostream &output) const -{ - output << "{\"statementName\": \"irf_calibration\""; - if (options_list.getNumberOfOptions()) - { - output << ", "; - options_list.writeJsonOutput(output); - } - - output << ", \"irf_restrictions\": ["; - for (constraints_t::const_iterator it = constraints.begin(); it != constraints.end(); it++) - { - if (it != constraints.begin()) - output << ", "; - output << "{\"endogenous\": \"" << symbol_table.getName(it->endo) << "\"" - << ", \"exogenous\": \"" << symbol_table.getName(it->exo) << "\"" - << ", \"periods\": \"" << it->periods << "\"" - << ", \"lower_bound\": \"" << it->lower_bound << "\"" - << ", \"upper_bound\": \"" << it->upper_bound << "\"" - << "}"; - } - output << "]" - << "}"; -} - -ShockGroupsStatement::ShockGroupsStatement(const group_t &shock_groups_arg, const string &name_arg) - : shock_groups(shock_groups_arg), name(name_arg) -{ -} - -void -ShockGroupsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - int i = 1; - bool unique_label = true; - for (vector::const_iterator it = shock_groups.begin(); it != shock_groups.end(); it++, unique_label = true) - { - for (vector::const_iterator it1 = it+1; it1 != shock_groups.end(); it1++) - if (it->name == it1->name) - { - unique_label = false; - cerr << "Warning: shock group label '" << it->name << "' has been reused. " - << "Only using the last definition." << endl; - break; - } - - if (unique_label) - { - output << "M_.shock_groups." << name - << ".group" << i << ".label = '" << it->name << "';" << endl - << "M_.shock_groups." << name - << ".group" << i << ".shocks = {"; - for (vector::const_iterator it1 = it->list.begin(); it1 != it->list.end(); it1++) - output << " '" << *it1 << "'"; - output << "};" << endl; - i++; - } - } -} diff --git a/preprocessor/Shocks.hh b/preprocessor/Shocks.hh deleted file mode 100644 index 618bf34b2..000000000 --- a/preprocessor/Shocks.hh +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#ifndef _SHOCKS_HH -#define _SHOCKS_HH - -using namespace std; - -#include -#include -#include - -#include "Statement.hh" -#include "SymbolTable.hh" -#include "ExprNode.hh" - -class AbstractShocksStatement : public Statement -{ -public: - struct DetShockElement - { - int period1; - int period2; - expr_t value; - }; - //The boolean element indicates if the shock is a surprise (false) or a perfect foresight (true) shock. - //This boolean is used only in case of conditional forecast with extended path method (simulation_type = deterministic). - typedef map > det_shocks_t; -protected: - //! Is this statement a "mshocks" statement ? (instead of a "shocks" statement) - const bool mshocks; - //! Does this "shocks" statement replace the previous ones? - const bool overwrite; - const det_shocks_t det_shocks; - const SymbolTable &symbol_table; - void writeDetShocks(ostream &output) const; - void writeJsonDetShocks(ostream &output) const; - - AbstractShocksStatement(bool mshocks_arg, bool overwrite_arg, - const det_shocks_t &det_shocks_arg, - const SymbolTable &symbol_table_arg); -}; - -class ShocksStatement : public AbstractShocksStatement -{ -public: - typedef map var_and_std_shocks_t; - typedef map, expr_t> covar_and_corr_shocks_t; -private: - const var_and_std_shocks_t var_shocks, std_shocks; - const covar_and_corr_shocks_t covar_shocks, corr_shocks; - void writeVarOrStdShock(ostream &output, var_and_std_shocks_t::const_iterator &it, bool stddev) const; - void writeVarAndStdShocks(ostream &output) const; - void writeCovarOrCorrShock(ostream &output, covar_and_corr_shocks_t::const_iterator &it, bool corr) const; - void writeCovarAndCorrShocks(ostream &output) const; - bool has_calibrated_measurement_errors() const; -public: - ShocksStatement(bool overwrite_arg, - const det_shocks_t &det_shocks_arg, - const var_and_std_shocks_t &var_shocks_arg, - const var_and_std_shocks_t &std_shocks_arg, - const covar_and_corr_shocks_t &covar_shocks_arg, - const covar_and_corr_shocks_t &corr_shocks_arg, - const SymbolTable &symbol_table_arg); - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class MShocksStatement : public AbstractShocksStatement -{ -public: - MShocksStatement(bool overwrite_arg, - const det_shocks_t &det_shocks_arg, - const SymbolTable &symbol_table_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; -}; - -class ConditionalForecastPathsStatement : public Statement -{ -private: - const AbstractShocksStatement::det_shocks_t paths; - const SymbolTable &symbol_table; - int path_length; -public: - ConditionalForecastPathsStatement(const AbstractShocksStatement::det_shocks_t &paths_arg, - const SymbolTable &symbol_table_arg); - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; -}; - -class MomentCalibration : public Statement -{ -public: - struct Constraint - { - int endo1, endo2; - string lags; - string lower_bound, upper_bound; - }; - typedef vector constraints_t; -private: - constraints_t constraints; - const SymbolTable &symbol_table; -public: - MomentCalibration(const constraints_t &constraints_arg, - const SymbolTable &symbol_table_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class IrfCalibration : public Statement -{ -public: - struct Constraint - { - int endo; - int exo; - string periods, lower_bound, upper_bound; - }; - typedef vector constraints_t; -private: - constraints_t constraints; - const SymbolTable &symbol_table; - const OptionsList options_list; -public: - IrfCalibration(const constraints_t &constraints_arg, - const SymbolTable &symbol_table_arg, - const OptionsList &options_list_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class ShockGroupsStatement : public Statement -{ -public: - struct Group - { - string name; - vector list; - }; - typedef vector group_t; -private: - group_t shock_groups; - vector group_names; - string name; -public: - ShockGroupsStatement(const group_t &shock_groups_arg, const string &name_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; -}; - -#endif diff --git a/preprocessor/SigmaeInitialization.cc b/preprocessor/SigmaeInitialization.cc deleted file mode 100644 index 63d6a0b58..000000000 --- a/preprocessor/SigmaeInitialization.cc +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2003-2015 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 . - */ - -#include "SigmaeInitialization.hh" - -SigmaeStatement::SigmaeStatement(const matrix_t &matrix_arg) throw (MatrixFormException) : - matrix(matrix_arg), - matrix_form(determineMatrixForm(matrix)) -{ -} - -SigmaeStatement::matrix_form_t -SigmaeStatement::determineMatrixForm(const matrix_t &matrix) throw (MatrixFormException) -{ - size_t nbe; - int inc; - matrix_form_t type; - // Checking if first or last row has one element. - if (matrix.front().size() == 1) - { - inc = 1; - nbe = 2; - type = eLower; - } - else if (matrix.back().size() == 1) - { - inc = -1; - nbe = matrix.front().size()-1; - type = eUpper; - } - else - throw MatrixFormException(); - - // Checking if matrix is triangular (upper or lower): - // each row has one element more or less than the previous one - // and first or last one has one element. - matrix_t::const_iterator ir; - for (ir = matrix.begin(), ir++; ir != matrix.end(); ir++, nbe += inc) - if (ir->size() != nbe) - throw MatrixFormException(); - - return type; -} - -void -SigmaeStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - size_t ic, ic1, ir, ir1; - - output << "M_.Sigma_e = [..." << endl; - for (ir = 0; ir < matrix.size(); ir++) - { - for (ic = 0; ic < matrix.size(); ic++) - { - if (ic >= ir && matrix_form == eUpper) - { - ic1 = ic-ir; - ir1 = ir; - } - else if (ic < ir && matrix_form == eUpper) - { - ic1 = ir-ic; - ir1 = ic; - } - else if (ic > ir && matrix_form == eLower) - { - ic1 = ir; - ir1 = ic; - } - else // ic <= ir && matrix_form == eLower - { - ic1 = ic; - ir1 = ir; - } - - matrix[ir1][ic1]->writeOutput(output); - output << " "; - } - output << ";..." << endl; - } - output << "];" << endl; -} diff --git a/preprocessor/SigmaeInitialization.hh b/preprocessor/SigmaeInitialization.hh deleted file mode 100644 index 41e24e329..000000000 --- a/preprocessor/SigmaeInitialization.hh +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2003-2015 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 . - */ - -#ifndef _SIGMAEINITIALIZATION_HH -#define _SIGMAEINITIALIZATION_HH - -#include -#include - -#include "ExprNode.hh" -#include "Statement.hh" - -//! Stores a Sigma_e statement -class SigmaeStatement : public Statement -{ -public: - //! Matrix form (lower or upper triangular) enum - enum matrix_form_t - { - eLower = 0, //!< Lower triangular matrix - eUpper = 1 //!< Upper triangular matrix - }; - //! Type of a matrix row - typedef vector row_t; - //! Type of a complete matrix - typedef vector matrix_t; - - //! An exception indicating that a matrix is neither upper triangular nor lower triangular - class MatrixFormException - { - }; -private: - //! The matrix - const matrix_t matrix; - //! Matrix form (lower or upper) - const matrix_form_t matrix_form; - - //! Returns the type (upper or lower triangular) of a given matrix - /*! Throws an exception if it is neither upper triangular nor lower triangular */ - static matrix_form_t determineMatrixForm(const matrix_t &matrix) throw (MatrixFormException); - -public: - SigmaeStatement(const matrix_t &matrix_arg) throw (MatrixFormException); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; -}; - -#endif diff --git a/preprocessor/Statement.cc b/preprocessor/Statement.cc deleted file mode 100644 index 8a86f75a9..000000000 --- a/preprocessor/Statement.cc +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright (C) 2006-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 . - */ - -#include "Statement.hh" -#include - -ModFileStructure::ModFileStructure() : - check_present(false), - steady_present(false), - perfect_foresight_solver_present(false), - stoch_simul_present(false), - estimation_present(false), - osr_present(false), - osr_params_present(false), - optim_weights_present(false), - ramsey_model_present(false), - ramsey_policy_present(false), - discretionary_policy_present(false), - planner_objective_present(false), - extended_path_present(false), - order_option(0), - bvar_present(false), - svar_identification_present(false), - identification_present(false), - estimation_analytic_derivation(false), - partial_information(false), - k_order_solver(false), - calibrated_measurement_errors(false), - dsge_prior_weight_in_estimated_params(false), - dsge_var_calibrated(""), - dsge_var_estimated(false), - bayesian_irf_present(false), - estimation_data_statement_present(false), - last_markov_switching_chain(0), - calib_smoother_present(false), - estim_params_use_calib(false), - prior_statement_present(false), - std_prior_statement_present(false), - corr_prior_statement_present(false), - options_statement_present(false), - std_options_statement_present(false), - corr_options_statement_present(false), - ms_dsge_present(false), - occbin_option(false), - orig_eq_nbr(0), - ramsey_eq_nbr(0), - steady_state_model_present(false), - write_latex_steady_state_model_present(false) -{ -} - -Statement::~Statement() -{ -} - -void -Statement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ -} - -void -Statement::writeCOutput(ostream &output, const string &basename) -{ -} - -void -Statement::writeJuliaOutput(ostream &output, const string &basename) -{ -} - -void -Statement::writeJsonOutput(ostream &output) const -{ -} - -void -Statement::computingPass() -{ -} - -NativeStatement::NativeStatement(const string &native_statement_arg) : - native_statement(native_statement_arg) -{ -} - -void -NativeStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const -{ - using namespace boost::xpressive; - string date_regex = "(-?\\d+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4]\\d|5[0-2])))"; - sregex regex_lookbehind = sregex::compile("(?first << " = " << it->second << ";" << endl; - - for (paired_num_options_t::const_iterator it = paired_num_options.begin(); - it != paired_num_options.end(); it++) - output << "options_." << it->first << " = [" << it->second.first << "; " - << it->second.second << "];" << endl; - - for (string_options_t::const_iterator it = string_options.begin(); - it != string_options.end(); it++) - output << "options_." << it->first << " = '" << it->second << "';" << endl; - - for (date_options_t::const_iterator it = date_options.begin(); - it != date_options.end(); it++) - output << "options_." << it->first << " = " << it->second << ";" << endl; - - for (symbol_list_options_t::const_iterator it = symbol_list_options.begin(); - it != symbol_list_options.end(); it++) - it->second.writeOutput("options_." + it->first, output); - - for (vec_int_options_t::const_iterator it = vector_int_options.begin(); - it != vector_int_options.end(); it++) - { - output << "options_." << it->first << " = "; - if (it->second.size() > 1) - { - output << "["; - for (vector::const_iterator viit = it->second.begin(); - viit != it->second.end(); viit++) - output << *viit << ";"; - output << "];" << endl; - } - else - output << it->second.front() << ";" << endl; - } -} - -void -OptionsList::writeOutput(ostream &output, const string &option_group) const -{ - // Initialize option_group as an empty struct iff the field does not exist! - unsigned idx = option_group.find_last_of("."); - if (idx < UINT_MAX) - { - output << "if ~isfield(" << option_group.substr(0, idx) << ",'" << option_group.substr(idx+1) << "')" << endl; - output << " " << option_group << " = struct();" << endl; - output << "end" << endl; - } - else - output << option_group << " = struct();" << endl; - - for (num_options_t::const_iterator it = num_options.begin(); - it != num_options.end(); it++) - output << option_group << "." << it->first << " = " << it->second << ";" << endl; - - for (paired_num_options_t::const_iterator it = paired_num_options.begin(); - it != paired_num_options.end(); it++) - output << option_group << "." << it->first << " = [" << it->second.first << "; " - << it->second.second << "];" << endl; - - for (string_options_t::const_iterator it = string_options.begin(); - it != string_options.end(); it++) - output << option_group << "." << it->first << " = '" << it->second << "';" << endl; - - for (date_options_t::const_iterator it = date_options.begin(); - it != date_options.end(); it++) - output << option_group << "." << it->first << " = " << it->second << ";" << endl; - - for (symbol_list_options_t::const_iterator it = symbol_list_options.begin(); - it != symbol_list_options.end(); it++) - it->second.writeOutput(option_group + "." + it->first, output); - - for (vec_int_options_t::const_iterator it = vector_int_options.begin(); - it != vector_int_options.end(); it++) - { - output << option_group << "." << it->first << " = "; - if (it->second.size() > 1) - { - output << "["; - for (vector::const_iterator viit = it->second.begin(); - viit != it->second.end(); viit++) - output << *viit << ";"; - output << "];" << endl; - } - else - output << it->second.front() << ";" << endl; - } -} - -void -OptionsList::writeJsonOutput(ostream &output) const -{ - if (getNumberOfOptions() == 0) - return; - - output << "\"options\": {"; - for (num_options_t::const_iterator it = num_options.begin(); - it != num_options.end();) - { - output << "\""<< it->first << "\": " << it->second; - it++; - if (it != num_options.end() - || !(paired_num_options.empty() - && string_options.empty() - && date_options.empty() - && symbol_list_options.empty() - && vector_int_options.empty())) - output << ", "; - } - - for (paired_num_options_t::const_iterator it = paired_num_options.begin(); - it != paired_num_options.end();) - { - output << "\""<< it->first << "\": [" << it->second.first << " " << it->second.second << "]"; - it++; - if (it != paired_num_options.end() - || !(string_options.empty() - && date_options.empty() - && symbol_list_options.empty() - && vector_int_options.empty())) - output << ", "; - } - - for (string_options_t::const_iterator it = string_options.begin(); - it != string_options.end();) - { - output << "\""<< it->first << "\": \"" << it->second << "\""; - it++; - if (it != string_options.end() - || !(date_options.empty() - && symbol_list_options.empty() - && vector_int_options.empty())) - output << ", "; - } - - for (date_options_t::const_iterator it = date_options.begin(); - it != date_options.end();) - { - output << "\""<< it->first << "\": \"" << it->second << "\""; - it++; - if (it != date_options.end() - || !(symbol_list_options.empty() - && vector_int_options.empty())) - output << ", "; - } - - for (symbol_list_options_t::const_iterator it = symbol_list_options.begin(); - it != symbol_list_options.end(); it++) - { - output << "\""<< it->first << "\":"; - it->second.writeJsonOutput(output); - it++; - if (it != symbol_list_options.end() - || !vector_int_options.empty()) - output << ", "; - } - - for (vec_int_options_t::const_iterator it = vector_int_options.begin(); - it != vector_int_options.end();) - { - output << "\""<< it->first << "\": ["; - if (it->second.size() > 1) - { - for (vector::const_iterator viit = it->second.begin(); - viit != it->second.end();) - { - output << *viit; - viit++; - if (viit != it->second.end()) - output << ", "; - } - } - else - output << it->second.front() << endl; - output << "]"; - it++; - if (it != vector_int_options.end()) - output << ", "; - } - - output << "}"; -} - -void -OptionsList::clear() -{ - num_options.clear(); - paired_num_options.clear(); - string_options.clear(); - date_options.clear(); - symbol_list_options.clear(); - vector_int_options.clear(); -} - -int -OptionsList::getNumberOfOptions() const -{ - return num_options.size() - + paired_num_options.size() - + string_options.size() - + date_options.size() - + symbol_list_options.size() - + vector_int_options.size(); -} diff --git a/preprocessor/Statement.hh b/preprocessor/Statement.hh deleted file mode 100644 index a6a1d5c32..000000000 --- a/preprocessor/Statement.hh +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) 2006-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 . - */ - -#ifndef _STATEMENT_HH -#define _STATEMENT_HH - -#include -#include -#include -#include - -#include "SymbolList.hh" -#include "WarningConsolidation.hh" - -class ModFileStructure -{ -public: - ModFileStructure(); - //! Whether check is present - bool check_present; - //! Whether steady is present - bool steady_present; - //! Whether a perfect_foresight_solver/simul statement is present - bool perfect_foresight_solver_present; - //! Whether a stoch_simul statement is present - bool stoch_simul_present; - //! Whether an estimation statement is present - bool estimation_present; - //! Whether an osr statement is present - bool osr_present; - //! Whether an osr params statement is present - bool osr_params_present; - //! Whether an optim weight statement is present - bool optim_weights_present; - //! Whether a ramsey_model statement is present - bool ramsey_model_present; - //! Whether a ramsey_policy statement is present - bool ramsey_policy_present; - //! Whether a discretionary_objective statement is present - bool discretionary_policy_present; - //! Whether a planner_objective statement is present - bool planner_objective_present; - //! Whether an extended_path statement is present - bool extended_path_present; - //! The value of the "order" option of stoch_simul, estimation, osr, ramsey_policy - //! Derivation order - /*! First initialized to zero. If user sets order option somewhere in the MOD file, it will be equal to the maximum of order options. Otherwise will default to 2 */ - int order_option; - //! Whether a bvar_density, bvar_forecast, sbvar, ms_sbvar statement is present - bool bvar_present; - //! Whether an svar_identification statement is present - bool svar_identification_present; - //! Whether an identification statement is present or the identification option of dynare_sensitivity statement is equal to one - bool identification_present; - //! Whether the option analytic_derivation is given to estimation - bool estimation_analytic_derivation; - //! Whether the option partial_information is given to stoch_simul/estimation/osr/ramsey_policy - bool partial_information; - //! Whether the "k_order_solver" option is used (explictly, or implicitly if order >= 3) - bool k_order_solver; - //! Whether there is a calibrated measurement error - bool calibrated_measurement_errors; - //! Whether dsge_prior_weight was initialized as a parameter - bool dsge_prior_weight_initialized; - //! Whether dsge_prior_weight is in the estimated_params block - bool dsge_prior_weight_in_estimated_params; - //! Whether there is a dsge_var, with calibrated prior weight - string dsge_var_calibrated; - //! Whether there is a dsge_var, with prior weight that must be estimated - bool dsge_var_estimated; - //! Whether there is a bayesian_irf option passed to the estimation statement - bool bayesian_irf_present; - //! Whether there is a data statement present - bool estimation_data_statement_present; - //! Last chain number for Markov Switching statement2 - int last_markov_switching_chain; - //! Whether a calib_smoother statement is present - bool calib_smoother_present; - //! Whether there is an estimated_params_init with use_calibration - bool estim_params_use_calib; - //! Set of parameters used within shocks blocks, inside the expressions - //! defining the values of covariances (stored as symbol ids) - set parameters_within_shocks_values; - //! Set of estimated parameters (stored as symbol ids) - set estimated_parameters; - //! Whether there is a prior statement present - bool prior_statement_present; - //! Whether there is a std prior statement present - bool std_prior_statement_present; - //! Whether there is a corr prior statement present - bool corr_prior_statement_present; - //! Whether there is a options statement present - bool options_statement_present; - //! Whether there is a std options statement present - bool std_options_statement_present; - //! Whether there is a corr options statement present - bool corr_options_statement_present; - //! Whether a Markov Switching DSGE is present - bool ms_dsge_present; - //! Whether occbin is present - bool occbin_option; - //! Stores the original number of equations in the model_block - int orig_eq_nbr; - //! Stores the number of equations added to the Ramsey model - int ramsey_eq_nbr; - //! Whether there was a steady_state_model block - bool steady_state_model_present; - //! Whether there is a write_latex_steady_state_model statement present - bool write_latex_steady_state_model_present; - //! Histval values that do not have the appropriate lag - map hist_vals_wrong_lag; -}; - -class Statement -{ -public: - virtual - ~Statement(); - //! Do some internal check, and fill the ModFileStructure class - /*! Don't forget to update ComputingTasks.hh, Shocks.hh and - NumericalInitialization.hh if you modify the signature of this - method. Otherwise the default implementation (i.e. a no-op) will apply and - some checks won't be run. */ - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void computingPass(); - //! Write Matlab output code - /*! - \param output is the output stream of the main matlab file - \param basename is the name of the modfile (without extension) which can be used to build auxiliary files - */ - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const = 0; - virtual void writeCOutput(ostream &output, const string &basename); - virtual void writeJuliaOutput(ostream &output, const string &basename); - virtual void writeJsonOutput(ostream &output) const; -}; - -class NativeStatement : public Statement -{ -private: - const string native_statement; -public: - NativeStatement(const string &native_statement_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class VerbatimStatement : public Statement -{ -private: - const string verbatim_statement; -public: - VerbatimStatement(const string &verbatim_statement_arg); - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; - virtual void writeJsonOutput(ostream &output) const; -}; - -class OptionsList -{ -public: - typedef map num_options_t; - typedef map > paired_num_options_t; - typedef map string_options_t; - typedef map date_options_t; - typedef map symbol_list_options_t; - typedef map > vec_int_options_t; - num_options_t num_options; - paired_num_options_t paired_num_options; - string_options_t string_options; - date_options_t date_options; - symbol_list_options_t symbol_list_options; - vec_int_options_t vector_int_options; - int getNumberOfOptions() const; - void writeOutput(ostream &output) const; - void writeOutput(ostream &output, const string &option_group) const; - void writeJsonOutput(ostream &output) const; - void clear(); -}; - -#endif // ! _STATEMENT_HH diff --git a/preprocessor/StaticModel.cc b/preprocessor/StaticModel.cc deleted file mode 100644 index 11a033a86..000000000 --- a/preprocessor/StaticModel.cc +++ /dev/null @@ -1,2882 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include "StaticModel.hh" - -// For mkdir() and chdir() -#ifdef _WIN32 -# include -#else -# include -# include -# include -#endif - -StaticModel::StaticModel(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg) : - ModelTree(symbol_table_arg, num_constants_arg, external_functions_table_arg), - global_temporary_terms(true) -{ -} - -void -StaticModel::compileDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int symb_id, map_idx_t &map_idx, temporary_terms_t temporary_terms) const -{ - first_derivatives_t::const_iterator it = first_derivatives.find(make_pair(eq, getDerivID(symbol_table.getID(eEndogenous, symb_id), 0))); - if (it != first_derivatives.end()) - (it->second)->compile(code_file, instruction_number, false, temporary_terms, map_idx, false, false); - else - { - FLDZ_ fldz; - fldz.write(code_file, instruction_number); - } -} - -void -StaticModel::compileChainRuleDerivative(ofstream &code_file, unsigned int &instruction_number, int eqr, int varr, int lag, map_idx_t &map_idx, temporary_terms_t temporary_terms) const -{ - map >, expr_t>::const_iterator it = first_chain_rule_derivatives.find(make_pair(eqr, make_pair(varr, lag))); - if (it != first_chain_rule_derivatives.end()) - (it->second)->compile(code_file, instruction_number, false, temporary_terms, map_idx, false, false); - else - { - FLDZ_ fldz; - fldz.write(code_file, instruction_number); - } -} - -void -StaticModel::computeTemporaryTermsOrdered() -{ - map > first_occurence; - map reference_count; - BinaryOpNode *eq_node; - first_derivatives_t::const_iterator it; - first_chain_rule_derivatives_t::const_iterator it_chr; - ostringstream tmp_s; - v_temporary_terms.clear(); - map_idx.clear(); - - unsigned int nb_blocks = getNbBlocks(); - v_temporary_terms = vector< vector >(nb_blocks); - v_temporary_terms_local = vector< vector >(nb_blocks); - - v_temporary_terms_inuse = vector(nb_blocks); - - map_idx2 = vector(nb_blocks); - - temporary_terms.clear(); - - //local temporay terms - for (unsigned int block = 0; block < nb_blocks; block++) - { - map reference_count_local; - reference_count_local.clear(); - map > first_occurence_local; - first_occurence_local.clear(); - temporary_terms_t temporary_terms_l; - temporary_terms_l.clear(); - - unsigned int block_size = getBlockSize(block); - unsigned int block_nb_mfs = getBlockMfs(block); - unsigned int block_nb_recursives = block_size - block_nb_mfs; - v_temporary_terms_local[block] = vector(block_size); - - for (unsigned int i = 0; i < block_size; i++) - { - if (i < block_nb_recursives && isBlockEquationRenormalized(block, i)) - getBlockEquationRenormalizedExpr(block, i)->computeTemporaryTerms(reference_count_local, temporary_terms_l, first_occurence_local, block, v_temporary_terms_local, i); - else - { - eq_node = (BinaryOpNode *) getBlockEquationExpr(block, i); - eq_node->computeTemporaryTerms(reference_count_local, temporary_terms_l, first_occurence_local, block, v_temporary_terms_local, i); - } - } - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - { - expr_t id = it->second.second; - id->computeTemporaryTerms(reference_count_local, temporary_terms_l, first_occurence_local, block, v_temporary_terms_local, block_size-1); - } - set temporary_terms_in_use; - temporary_terms_in_use.clear(); - v_temporary_terms_inuse[block] = temporary_terms_in_use; - computeTemporaryTermsMapping(temporary_terms_l, map_idx2[block]); - } - - // global temporay terms - for (unsigned int block = 0; block < nb_blocks; block++) - { - // Compute the temporary terms reordered - unsigned int block_size = getBlockSize(block); - unsigned int block_nb_mfs = getBlockMfs(block); - unsigned int block_nb_recursives = block_size - block_nb_mfs; - v_temporary_terms[block] = vector(block_size); - for (unsigned int i = 0; i < block_size; i++) - { - if (i < block_nb_recursives && isBlockEquationRenormalized(block, i)) - getBlockEquationRenormalizedExpr(block, i)->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, i); - else - { - eq_node = (BinaryOpNode *) getBlockEquationExpr(block, i); - eq_node->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, i); - } - } - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - { - expr_t id = it->second.second; - id->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, block_size-1); - } - } - - for (unsigned int block = 0; block < nb_blocks; block++) - { - // Collecte the temporary terms reordered - unsigned int block_size = getBlockSize(block); - unsigned int block_nb_mfs = getBlockMfs(block); - unsigned int block_nb_recursives = block_size - block_nb_mfs; - set temporary_terms_in_use; - for (unsigned int i = 0; i < block_size; i++) - { - if (i < block_nb_recursives && isBlockEquationRenormalized(block, i)) - getBlockEquationRenormalizedExpr(block, i)->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block); - else - { - eq_node = (BinaryOpNode *) getBlockEquationExpr(block, i); - eq_node->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block); - } - } - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - { - expr_t id = it->second.second; - id->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block); - } - for (int i = 0; i < (int) getBlockSize(block); i++) - for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin(); - it != v_temporary_terms[block][i].end(); it++) - (*it)->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block); - v_temporary_terms_inuse[block] = temporary_terms_in_use; - } - computeTemporaryTermsMapping(temporary_terms, map_idx); -} - -void -StaticModel::computeTemporaryTermsMapping(temporary_terms_t &temporary_terms, map_idx_t &map_idx) -{ - // Add a mapping form node ID to temporary terms order - int j = 0; - for (temporary_terms_t::const_iterator it = temporary_terms.begin(); - it != temporary_terms.end(); it++) - map_idx[(*it)->idx] = j++; -} - -void -StaticModel::writeModelEquationsOrdered_M(const string &static_basename) const -{ - string tmp_s, sps; - ostringstream tmp_output, tmp1_output, global_output; - expr_t lhs = NULL, rhs = NULL; - BinaryOpNode *eq_node; - map reference_count; - temporary_terms_t local_temporary_terms; - ofstream output; - vector feedback_variables; - deriv_node_temp_terms_t tef_terms; - ExprNodeOutputType local_output_type; - - local_output_type = oMatlabStaticModelSparse; - if (global_temporary_terms) - local_temporary_terms = temporary_terms; - - //---------------------------------------------------------------------- - //For each block - for (unsigned int block = 0; block < getNbBlocks(); block++) - { - //recursive_variables.clear(); - feedback_variables.clear(); - //For a block composed of a single equation determines wether we have to evaluate or to solve the equation - BlockSimulationType simulation_type = getBlockSimulationType(block); - unsigned int block_size = getBlockSize(block); - unsigned int block_mfs = getBlockMfs(block); - unsigned int block_recursive = block_size - block_mfs; - - tmp1_output.str(""); - tmp1_output << static_basename << "_" << block+1 << ".m"; - output.open(tmp1_output.str().c_str(), ios::out | ios::binary); - output << "%\n"; - output << "% " << tmp1_output.str() << " : Computes static model for Dynare\n"; - output << "%\n"; - output << "% Warning : this file is generated automatically by Dynare\n"; - output << "% from model file (.mod)\n\n"; - output << "%/\n"; - if (simulation_type == EVALUATE_BACKWARD || simulation_type == EVALUATE_FORWARD) - output << "function y = " << static_basename << "_" << block+1 << "(y, x, params)\n"; - else - output << "function [residual, y, g1] = " << static_basename << "_" << block+1 << "(y, x, params)\n"; - - BlockType block_type; - if (simulation_type == SOLVE_FORWARD_COMPLETE || simulation_type == SOLVE_BACKWARD_COMPLETE) - block_type = SIMULTANS; - else if ((simulation_type == SOLVE_FORWARD_SIMPLE || simulation_type == SOLVE_BACKWARD_SIMPLE - || simulation_type == EVALUATE_BACKWARD || simulation_type == EVALUATE_FORWARD) - && getBlockFirstEquation(block) < prologue) - block_type = PROLOGUE; - else if ((simulation_type == SOLVE_FORWARD_SIMPLE || simulation_type == SOLVE_BACKWARD_SIMPLE - || simulation_type == EVALUATE_BACKWARD || simulation_type == EVALUATE_FORWARD) - && getBlockFirstEquation(block) >= equations.size() - epilogue) - block_type = EPILOGUE; - else - block_type = SIMULTANS; - output << " % ////////////////////////////////////////////////////////////////////////" << endl - << " % //" << string(" Block ").substr(int (log10(block + 1))) << block + 1 << " " << BlockType0(block_type) - << " //" << endl - << " % // Simulation type " - << BlockSim(simulation_type) << " //" << endl - << " % ////////////////////////////////////////////////////////////////////////" << endl; - output << " global options_;" << endl; - //The Temporary terms - if (simulation_type != EVALUATE_BACKWARD && simulation_type != EVALUATE_FORWARD) - output << " g1 = spalloc(" << block_mfs << ", " << block_mfs << ", " << derivative_endo[block].size() << ");" << endl; - - if (v_temporary_terms_inuse[block].size()) - { - tmp_output.str(""); - for (temporary_terms_inuse_t::const_iterator it = v_temporary_terms_inuse[block].begin(); - it != v_temporary_terms_inuse[block].end(); it++) - tmp_output << " T" << *it; - output << " global" << tmp_output.str() << ";\n"; - } - - if (simulation_type != EVALUATE_BACKWARD && simulation_type != EVALUATE_FORWARD) - output << " residual=zeros(" << block_mfs << ",1);\n"; - - // The equations - for (unsigned int i = 0; i < block_size; i++) - { - if (!global_temporary_terms) - local_temporary_terms = v_temporary_terms[block][i]; - temporary_terms_t tt2; - tt2.clear(); - if (v_temporary_terms[block].size()) - { - output << " " << "% //Temporary variables" << endl; - for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin(); - it != v_temporary_terms[block][i].end(); it++) - { - if (dynamic_cast(*it) != NULL) - (*it)->writeExternalFunctionOutput(output, local_output_type, tt2, tef_terms); - - output << " " << sps; - (*it)->writeOutput(output, local_output_type, local_temporary_terms, tef_terms); - output << " = "; - (*it)->writeOutput(output, local_output_type, tt2, tef_terms); - // Insert current node into tt2 - tt2.insert(*it); - output << ";" << endl; - } - } - - int variable_ID = getBlockVariableID(block, i); - int equation_ID = getBlockEquationID(block, i); - EquationType equ_type = getBlockEquationType(block, i); - string sModel = symbol_table.getName(symbol_table.getID(eEndogenous, variable_ID)); - eq_node = (BinaryOpNode *) getBlockEquationExpr(block, i); - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - tmp_output.str(""); - lhs->writeOutput(tmp_output, local_output_type, local_temporary_terms); - switch (simulation_type) - { - case EVALUATE_BACKWARD: - case EVALUATE_FORWARD: - evaluation: - output << " % equation " << getBlockEquationID(block, i)+1 << " variable : " << sModel - << " (" << variable_ID+1 << ") " << c_Equation_Type(equ_type) << endl; - output << " "; - if (equ_type == E_EVALUATE) - { - output << tmp_output.str(); - output << " = "; - rhs->writeOutput(output, local_output_type, local_temporary_terms); - } - else if (equ_type == E_EVALUATE_S) - { - output << "%" << tmp_output.str(); - output << " = "; - if (isBlockEquationRenormalized(block, i)) - { - rhs->writeOutput(output, local_output_type, local_temporary_terms); - output << "\n "; - tmp_output.str(""); - eq_node = (BinaryOpNode *) getBlockEquationRenormalizedExpr(block, i); - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - lhs->writeOutput(output, local_output_type, local_temporary_terms); - output << " = "; - rhs->writeOutput(output, local_output_type, local_temporary_terms); - } - } - else - { - cerr << "Type mismatch for equation " << equation_ID+1 << "\n"; - exit(EXIT_FAILURE); - } - output << ";\n"; - break; - case SOLVE_BACKWARD_SIMPLE: - case SOLVE_FORWARD_SIMPLE: - case SOLVE_BACKWARD_COMPLETE: - case SOLVE_FORWARD_COMPLETE: - if (i < block_recursive) - goto evaluation; - feedback_variables.push_back(variable_ID); - output << " % equation " << equation_ID+1 << " variable : " << sModel - << " (" << variable_ID+1 << ") " << c_Equation_Type(equ_type) << endl; - output << " " << "residual(" << i+1-block_recursive << ") = ("; - goto end; - default: - end: - output << tmp_output.str(); - output << ") - ("; - rhs->writeOutput(output, local_output_type, local_temporary_terms); - output << ");\n"; - } - } - // The Jacobian if we have to solve the block - if (simulation_type == SOLVE_BACKWARD_SIMPLE || simulation_type == SOLVE_FORWARD_SIMPLE - || simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_FORWARD_COMPLETE) - output << " " << sps << "% Jacobian " << endl; - switch (simulation_type) - { - case SOLVE_BACKWARD_SIMPLE: - case SOLVE_FORWARD_SIMPLE: - case SOLVE_BACKWARD_COMPLETE: - case SOLVE_FORWARD_COMPLETE: - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - { - unsigned int eq = it->first.first; - unsigned int var = it->first.second; - unsigned int eqr = getBlockEquationID(block, eq); - unsigned int varr = getBlockVariableID(block, var); - expr_t id = it->second.second; - output << " g1(" << eq+1-block_recursive << ", " << var+1-block_recursive << ") = "; - id->writeOutput(output, local_output_type, local_temporary_terms); - output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr)) - << "(" << 0 - << ") " << varr+1 - << ", equation=" << eqr+1 << endl; - } - break; - default: - break; - } - output << "end" << endl; - output.close(); - } -} - -void -StaticModel::writeModelEquationsCode(const string file_name, const string bin_basename, map_idx_t map_idx) const -{ - - ostringstream tmp_output; - ofstream code_file; - unsigned int instruction_number = 0; - bool file_open = false; - - string main_name = file_name; - main_name += ".cod"; - code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate); - if (!code_file.is_open()) - { - cerr << "Error : Can't open file \"" << main_name << "\" for writing" << endl; - exit(EXIT_FAILURE); - } - int count_u; - int u_count_int = 0; - - Write_Inf_To_Bin_File(file_name, u_count_int, file_open, false, symbol_table.endo_nbr()); - file_open = true; - - //Temporary variables declaration - FDIMST_ fdimst(temporary_terms.size()); - fdimst.write(code_file, instruction_number); - FBEGINBLOCK_ fbeginblock(symbol_table.endo_nbr(), - SOLVE_FORWARD_COMPLETE, - 0, - symbol_table.endo_nbr(), - variable_reordered, - equation_reordered, - false, - symbol_table.endo_nbr(), - 0, - 0, - u_count_int, - symbol_table.endo_nbr() - ); - fbeginblock.write(code_file, instruction_number); - - // Add a mapping form node ID to temporary terms order - int j = 0; - for (temporary_terms_t::const_iterator it = temporary_terms.begin(); - it != temporary_terms.end(); it++) - map_idx[(*it)->idx] = j++; - compileTemporaryTerms(code_file, instruction_number, temporary_terms, map_idx, false, false); - - compileModelEquations(code_file, instruction_number, temporary_terms, map_idx, false, false); - - FENDEQU_ fendequ; - fendequ.write(code_file, instruction_number); - - // Get the current code_file position and jump if eval = true - streampos pos1 = code_file.tellp(); - FJMPIFEVAL_ fjmp_if_eval(0); - fjmp_if_eval.write(code_file, instruction_number); - int prev_instruction_number = instruction_number; - - vector > > derivatives; - derivatives.resize(symbol_table.endo_nbr()); - count_u = symbol_table.endo_nbr(); - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - int deriv_id = it->first.second; - if (getTypeByDerivID(deriv_id) == eEndogenous) - { - expr_t d1 = it->second; - unsigned int eq = it->first.first; - int symb = getSymbIDByDerivID(deriv_id); - unsigned int var = symbol_table.getTypeSpecificID(symb); - FNUMEXPR_ fnumexpr(FirstEndoDerivative, eq, var); - fnumexpr.write(code_file, instruction_number); - if (!derivatives[eq].size()) - derivatives[eq].clear(); - derivatives[eq].push_back(make_pair(var, count_u)); - - d1->compile(code_file, instruction_number, false, temporary_terms, map_idx, false, false); - - FSTPSU_ fstpsu(count_u); - fstpsu.write(code_file, instruction_number); - count_u++; - } - } - for (int i = 0; i < symbol_table.endo_nbr(); i++) - { - FLDR_ fldr(i); - fldr.write(code_file, instruction_number); - if (derivatives[i].size()) - { - for (vector >::const_iterator it = derivatives[i].begin(); - it != derivatives[i].end(); it++) - { - FLDSU_ fldsu(it->second); - fldsu.write(code_file, instruction_number); - FLDSV_ fldsv(eEndogenous, it->first); - fldsv.write(code_file, instruction_number); - FBINARY_ fbinary(oTimes); - fbinary.write(code_file, instruction_number); - if (it != derivatives[i].begin()) - { - FBINARY_ fbinary(oPlus); - fbinary.write(code_file, instruction_number); - } - } - FBINARY_ fbinary(oMinus); - fbinary.write(code_file, instruction_number); - } - FSTPSU_ fstpsu(i); - fstpsu.write(code_file, instruction_number); - } - // Get the current code_file position and jump = true - streampos pos2 = code_file.tellp(); - FJMP_ fjmp(0); - fjmp.write(code_file, instruction_number); - // Set code_file position to previous JMPIFEVAL_ and set the number of instructions to jump - streampos pos3 = code_file.tellp(); - code_file.seekp(pos1); - FJMPIFEVAL_ fjmp_if_eval1(instruction_number - prev_instruction_number); - fjmp_if_eval1.write(code_file, instruction_number); - code_file.seekp(pos3); - prev_instruction_number = instruction_number; - - temporary_terms_t tt2; - tt2.clear(); - temporary_terms_t tt3; - tt3.clear(); - - // The Jacobian if we have to solve the block determinsitic bloc - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - int deriv_id = it->first.second; - if (getTypeByDerivID(deriv_id) == eEndogenous) - { - expr_t d1 = it->second; - unsigned int eq = it->first.first; - int symb = getSymbIDByDerivID(deriv_id); - unsigned int var = symbol_table.getTypeSpecificID(symb); - FNUMEXPR_ fnumexpr(FirstEndoDerivative, eq, var); - fnumexpr.write(code_file, instruction_number); - if (!derivatives[eq].size()) - derivatives[eq].clear(); - derivatives[eq].push_back(make_pair(var, count_u)); - - d1->compile(code_file, instruction_number, false, temporary_terms, map_idx, false, false); - FSTPG2_ fstpg2(eq, var); - fstpg2.write(code_file, instruction_number); - } - } - - // Set codefile position to previous JMP_ and set the number of instructions to jump - pos1 = code_file.tellp(); - code_file.seekp(pos2); - FJMP_ fjmp1(instruction_number - prev_instruction_number); - fjmp1.write(code_file, instruction_number); - code_file.seekp(pos1); - - FENDBLOCK_ fendblock; - fendblock.write(code_file, instruction_number); - FEND_ fend; - fend.write(code_file, instruction_number); - code_file.close(); -} - -void -StaticModel::writeModelEquationsCode_Block(const string file_name, const string bin_basename, map_idx_t map_idx, vector map_idx2) const -{ - struct Uff_l - { - int u, var, lag; - Uff_l *pNext; - }; - - struct Uff - { - Uff_l *Ufl, *Ufl_First; - }; - - int i, v; - string tmp_s; - ostringstream tmp_output; - ofstream code_file; - unsigned int instruction_number = 0; - expr_t lhs = NULL, rhs = NULL; - BinaryOpNode *eq_node; - Uff Uf[symbol_table.endo_nbr()]; - map reference_count; - vector feedback_variables; - deriv_node_temp_terms_t tef_terms; - bool file_open = false; - - string main_name = file_name; - main_name += ".cod"; - code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate); - if (!code_file.is_open()) - { - cerr << "Error : Can't open file \"" << main_name << "\" for writing" << endl; - exit(EXIT_FAILURE); - } - //Temporary variables declaration - - FDIMST_ fdimst(temporary_terms.size()); - fdimst.write(code_file, instruction_number); - - for (unsigned int block = 0; block < getNbBlocks(); block++) - { - feedback_variables.clear(); - if (block > 0) - { - FENDBLOCK_ fendblock; - fendblock.write(code_file, instruction_number); - } - int count_u; - int u_count_int = 0; - BlockSimulationType simulation_type = getBlockSimulationType(block); - unsigned int block_size = getBlockSize(block); - unsigned int block_mfs = getBlockMfs(block); - unsigned int block_recursive = block_size - block_mfs; - - if (simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE || simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE - || simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_FORWARD_COMPLETE) - { - Write_Inf_To_Bin_File_Block(file_name, bin_basename, block, u_count_int, file_open); - file_open = true; - } - - FBEGINBLOCK_ fbeginblock(block_mfs, - simulation_type, - getBlockFirstEquation(block), - block_size, - variable_reordered, - equation_reordered, - blocks_linear[block], - symbol_table.endo_nbr(), - 0, - 0, - u_count_int, - /*symbol_table.endo_nbr()*/ block_size - ); - - fbeginblock.write(code_file, instruction_number); - - // Get the current code_file position and jump if eval = true - streampos pos1 = code_file.tellp(); - FJMPIFEVAL_ fjmp_if_eval(0); - fjmp_if_eval.write(code_file, instruction_number); - int prev_instruction_number = instruction_number; - - for (i = 0; i < (int) block_size; i++) - { - //The Temporary terms - temporary_terms_t tt2; - tt2.clear(); - if (v_temporary_terms[block].size()) - { - for (temporary_terms_t::const_iterator it = v_temporary_terms[block][i].begin(); - it != v_temporary_terms[block][i].end(); it++) - { - if (dynamic_cast(*it) != NULL) - (*it)->compileExternalFunctionOutput(code_file, instruction_number, false, tt2, map_idx, false, false, tef_terms); - - FNUMEXPR_ fnumexpr(TemporaryTerm, (int)(map_idx.find((*it)->idx)->second)); - fnumexpr.write(code_file, instruction_number); - (*it)->compile(code_file, instruction_number, false, tt2, map_idx, false, false, tef_terms); - FSTPST_ fstpst((int)(map_idx.find((*it)->idx)->second)); - fstpst.write(code_file, instruction_number); - // Insert current node into tt2 - tt2.insert(*it); - } - } - - // The equations - int variable_ID, equation_ID; - EquationType equ_type; - switch (simulation_type) - { - evaluation: - case EVALUATE_BACKWARD: - case EVALUATE_FORWARD: - equ_type = getBlockEquationType(block, i); - { - FNUMEXPR_ fnumexpr(ModelEquation, getBlockEquationID(block, i)); - fnumexpr.write(code_file, instruction_number); - } - if (equ_type == E_EVALUATE) - { - eq_node = (BinaryOpNode *) getBlockEquationExpr(block, i); - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - rhs->compile(code_file, instruction_number, false, temporary_terms, map_idx, false, false); - lhs->compile(code_file, instruction_number, true, temporary_terms, map_idx, false, false); - } - else if (equ_type == E_EVALUATE_S) - { - eq_node = (BinaryOpNode *) getBlockEquationRenormalizedExpr(block, i); - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - rhs->compile(code_file, instruction_number, false, temporary_terms, map_idx, false, false); - lhs->compile(code_file, instruction_number, true, temporary_terms, map_idx, false, false); - } - break; - case SOLVE_BACKWARD_COMPLETE: - case SOLVE_FORWARD_COMPLETE: - if (i < (int) block_recursive) - goto evaluation; - variable_ID = getBlockVariableID(block, i); - equation_ID = getBlockEquationID(block, i); - feedback_variables.push_back(variable_ID); - Uf[equation_ID].Ufl = NULL; - goto end; - default: - end: - FNUMEXPR_ fnumexpr(ModelEquation, getBlockEquationID(block, i)); - fnumexpr.write(code_file, instruction_number); - eq_node = (BinaryOpNode *) getBlockEquationExpr(block, i); - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - lhs->compile(code_file, instruction_number, false, temporary_terms, map_idx, false, false); - rhs->compile(code_file, instruction_number, false, temporary_terms, map_idx, false, false); - - FBINARY_ fbinary(oMinus); - fbinary.write(code_file, instruction_number); - - FSTPR_ fstpr(i - block_recursive); - fstpr.write(code_file, instruction_number); - } - } - FENDEQU_ fendequ; - fendequ.write(code_file, instruction_number); - - // The Jacobian if we have to solve the block - if (simulation_type != EVALUATE_BACKWARD - && simulation_type != EVALUATE_FORWARD) - { - switch (simulation_type) - { - case SOLVE_BACKWARD_SIMPLE: - case SOLVE_FORWARD_SIMPLE: - { - FNUMEXPR_ fnumexpr(FirstEndoDerivative, 0, 0); - fnumexpr.write(code_file, instruction_number); - } - compileDerivative(code_file, instruction_number, getBlockEquationID(block, 0), getBlockVariableID(block, 0), map_idx, temporary_terms); - { - FSTPG_ fstpg(0); - fstpg.write(code_file, instruction_number); - } - break; - - case SOLVE_BACKWARD_COMPLETE: - case SOLVE_FORWARD_COMPLETE: - count_u = feedback_variables.size(); - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - { - unsigned int eq = it->first.first; - unsigned int var = it->first.second; - unsigned int eqr = getBlockEquationID(block, eq); - unsigned int varr = getBlockVariableID(block, var); - if (eq >= block_recursive && var >= block_recursive) - { - if (!Uf[eqr].Ufl) - { - Uf[eqr].Ufl = (Uff_l *) malloc(sizeof(Uff_l)); - Uf[eqr].Ufl_First = Uf[eqr].Ufl; - } - else - { - Uf[eqr].Ufl->pNext = (Uff_l *) malloc(sizeof(Uff_l)); - Uf[eqr].Ufl = Uf[eqr].Ufl->pNext; - } - Uf[eqr].Ufl->pNext = NULL; - Uf[eqr].Ufl->u = count_u; - Uf[eqr].Ufl->var = varr; - FNUMEXPR_ fnumexpr(FirstEndoDerivative, eqr, varr); - fnumexpr.write(code_file, instruction_number); - compileChainRuleDerivative(code_file, instruction_number, eqr, varr, 0, map_idx, temporary_terms); - FSTPSU_ fstpsu(count_u); - fstpsu.write(code_file, instruction_number); - count_u++; - } - } - for (i = 0; i < (int) block_size; i++) - { - if (i >= (int) block_recursive) - { - FLDR_ fldr(i-block_recursive); - fldr.write(code_file, instruction_number); - - FLDZ_ fldz; - fldz.write(code_file, instruction_number); - - v = getBlockEquationID(block, i); - for (Uf[v].Ufl = Uf[v].Ufl_First; Uf[v].Ufl; Uf[v].Ufl = Uf[v].Ufl->pNext) - { - FLDSU_ fldsu(Uf[v].Ufl->u); - fldsu.write(code_file, instruction_number); - FLDSV_ fldsv(eEndogenous, Uf[v].Ufl->var); - fldsv.write(code_file, instruction_number); - - FBINARY_ fbinary(oTimes); - fbinary.write(code_file, instruction_number); - - FCUML_ fcuml; - fcuml.write(code_file, instruction_number); - } - Uf[v].Ufl = Uf[v].Ufl_First; - while (Uf[v].Ufl) - { - Uf[v].Ufl_First = Uf[v].Ufl->pNext; - free(Uf[v].Ufl); - Uf[v].Ufl = Uf[v].Ufl_First; - } - FBINARY_ fbinary(oMinus); - fbinary.write(code_file, instruction_number); - - FSTPSU_ fstpsu(i - block_recursive); - fstpsu.write(code_file, instruction_number); - - } - } - break; - default: - break; - } - } - - // Get the current code_file position and jump = true - streampos pos2 = code_file.tellp(); - FJMP_ fjmp(0); - fjmp.write(code_file, instruction_number); - // Set code_file position to previous JMPIFEVAL_ and set the number of instructions to jump - streampos pos3 = code_file.tellp(); - code_file.seekp(pos1); - FJMPIFEVAL_ fjmp_if_eval1(instruction_number - prev_instruction_number); - fjmp_if_eval1.write(code_file, instruction_number); - code_file.seekp(pos3); - prev_instruction_number = instruction_number; - - temporary_terms_t tt2; - tt2.clear(); - temporary_terms_t tt3; - tt3.clear(); - deriv_node_temp_terms_t tef_terms2; - - for (i = 0; i < (int) block_size; i++) - { - if (v_temporary_terms_local[block].size()) - { - for (temporary_terms_t::const_iterator it = v_temporary_terms_local[block][i].begin(); - it != v_temporary_terms_local[block][i].end(); it++) - { - if (dynamic_cast(*it) != NULL) - (*it)->compileExternalFunctionOutput(code_file, instruction_number, false, tt3, map_idx2[block], false, false, tef_terms2); - - FNUMEXPR_ fnumexpr(TemporaryTerm, (int)(map_idx2[block].find((*it)->idx)->second)); - fnumexpr.write(code_file, instruction_number); - - (*it)->compile(code_file, instruction_number, false, tt3, map_idx2[block], false, false, tef_terms); - - FSTPST_ fstpst((int)(map_idx2[block].find((*it)->idx)->second)); - fstpst.write(code_file, instruction_number); - // Insert current node into tt2 - tt3.insert(*it); - tt2.insert(*it); - } - } - - // The equations - int variable_ID, equation_ID; - EquationType equ_type; - switch (simulation_type) - { - evaluation_l: - case EVALUATE_BACKWARD: - case EVALUATE_FORWARD: - equ_type = getBlockEquationType(block, i); - { - FNUMEXPR_ fnumexpr(ModelEquation, getBlockEquationID(block, i)); - fnumexpr.write(code_file, instruction_number); - } - if (equ_type == E_EVALUATE) - { - eq_node = (BinaryOpNode *) getBlockEquationExpr(block, i); - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - rhs->compile(code_file, instruction_number, false, tt2, map_idx2[block], false, false); - lhs->compile(code_file, instruction_number, true, tt2, map_idx2[block], false, false); - } - else if (equ_type == E_EVALUATE_S) - { - eq_node = (BinaryOpNode *) getBlockEquationRenormalizedExpr(block, i); - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - rhs->compile(code_file, instruction_number, false, tt2, map_idx2[block], false, false); - lhs->compile(code_file, instruction_number, true, tt2, map_idx2[block], false, false); - } - break; - case SOLVE_BACKWARD_COMPLETE: - case SOLVE_FORWARD_COMPLETE: - if (i < (int) block_recursive) - goto evaluation_l; - variable_ID = getBlockVariableID(block, i); - equation_ID = getBlockEquationID(block, i); - feedback_variables.push_back(variable_ID); - Uf[equation_ID].Ufl = NULL; - goto end_l; - default: - end_l: - FNUMEXPR_ fnumexpr(ModelEquation, getBlockEquationID(block, i)); - fnumexpr.write(code_file, instruction_number); - eq_node = (BinaryOpNode *) getBlockEquationExpr(block, i); - lhs = eq_node->get_arg1(); - rhs = eq_node->get_arg2(); - lhs->compile(code_file, instruction_number, false, tt2, map_idx2[block], false, false); - rhs->compile(code_file, instruction_number, false, tt2, map_idx2[block], false, false); - - FBINARY_ fbinary(oMinus); - fbinary.write(code_file, instruction_number); - - FSTPR_ fstpr(i - block_recursive); - fstpr.write(code_file, instruction_number); - } - } - FENDEQU_ fendequ_l; - fendequ_l.write(code_file, instruction_number); - - // The Jacobian if we have to solve the block determinsitic bloc - switch (simulation_type) - { - case SOLVE_BACKWARD_SIMPLE: - case SOLVE_FORWARD_SIMPLE: - { - FNUMEXPR_ fnumexpr(FirstEndoDerivative, 0, 0); - fnumexpr.write(code_file, instruction_number); - } - compileDerivative(code_file, instruction_number, getBlockEquationID(block, 0), getBlockVariableID(block, 0), map_idx2[block], tt2 /*temporary_terms*/); - { - FSTPG2_ fstpg2(0, 0); - fstpg2.write(code_file, instruction_number); - } - break; - case EVALUATE_BACKWARD: - case EVALUATE_FORWARD: - case SOLVE_BACKWARD_COMPLETE: - case SOLVE_FORWARD_COMPLETE: - count_u = feedback_variables.size(); - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++) - { - unsigned int eq = it->first.first; - unsigned int var = it->first.second; - unsigned int eqr = getBlockEquationID(block, eq); - unsigned int varr = getBlockVariableID(block, var); - FNUMEXPR_ fnumexpr(FirstEndoDerivative, eqr, varr, 0); - fnumexpr.write(code_file, instruction_number); - - compileChainRuleDerivative(code_file, instruction_number, eqr, varr, 0, map_idx2[block], tt2 /*temporary_terms*/); - - FSTPG2_ fstpg2(eq, var); - fstpg2.write(code_file, instruction_number); - } - break; - default: - break; - } - // Set codefile position to previous JMP_ and set the number of instructions to jump - pos1 = code_file.tellp(); - code_file.seekp(pos2); - FJMP_ fjmp1(instruction_number - prev_instruction_number); - fjmp1.write(code_file, instruction_number); - code_file.seekp(pos1); - } - FENDBLOCK_ fendblock; - fendblock.write(code_file, instruction_number); - FEND_ fend; - fend.write(code_file, instruction_number); - code_file.close(); -} - -void -StaticModel::Write_Inf_To_Bin_File_Block(const string &static_basename, const string &bin_basename, const int &num, - int &u_count_int, bool &file_open) const -{ - int j; - std::ofstream SaveCode; - if (file_open) - SaveCode.open((bin_basename + "_static.bin").c_str(), ios::out | ios::in | ios::binary | ios::ate); - else - SaveCode.open((bin_basename + "_static.bin").c_str(), ios::out | ios::binary); - if (!SaveCode.is_open()) - { - cerr << "Error : Can't open file \"" << bin_basename << "_static.bin\" for writing" << endl; - exit(EXIT_FAILURE); - } - u_count_int = 0; - unsigned int block_size = getBlockSize(num); - unsigned int block_mfs = getBlockMfs(num); - unsigned int block_recursive = block_size - block_mfs; - for (block_derivatives_equation_variable_laglead_nodeid_t::const_iterator it = blocks_derivatives[num].begin(); it != (blocks_derivatives[num]).end(); it++) - { - unsigned int eq = it->first.first; - unsigned int var = it->first.second; - int lag = 0; - if (eq >= block_recursive && var >= block_recursive) - { - int v = eq - block_recursive; - SaveCode.write(reinterpret_cast(&v), sizeof(v)); - int varr = var - block_recursive; - SaveCode.write(reinterpret_cast(&varr), sizeof(varr)); - SaveCode.write(reinterpret_cast(&lag), sizeof(lag)); - int u = u_count_int + block_mfs; - SaveCode.write(reinterpret_cast(&u), sizeof(u)); - u_count_int++; - } - } - - for (j = block_recursive; j < (int) block_size; j++) - { - unsigned int varr = getBlockVariableID(num, j); - SaveCode.write(reinterpret_cast(&varr), sizeof(varr)); - } - for (j = block_recursive; j < (int) block_size; j++) - { - unsigned int eqr = getBlockEquationID(num, j); - SaveCode.write(reinterpret_cast(&eqr), sizeof(eqr)); - } - SaveCode.close(); -} - -map >, expr_t> -StaticModel::collect_first_order_derivatives_endogenous() -{ - map >, expr_t> endo_derivatives; - for (first_derivatives_t::iterator it2 = first_derivatives.begin(); - it2 != first_derivatives.end(); it2++) - { - if (getTypeByDerivID(it2->first.second) == eEndogenous) - { - int eq = it2->first.first; - int var = symbol_table.getTypeSpecificID(getSymbIDByDerivID(it2->first.second)); - int lag = 0; - endo_derivatives[make_pair(eq, make_pair(var, lag))] = it2->second; - } - } - return endo_derivatives; -} - -void -StaticModel::computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian, bool thirdDerivatives, int paramsDerivsOrder, bool block, bool bytecode, const bool nopreprocessoroutput) -{ - initializeVariablesAndEquations(); - - vector neweqs; - for (unsigned int eq = 0; eq < equations.size() - aux_equations.size(); eq++) - { - expr_t eq_tmp = equations[eq]->substituteStaticAuxiliaryVariable(); - neweqs.push_back(dynamic_cast(eq_tmp->toStatic(*this))); - } - - for (unsigned int eq = 0; eq < aux_equations.size(); eq++) - { - expr_t eq_tmp = aux_equations[eq]->substituteStaticAuxiliaryDefinition(); - neweqs.push_back(dynamic_cast(eq_tmp->toStatic(*this))); - } - - equations.clear(); - copy(neweqs.begin(), neweqs.end(), back_inserter(equations)); - // Compute derivatives w.r. to all endogenous, and possibly exogenous and exogenous deterministic - set vars; - - for (int i = 0; i < symbol_table.endo_nbr(); i++) - { - int id = symbol_table.getID(eEndogenous, i); - // if (!symbol_table.isAuxiliaryVariableButNotMultiplier(id)) - vars.insert(getDerivID(id, 0)); - } - - // Launch computations - if (!nopreprocessoroutput) - cout << "Computing static model derivatives:" << endl - << " - order 1" << endl; - first_derivatives.clear(); - - computeJacobian(vars); - - if (hessian) - { - if (!nopreprocessoroutput) - cout << " - order 2" << endl; - computeHessian(vars); - } - - if (thirdDerivatives) - { - if (!nopreprocessoroutput) - cout << " - order 3" << endl; - computeThirdDerivatives(vars); - } - - if (paramsDerivsOrder > 0) - { - if (!nopreprocessoroutput) - cout << " - derivatives of Jacobian/Hessian w.r. to parameters" << endl; - computeParamsDerivatives(paramsDerivsOrder); - - if (!no_tmp_terms) - computeParamsDerivativesTemporaryTerms(); - } - - if (block) - { - jacob_map_t contemporaneous_jacobian, static_jacobian; - vector n_static, n_forward, n_backward, n_mixed; - - // for each block contains pair - vector > blocks; - - evaluateAndReduceJacobian(eval_context, contemporaneous_jacobian, static_jacobian, dynamic_jacobian, cutoff, false); - - computeNonSingularNormalization(contemporaneous_jacobian, cutoff, static_jacobian, dynamic_jacobian); - - computePrologueAndEpilogue(static_jacobian, equation_reordered, variable_reordered); - - map >, expr_t> first_order_endo_derivatives = collect_first_order_derivatives_endogenous(); - - equation_type_and_normalized_equation = equationTypeDetermination(first_order_endo_derivatives, variable_reordered, equation_reordered, mfs); - - if (!nopreprocessoroutput) - cout << "Finding the optimal block decomposition of the model ...\n"; - - lag_lead_vector_t equation_lag_lead, variable_lag_lead; - - computeBlockDecompositionAndFeedbackVariablesForEachBlock(static_jacobian, dynamic_jacobian, equation_reordered, variable_reordered, blocks, equation_type_and_normalized_equation, false, false, mfs, inv_equation_reordered, inv_variable_reordered, equation_lag_lead, variable_lag_lead, n_static, n_forward, n_backward, n_mixed); - - block_type_firstequation_size_mfs = reduceBlocksAndTypeDetermination(dynamic_jacobian, blocks, equation_type_and_normalized_equation, variable_reordered, equation_reordered, n_static, n_forward, n_backward, n_mixed, block_col_type); - - printBlockDecomposition(blocks); - - computeChainRuleJacobian(blocks_derivatives); - - blocks_linear = BlockLinear(blocks_derivatives, variable_reordered); - - collect_block_first_order_derivatives(); - - global_temporary_terms = true; - if (!no_tmp_terms) - computeTemporaryTermsOrdered(); - } - else - { - if (!no_tmp_terms) - { - computeTemporaryTerms(true); - if (bytecode) - computeTemporaryTermsMapping(temporary_terms, map_idx); - } - } -} - -void -StaticModel::writeStaticMFile(const string &func_name) const -{ - // Writing comments and function definition command - string filename = func_name + "_static.m"; - - ofstream output; - output.open(filename.c_str(), ios::out | ios::binary); - if (!output.is_open()) - { - cerr << "ERROR: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - output << "function [residual, g1, g2, g3] = " << func_name + "_static(y, x, params)" << endl - << "%" << endl - << "% Status : Computes static model for Dynare" << endl - << "%" << endl - << "% Inputs : " << endl - << "% y [M_.endo_nbr by 1] double vector of endogenous variables in declaration order" << endl - << "% x [M_.exo_nbr by 1] double vector of exogenous variables in declaration order" << endl - << "% params [M_.param_nbr by 1] double vector of parameter values in declaration order" << endl - << "%" << endl - << "% Outputs:" << endl - << "% residual [M_.endo_nbr by 1] double vector of residuals of the static model equations " << endl - << "% in order of declaration of the equations." << endl - << "% Dynare may prepend or append auxiliary equations, see M_.aux_vars" << endl - << "% g1 [M_.endo_nbr by M_.endo_nbr] double Jacobian matrix of the static model equations;" << endl - << "% columns: variables in declaration order" << endl - << "% rows: equations in order of declaration" << endl - << "% g2 [M_.endo_nbr by (M_.endo_nbr)^2] double Hessian matrix of the static model equations;" << endl - << "% columns: variables in declaration order" << endl - << "% rows: equations in order of declaration" << endl - << "% g3 [M_.endo_nbr by (M_.endo_nbr)^3] double Third derivatives matrix of the static model equations;" << endl - << "% columns: variables in declaration order" << endl - << "% rows: equations in order of declaration" << endl - << "%" << endl - << "%" << endl - << "% Warning : this file is generated automatically by Dynare" << endl - << "% from model file (.mod)" << endl << endl; - - writeStaticModel(output, false, false); - output << "end" << endl; - output.close(); -} - -void -StaticModel::writeStaticModel(ostream &StaticOutput, bool use_dll, bool julia) const -{ - ostringstream model_local_vars_output; // Used for storing model local vars - ostringstream model_output; // Used for storing model - ostringstream jacobian_output; // Used for storing jacobian equations - ostringstream hessian_output; // Used for storing Hessian equations - ostringstream third_derivatives_output; // Used for storing third order derivatives equations - ostringstream for_sym; - ExprNodeOutputType output_type = (use_dll ? oCStaticModel : - julia ? oJuliaStaticModel : oMatlabStaticModel); - - deriv_node_temp_terms_t tef_terms; - temporary_terms_t temp_term_empty; - temporary_terms_t temp_term_union = temporary_terms_res; - temporary_terms_t temp_term_union_m_1; - - writeModelLocalVariables(model_local_vars_output, output_type, tef_terms); - - writeTemporaryTerms(temporary_terms_res, temp_term_union_m_1, model_output, output_type, tef_terms); - - writeModelEquations(model_output, output_type); - - int nrows = equations.size(); - int JacobianColsNbr = symbol_table.endo_nbr(); - int hessianColsNbr = JacobianColsNbr*JacobianColsNbr; - - // Write Jacobian w.r. to endogenous only - temp_term_union_m_1 = temp_term_union; - temp_term_union.insert(temporary_terms_g1.begin(), temporary_terms_g1.end()); - if (!first_derivatives.empty()) - if (julia) - writeTemporaryTerms(temp_term_union, temp_term_empty, jacobian_output, output_type, tef_terms); - else - writeTemporaryTerms(temp_term_union, temp_term_union_m_1, jacobian_output, output_type, tef_terms); - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - int eq = it->first.first; - int symb_id = getSymbIDByDerivID(it->first.second); - expr_t d1 = it->second; - - jacobianHelper(jacobian_output, eq, symbol_table.getTypeSpecificID(symb_id), output_type); - jacobian_output << "="; - d1->writeOutput(jacobian_output, output_type, temp_term_union, tef_terms); - jacobian_output << ";" << endl; - } - - int g2ncols = symbol_table.endo_nbr() * symbol_table.endo_nbr(); - // Write Hessian w.r. to endogenous only (only if 2nd order derivatives have been computed) - temp_term_union_m_1 = temp_term_union; - temp_term_union.insert(temporary_terms_g2.begin(), temporary_terms_g2.end()); - if (!second_derivatives.empty()) - if (julia) - writeTemporaryTerms(temp_term_union, temp_term_empty, hessian_output, output_type, tef_terms); - else - writeTemporaryTerms(temp_term_union, temp_term_union_m_1, hessian_output, output_type, tef_terms); - int k = 0; // Keep the line of a 2nd derivative in v2 - for (second_derivatives_t::const_iterator it = second_derivatives.begin(); - it != second_derivatives.end(); it++) - { - int eq = it->first.first; - int symb_id1 = getSymbIDByDerivID(it->first.second.first); - int symb_id2 = getSymbIDByDerivID(it->first.second.second); - expr_t d2 = it->second; - - int tsid1 = symbol_table.getTypeSpecificID(symb_id1); - int tsid2 = symbol_table.getTypeSpecificID(symb_id2); - - int col_nb = tsid1*symbol_table.endo_nbr()+tsid2; - int col_nb_sym = tsid2*symbol_table.endo_nbr()+tsid1; - - if (output_type == oJuliaDynamicModel) - { - for_sym << "g2[" << eq + 1 << "," << col_nb + 1 << "]"; - hessian_output << " @inbounds " << for_sym.str() << " = "; - d2->writeOutput(hessian_output, output_type, temp_term_union, tef_terms); - hessian_output << endl; - } - else - { - sparseHelper(2, hessian_output, k, 0, output_type); - hessian_output << "=" << eq + 1 << ";" << endl; - - sparseHelper(2, hessian_output, k, 1, output_type); - hessian_output << "=" << col_nb + 1 << ";" << endl; - - sparseHelper(2, hessian_output, k, 2, output_type); - hessian_output << "="; - d2->writeOutput(hessian_output, output_type, temp_term_union, tef_terms); - hessian_output << ";" << endl; - - k++; - } - - // Treating symetric elements - if (symb_id1 != symb_id2) - if (output_type == oJuliaDynamicModel) - hessian_output << " @inbounds g2[" << eq + 1 << "," << col_nb_sym + 1 << "] = " - << for_sym.str() << endl; - else - { - sparseHelper(2, hessian_output, k, 0, output_type); - hessian_output << "=" << eq + 1 << ";" << endl; - - sparseHelper(2, hessian_output, k, 1, output_type); - hessian_output << "=" << col_nb_sym + 1 << ";" << endl; - - sparseHelper(2, hessian_output, k, 2, output_type); - hessian_output << "="; - sparseHelper(2, hessian_output, k-1, 2, output_type); - hessian_output << ";" << endl; - - k++; - } - } - - // Writing third derivatives - temp_term_union_m_1 = temp_term_union; - temp_term_union.insert(temporary_terms_g3.begin(), temporary_terms_g3.end()); - if (!third_derivatives.empty()) - if (julia) - writeTemporaryTerms(temp_term_union, temp_term_empty, third_derivatives_output, output_type, tef_terms); - else - writeTemporaryTerms(temp_term_union, temp_term_union_m_1, third_derivatives_output, output_type, tef_terms); - k = 0; // Keep the line of a 3rd derivative in v3 - for (third_derivatives_t::const_iterator it = third_derivatives.begin(); - it != third_derivatives.end(); it++) - { - int eq = it->first.first; - int var1 = it->first.second.first; - int var2 = it->first.second.second.first; - int var3 = it->first.second.second.second; - expr_t d3 = it->second; - - int id1 = getSymbIDByDerivID(var1); - int id2 = getSymbIDByDerivID(var2); - int id3 = getSymbIDByDerivID(var3); - - // Reference column number for the g3 matrix - int ref_col = id1 * hessianColsNbr + id2 * JacobianColsNbr + id3; - - if (output_type == oJuliaDynamicModel) - { - for_sym << "g3[" << eq + 1 << "," << ref_col + 1 << "]"; - third_derivatives_output << " @inbounds " << for_sym.str() << " = "; - d3->writeOutput(third_derivatives_output, output_type, temp_term_union, tef_terms); - third_derivatives_output << endl; - } - else - { - sparseHelper(3, third_derivatives_output, k, 0, output_type); - third_derivatives_output << "=" << eq + 1 << ";" << endl; - - sparseHelper(3, third_derivatives_output, k, 1, output_type); - third_derivatives_output << "=" << ref_col + 1 << ";" << endl; - - sparseHelper(3, third_derivatives_output, k, 2, output_type); - third_derivatives_output << "="; - d3->writeOutput(third_derivatives_output, output_type, temp_term_union, tef_terms); - third_derivatives_output << ";" << endl; - } - - // Compute the column numbers for the 5 other permutations of (id1,id2,id3) - // and store them in a set (to avoid duplicates if two indexes are equal) - set cols; - cols.insert(id1 * hessianColsNbr + id3 * JacobianColsNbr + id2); - cols.insert(id2 * hessianColsNbr + id1 * JacobianColsNbr + id3); - cols.insert(id2 * hessianColsNbr + id3 * JacobianColsNbr + id1); - cols.insert(id3 * hessianColsNbr + id1 * JacobianColsNbr + id2); - cols.insert(id3 * hessianColsNbr + id2 * JacobianColsNbr + id1); - - int k2 = 1; // Keeps the offset of the permutation relative to k - for (set::iterator it2 = cols.begin(); it2 != cols.end(); it2++) - if (*it2 != ref_col) - if (output_type == oJuliaDynamicModel) - third_derivatives_output << " @inbounds g3[" << eq + 1 << "," << *it2 + 1 << "] = " - << for_sym.str() << endl; - else - { - sparseHelper(3, third_derivatives_output, k+k2, 0, output_type); - third_derivatives_output << "=" << eq + 1 << ";" << endl; - - sparseHelper(3, third_derivatives_output, k+k2, 1, output_type); - third_derivatives_output << "=" << *it2 + 1 << ";" << endl; - - sparseHelper(3, third_derivatives_output, k+k2, 2, output_type); - third_derivatives_output << "="; - sparseHelper(3, third_derivatives_output, k, 2, output_type); - third_derivatives_output << ";" << endl; - - k2++; - } - k += k2; - } - - if (output_type == oMatlabStaticModel) - { - // Check that we don't have more than 32 nested parenthesis because Matlab does not suppor this. See Issue #1201 - map tmp_paren_vars; - bool message_printed = false; - fixNestedParenthesis(model_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(model_local_vars_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(jacobian_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(hessian_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(third_derivatives_output, tmp_paren_vars, message_printed); - - StaticOutput << "residual = zeros( " << equations.size() << ", 1);" << endl << endl - << "%" << endl - << "% Model equations" << endl - << "%" << endl << endl - << model_local_vars_output.str() - << model_output.str() - << "if ~isreal(residual)" << endl - << " residual = real(residual)+imag(residual).^2;" << endl - << "end" << endl - << "if nargout >= 2," << endl - << " g1 = zeros(" << equations.size() << ", " << symbol_table.endo_nbr() << ");" << endl << endl - << " %" << endl - << " % Jacobian matrix" << endl - << " %" << endl << endl - << jacobian_output.str() - << " if ~isreal(g1)" << endl - << " g1 = real(g1)+2*imag(g1);" << endl - << " end" << endl - << "if nargout >= 3," << endl - << " %" << endl - << " % Hessian matrix" << endl - << " %" << endl - << endl; - - if (second_derivatives.size()) - StaticOutput << " v2 = zeros(" << NNZDerivatives[1] << ",3);" << endl - << hessian_output.str() - << " g2 = sparse(v2(:,1),v2(:,2),v2(:,3)," << equations.size() << "," << g2ncols << ");" << endl; - else - StaticOutput << " g2 = sparse([],[],[]," << equations.size() << "," << g2ncols << ");" << endl; - - // Initialize g3 matrix - StaticOutput << "if nargout >= 4," << endl - << " %" << endl - << " % Third order derivatives" << endl - << " %" << endl - << endl; - int ncols = hessianColsNbr * JacobianColsNbr; - if (third_derivatives.size()) - StaticOutput << " v3 = zeros(" << NNZDerivatives[2] << ",3);" << endl - << third_derivatives_output.str() - << " g3 = sparse(v3(:,1),v3(:,2),v3(:,3)," << nrows << "," << ncols << ");" << endl; - else // Either 3rd derivatives is all zero, or we didn't compute it - StaticOutput << " g3 = sparse([],[],[]," << nrows << "," << ncols << ");" << endl; - StaticOutput << "end" << endl - << "end" << endl - << "end" << endl; - } - else if (output_type == oCStaticModel) - { - StaticOutput << "void Static(double *y, double *x, int nb_row_x, double *params, double *residual, double *g1, double *v2)" << endl - << "{" << endl - << " double lhs, rhs;" << endl - << endl - << " /* Residual equations */" << endl - << model_local_vars_output.str() - << model_output.str() - << " /* Jacobian */" << endl - << " if (g1 == NULL)" << endl - << " return;" << endl - << endl - << jacobian_output.str() - << endl; - - if (second_derivatives.size()) - StaticOutput << " /* Hessian for endogenous and exogenous variables */" << endl - << " if (v2 == NULL)" << endl - << " return;" << endl - << endl - << hessian_output.str() - << endl; - if (third_derivatives.size()) - StaticOutput << " /* Third derivatives for endogenous and exogenous variables */" << endl - << " if (v3 == NULL)" << endl - << " return;" << endl - << endl - << third_derivatives_output.str() - << endl; - } - else - { - ostringstream comments; - comments << "## Function Arguments" << endl - << endl - << "## Input" << endl - << " 1 y: Array{Float64, length(model.endo), 1} Vector of endogenous variables in declaration order" << endl - << " 2 x: Array{Float64, length(model.exo), 1} Vector of exogenous variables in declaration order" << endl - << " 3 params: Array{Float64, length(model.param), 1} Vector of parameter values in declaration order" << endl - << endl - << "## Output" << endl - << " 4 residual: Array(Float64, model.eq_nbr, 1) Vector of residuals of the static model equations" << endl - << " in order of declaration of the equations." << endl - << " Dynare may prepend auxiliary equations, see model.aux_vars" << endl; - - StaticOutput << "function static!(y::Vector{Float64}, x::Vector{Float64}, " - << "params::Vector{Float64}," << endl - << " residual::Vector{Float64})" << endl - << "#=" << endl << comments.str() << "=#" << endl - << " @assert length(y) == " << symbol_table.endo_nbr() << endl - << " @assert length(x) == " << symbol_table.exo_nbr() << endl - << " @assert length(params) == " << symbol_table.param_nbr() << endl - << " @assert length(residual) == " << equations.size() << endl - << " #" << endl - << " # Model equations" << endl - << " #" << endl - << model_local_vars_output.str() - << model_output.str() - << "if ~isreal(residual)" << endl - << " residual = real(residual)+imag(residual).^2;" << endl - << "end" << endl - << "end" << endl << endl - << "function static!(y::Vector{Float64}, x::Vector{Float64}, " - << "params::Vector{Float64}," << endl - << " residual::Vector{Float64}, g1::Matrix{Float64})" << endl; - - comments << " 5 g1: Array(Float64, model.eq_nbr, length(model.endo)) Jacobian matrix of the static model equations;" << endl - << " columns: variables in declaration order" << endl - << " rows: equations in order of declaration" << endl; - - StaticOutput << "#=" << endl << comments.str() << "=#" << endl - << " @assert size(g1) == (" << equations.size() << ", " << symbol_table.endo_nbr() - << ")" << endl - << " fill!(g1, 0.0)" << endl - << " static!(y, x, params, residual)" << endl - << model_local_vars_output.str() - << " #" << endl - << " # Jacobian matrix" << endl - << " #" << endl - << jacobian_output.str() - << " if ~isreal(g1)" << endl - << " g1 = real(g1)+2*imag(g1);" << endl - << " end" << endl - << "end" << endl << endl - << "function static!(y::Vector{Float64}, x::Vector{Float64}, " - << "params::Vector{Float64}," << endl - << " residual::Vector{Float64}, g1::Matrix{Float64}, " - << "g2::Matrix{Float64})" << endl; - - comments << " 6 g2: spzeros(model.eq_nbr, length(model.endo)^2) Hessian matrix of the static model equations;" << endl - << " columns: variables in declaration order" << endl - << " rows: equations in order of declaration" << endl; - - StaticOutput << "#=" << endl << comments.str() << "=#" << endl - << " @assert size(g2) == (" << equations.size() << ", " << g2ncols << ")" << endl - << " fill!(g2, 0.0)" << endl - << " static!(y, x, params, residual, g1)" << endl; - if (second_derivatives.size()) - StaticOutput << model_local_vars_output.str() - << " #" << endl - << " # Hessian matrix" << endl - << " #" << endl - << hessian_output.str(); - - // Initialize g3 matrix - int ncols = hessianColsNbr * JacobianColsNbr; - StaticOutput << "end" << endl << endl - << "function static!(y::Vector{Float64}, x::Vector{Float64}, " - << "params::Vector{Float64}," << endl - << " residual::Vector{Float64}, g1::Matrix{Float64}, " - << "g2::Matrix{Float64}," << endl - << " g3::Matrix{Float64})" << endl; - - comments << " 7 g3: spzeros(model.eq_nbr, length(model.endo)^3) Third derivatives matrix of the static model equations;" << endl - << " columns: variables in declaration order" << endl - << " rows: equations in order of declaration" << endl; - - StaticOutput << "#=" << endl << comments.str() << "=#" << endl - << " @assert size(g3) == (" << nrows << ", " << ncols << ")" << endl - << " fill!(g3, 0.0)" << endl - << " static!(y, x, params, residual, g1, g2)" << endl; - if (third_derivatives.size()) - StaticOutput << model_local_vars_output.str() - << " #" << endl - << " # Third order derivatives" << endl - << " #" << endl - << third_derivatives_output.str(); - StaticOutput << "end" << endl; - } -} - -void -StaticModel::writeStaticCFile(const string &func_name) const -{ - // Writing comments and function definition command - string filename = func_name + "_static.c"; - string filename_mex = func_name + "_static_mex.c"; - - ofstream output; - output.open(filename.c_str(), ios::out | ios::binary); - if (!output.is_open()) - { - cerr << "ERROR: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - output << "/*" << endl - << " * " << filename << " : Computes static model for Dynare" << endl - << " *" << endl - << " * Warning : this file is generated automatically by Dynare" << endl - << " * from model file (.mod)" << endl << endl - << " */" << endl -#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) - << "#ifdef _MSC_VER" << endl - << "#define _USE_MATH_DEFINES" << endl - << "#endif" << endl -#endif - << "#include " << endl; - - if (external_functions_table.get_total_number_of_unique_model_block_external_functions()) - // External Matlab function, implies Static function will call mex - output << "#include \"mex.h\"" << endl; - else - output << "#include " << endl; - - output << "#define max(a, b) (((a) > (b)) ? (a) : (b))" << endl - << "#define min(a, b) (((a) > (b)) ? (b) : (a))" << endl; - - // Write function definition if oPowerDeriv is used - writePowerDerivCHeader(output); - writeNormcdfCHeader(output); - - // Writing the function body - writeStaticModel(output, true, false); - output << "}" << endl << endl; - - writePowerDeriv(output); - writeNormcdf(output); - output.close(); - - output.open(filename_mex.c_str(), ios::out | ios::binary); - if (!output.is_open()) - { - cerr << "ERROR: Can't open file " << filename_mex << " for writing" << endl; - exit(EXIT_FAILURE); - } - - // Writing the gateway routine - output << "/*" << endl - << " * " << filename_mex << " : The gateway routine used to call the Static function " - << "located in " << filename << endl - << " *" << endl - << " * Warning : this file is generated automatically by Dynare" << endl - << " * from model file (.mod)" << endl << endl - << " */" << endl << endl - << "#include \"mex.h\"" << endl << endl - << "void Static(double *y, double *x, int nb_row_x, double *params, double *residual, double *g1, double *v2);" << endl - << "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl - << "{" << endl - << " double *y, *x, *params;" << endl - << " double *residual, *g1, *v2;" << endl - << " int nb_row_x;" << endl - << endl - << " /* Create a pointer to the input matrix y. */" << endl - << " y = mxGetPr(prhs[0]);" << endl - << endl - << " /* Create a pointer to the input matrix x. */" << endl - << " x = mxGetPr(prhs[1]);" << endl - << endl - << " /* Create a pointer to the input matrix params. */" << endl - << " params = mxGetPr(prhs[2]);" << endl - << endl - << " /* Gets number of rows of matrix x. */" << endl - << " nb_row_x = mxGetM(prhs[1]);" << endl - << endl - << " residual = NULL;" << endl - << " if (nlhs >= 1)" << endl - << " {" << endl - << " /* Set the output pointer to the output matrix residual. */" << endl - << " plhs[0] = mxCreateDoubleMatrix(" << equations.size() << ",1, mxREAL);" << endl - << " /* Create a C pointer to a copy of the output matrix residual. */" << endl - << " residual = mxGetPr(plhs[0]);" << endl - << " }" << endl - << endl - << " g1 = NULL;" << endl - << " if (nlhs >= 2)" << endl - << " {" << endl - << " /* Set the output pointer to the output matrix g1. */" << endl - << " plhs[1] = mxCreateDoubleMatrix(" << equations.size() << ", " << symbol_table.endo_nbr() << ", mxREAL);" << endl - << " /* Create a C pointer to a copy of the output matrix g1. */" << endl - << " g1 = mxGetPr(plhs[1]);" << endl - << " }" << endl - << endl - << " v2 = NULL;" << endl - << " if (nlhs >= 3)" << endl - << " {" << endl - << " /* Set the output pointer to the output matrix v2. */" << endl - << " plhs[2] = mxCreateDoubleMatrix(" << NNZDerivatives[1] << ", " << 3 - << ", mxREAL);" << endl - << " v2 = mxGetPr(plhs[2]);" << endl - << " }" << endl - << endl - << " /* Call the C subroutines. */" << endl - << " Static(y, x, nb_row_x, params, residual, g1, v2);" << endl - << "}" << endl << endl; - output.close(); -} - -void -StaticModel::writeStaticJuliaFile(const string &basename) const -{ - string filename = basename + "Static.jl"; - ofstream output; - output.open(filename.c_str(), ios::out | ios::binary); - if (!output.is_open()) - { - cerr << "ERROR: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - output << "module " << basename << "Static" << endl - << "#" << endl - << "# NB: this file was automatically generated by Dynare" << endl - << "# from " << basename << ".mod" << endl - << "#" << endl - << "using Utils" << endl << endl - << "export static!" << endl << endl; - writeStaticModel(output, false, true); - output << "end" << endl; -} - -void -StaticModel::writeStaticFile(const string &basename, bool block, bool bytecode, bool use_dll, bool julia) const -{ - int r; - - //assert(block); - -#ifdef _WIN32 - r = mkdir(basename.c_str()); -#else - r = mkdir(basename.c_str(), 0777); -#endif - if (r < 0 && errno != EEXIST) - { - perror("ERROR"); - exit(EXIT_FAILURE); - } - if (block && bytecode) - writeModelEquationsCode_Block(basename + "_static", basename, map_idx, map_idx2); - else if (!block && bytecode) - writeModelEquationsCode(basename + "_static", basename, map_idx); - else if (block && !bytecode) - { - chdir(basename.c_str()); - writeModelEquationsOrdered_M(basename + "_static"); - chdir(".."); - writeStaticBlockMFSFile(basename); - } - else if (use_dll) - writeStaticCFile(basename); - else if (julia) - writeStaticJuliaFile(basename); - else - writeStaticMFile(basename); - writeSetAuxiliaryVariables(basename, julia); -} - -bool -StaticModel::exoPresentInEqs() const -{ - for (int i = 0; i < (int) equations.size(); i++) - if (equations[i]->containsExogenous()) - return true; - return false; -} - -void -StaticModel::writeStaticBlockMFSFile(const string &basename) const -{ - string filename = basename + "_static.m"; - - ofstream output; - output.open(filename.c_str(), ios::out | ios::binary); - if (!output.is_open()) - { - cerr << "ERROR: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - string func_name = basename + "_static"; - - output << "function [residual, g1, y, var_index] = " << func_name << "(nblock, y, x, params)" << endl - << " residual = [];" << endl - << " g1 = [];" << endl - << " var_index = [];\n" << endl - << " switch nblock" << endl; - - unsigned int nb_blocks = getNbBlocks(); - - for (int b = 0; b < (int) nb_blocks; b++) - { - - set local_var; - - output << " case " << b+1 << endl; - - BlockSimulationType simulation_type = getBlockSimulationType(b); - - if (simulation_type == EVALUATE_BACKWARD || simulation_type == EVALUATE_FORWARD) - { - output << " y_tmp = " << func_name << "_" << b+1 << "(y, x, params);\n"; - ostringstream tmp; - for (int i = 0; i < (int) getBlockSize(b); i++) - tmp << " " << getBlockVariableID(b, i)+1; - output << " var_index = [" << tmp.str() << "];\n"; - output << " residual = y(var_index) - y_tmp(var_index);\n"; - output << " y = y_tmp;\n"; - } - else - output << " [residual, y, g1] = " << func_name << "_" << b+1 << "(y, x, params);\n"; - - } - output << " end" << endl - << "end" << endl; - output.close(); -} - -void -StaticModel::writeOutput(ostream &output, bool block) const -{ - if (!block) - return; - - unsigned int nb_blocks = getNbBlocks(); - for (int b = 0; b < (int) nb_blocks; b++) - { - BlockSimulationType simulation_type = getBlockSimulationType(b); - unsigned int block_size = getBlockSize(b); - ostringstream tmp_s, tmp_s_eq; - tmp_s.str(""); - tmp_s_eq.str(""); - for (unsigned int i = 0; i < block_size; i++) - { - tmp_s << " " << getBlockVariableID(b, i)+1; - tmp_s_eq << " " << getBlockEquationID(b, i)+1; - } - output << "block_structure_stat.block(" << b+1 << ").Simulation_Type = " << simulation_type << ";\n"; - output << "block_structure_stat.block(" << b+1 << ").endo_nbr = " << block_size << ";\n"; - output << "block_structure_stat.block(" << b+1 << ").mfs = " << getBlockMfs(block) << ";\n"; - output << "block_structure_stat.block(" << b+1 << ").equation = [" << tmp_s_eq.str() << "];\n"; - output << "block_structure_stat.block(" << b+1 << ").variable = [" << tmp_s.str() << "];\n"; - } - output << "M_.block_structure_stat.block = block_structure_stat.block;\n"; - string cst_s; - int nb_endo = symbol_table.endo_nbr(); - output << "M_.block_structure_stat.variable_reordered = ["; - for (int i = 0; i < nb_endo; i++) - output << " " << variable_reordered[i]+1; - output << "];\n"; - output << "M_.block_structure_stat.equation_reordered = ["; - for (int i = 0; i < nb_endo; i++) - output << " " << equation_reordered[i]+1; - output << "];\n"; - - map, int> row_incidence; - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - int deriv_id = it->first.second; - if (getTypeByDerivID(deriv_id) == eEndogenous) - { - int eq = it->first.first; - int symb = getSymbIDByDerivID(deriv_id); - int var = symbol_table.getTypeSpecificID(symb); - //int lag = getLagByDerivID(deriv_id); - row_incidence[make_pair(eq, var)] = 1; - } - } - output << "M_.block_structure_stat.incidence.sparse_IM = ["; - for (map, int>::const_iterator it = row_incidence.begin(); it != row_incidence.end(); it++) - { - output << it->first.first+1 << " " << it->first.second+1 << ";\n"; - } - output << "];\n"; -} - -SymbolType -StaticModel::getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException) -{ - if (deriv_id < symbol_table.endo_nbr()) - return eEndogenous; - else if (deriv_id < symbol_table.endo_nbr() + symbol_table.param_nbr()) - return eParameter; - else - throw UnknownDerivIDException(); -} - -int -StaticModel::getLagByDerivID(int deriv_id) const throw (UnknownDerivIDException) -{ - return 0; -} - -int -StaticModel::getSymbIDByDerivID(int deriv_id) const throw (UnknownDerivIDException) -{ - if (deriv_id < symbol_table.endo_nbr()) - return symbol_table.getID(eEndogenous, deriv_id); - else if (deriv_id < symbol_table.endo_nbr() + symbol_table.param_nbr()) - return symbol_table.getID(eParameter, deriv_id - symbol_table.endo_nbr()); - else - throw UnknownDerivIDException(); -} - -int -StaticModel::getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException) -{ - if (symbol_table.getType(symb_id) == eEndogenous) - return symbol_table.getTypeSpecificID(symb_id); - else if (symbol_table.getType(symb_id) == eParameter) - return symbol_table.getTypeSpecificID(symb_id) + symbol_table.endo_nbr(); - else - return -1; -} - -void -StaticModel::addAllParamDerivId(set &deriv_id_set) -{ - for (int i = 0; i < symbol_table.param_nbr(); i++) - deriv_id_set.insert(i + symbol_table.endo_nbr()); -} - -map >, pair >, int> -StaticModel::get_Derivatives(int block) -{ - map >, pair >, int> Derivatives; - Derivatives.clear(); - int block_size = getBlockSize(block); - int block_nb_recursive = block_size - getBlockMfs(block); - int lag = 0; - for (int eq = 0; eq < block_size; eq++) - { - int eqr = getBlockEquationID(block, eq); - for (int var = 0; var < block_size; var++) - { - int varr = getBlockVariableID(block, var); - if (dynamic_jacobian.find(make_pair(lag, make_pair(eqr, varr))) != dynamic_jacobian.end()) - { - bool OK = true; - map >, pair >, int>::const_iterator its = Derivatives.find(make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))); - if (its != Derivatives.end()) - { - if (its->second == 2) - OK = false; - } - - if (OK) - { - if (getBlockEquationType(block, eq) == E_EVALUATE_S && eq < block_nb_recursive) - //It's a normalized equation, we have to recompute the derivative using chain rule derivative function - Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 1; - else - //It's a feedback equation we can use the derivatives - Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 0; - } - if (var < block_nb_recursive) - { - int eqs = getBlockEquationID(block, var); - for (int vars = block_nb_recursive; vars < block_size; vars++) - { - int varrs = getBlockVariableID(block, vars); - //A new derivative needs to be computed using the chain rule derivative function (a feedback variable appears in a recursive equation) - if (Derivatives.find(make_pair(make_pair(lag, make_pair(var, vars)), make_pair(eqs, varrs))) != Derivatives.end()) - Derivatives[make_pair(make_pair(lag, make_pair(eq, vars)), make_pair(eqr, varrs))] = 2; - } - } - } - } - } - - return (Derivatives); -} - -void -StaticModel::computeChainRuleJacobian(blocks_derivatives_t &blocks_derivatives) -{ - map recursive_variables; - unsigned int nb_blocks = getNbBlocks(); - blocks_derivatives = blocks_derivatives_t(nb_blocks); - for (unsigned int block = 0; block < nb_blocks; block++) - { - block_derivatives_equation_variable_laglead_nodeid_t tmp_derivatives; - recursive_variables.clear(); - BlockSimulationType simulation_type = getBlockSimulationType(block); - int block_size = getBlockSize(block); - int block_nb_mfs = getBlockMfs(block); - int block_nb_recursives = block_size - block_nb_mfs; - if (simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE) - { - blocks_derivatives.push_back(block_derivatives_equation_variable_laglead_nodeid_t(0)); - for (int i = 0; i < block_nb_recursives; i++) - { - if (getBlockEquationType(block, i) == E_EVALUATE_S) - recursive_variables[getDerivID(symbol_table.getID(eEndogenous, getBlockVariableID(block, i)), 0)] = getBlockEquationRenormalizedExpr(block, i); - else - recursive_variables[getDerivID(symbol_table.getID(eEndogenous, getBlockVariableID(block, i)), 0)] = getBlockEquationExpr(block, i); - } - map >, pair >, int> Derivatives = get_Derivatives(block); - map >, pair >, int>::const_iterator it = Derivatives.begin(); - for (int i = 0; i < (int) Derivatives.size(); i++) - { - int Deriv_type = it->second; - pair >, pair > it_l(it->first); - it++; - int lag = it_l.first.first; - int eq = it_l.first.second.first; - int var = it_l.first.second.second; - int eqr = it_l.second.first; - int varr = it_l.second.second; - if (Deriv_type == 0) - first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = first_derivatives[make_pair(eqr, getDerivID(symbol_table.getID(eEndogenous, varr), lag))]; - else if (Deriv_type == 1) - first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = (equation_type_and_normalized_equation[eqr].second)->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables); - else if (Deriv_type == 2) - { - if (getBlockEquationType(block, eq) == E_EVALUATE_S && eq < block_nb_recursives) - first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = (equation_type_and_normalized_equation[eqr].second)->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables); - else - first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables); - } - tmp_derivatives.push_back(make_pair(make_pair(eq, var), make_pair(lag, first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))]))); - } - } - else - { - blocks_derivatives.push_back(block_derivatives_equation_variable_laglead_nodeid_t(0)); - for (int i = 0; i < block_nb_recursives; i++) - { - if (getBlockEquationType(block, i) == E_EVALUATE_S) - recursive_variables[getDerivID(symbol_table.getID(eEndogenous, getBlockVariableID(block, i)), 0)] = getBlockEquationRenormalizedExpr(block, i); - else - recursive_variables[getDerivID(symbol_table.getID(eEndogenous, getBlockVariableID(block, i)), 0)] = getBlockEquationExpr(block, i); - } - for (int eq = block_nb_recursives; eq < block_size; eq++) - { - int eqr = getBlockEquationID(block, eq); - for (int var = block_nb_recursives; var < block_size; var++) - { - int varr = getBlockVariableID(block, var); - expr_t d1 = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), 0), recursive_variables); - if (d1 == Zero) - continue; - first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, 0))] = d1; - tmp_derivatives.push_back( - make_pair(make_pair(eq, var), make_pair(0, first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, 0))]))); - } - } - } - blocks_derivatives[block] = tmp_derivatives; - } -} - -void -StaticModel::collect_block_first_order_derivatives() -{ - //! vector for an equation or a variable indicates the block number - vector equation_2_block, variable_2_block; - unsigned int nb_blocks = getNbBlocks(); - equation_2_block = vector(equation_reordered.size()); - variable_2_block = vector(variable_reordered.size()); - for (unsigned int block = 0; block < nb_blocks; block++) - { - unsigned int block_size = getBlockSize(block); - for (unsigned int i = 0; i < block_size; i++) - { - equation_2_block[getBlockEquationID(block, i)] = block; - variable_2_block[getBlockVariableID(block, i)] = block; - } - } - derivative_endo = vector(nb_blocks); - endo_max_leadlag_block = vector >(nb_blocks, make_pair(0, 0)); - max_leadlag_block = vector >(nb_blocks, make_pair(0, 0)); - for (first_derivatives_t::iterator it2 = first_derivatives.begin(); - it2 != first_derivatives.end(); it2++) - { - int eq = it2->first.first; - int var = symbol_table.getTypeSpecificID(getSymbIDByDerivID(it2->first.second)); - int lag = 0; - int block_eq = equation_2_block[eq]; - int block_var = variable_2_block[var]; - max_leadlag_block[block_eq] = make_pair(0, 0); - max_leadlag_block[block_eq] = make_pair(0, 0); - endo_max_leadlag_block[block_eq] = make_pair(0, 0); - endo_max_leadlag_block[block_eq] = make_pair(0, 0); - derivative_t tmp_derivative; - lag_var_t lag_var; - if (getTypeByDerivID(it2->first.second) == eEndogenous && block_eq == block_var) - { - tmp_derivative = derivative_endo[block_eq]; - tmp_derivative[make_pair(lag, make_pair(eq, var))] = first_derivatives[make_pair(eq, getDerivID(symbol_table.getID(eEndogenous, var), lag))]; - derivative_endo[block_eq] = tmp_derivative; - } - } -} - -void -StaticModel::writeChainRuleDerivative(ostream &output, int eqr, int varr, int lag, - ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms) const -{ - map >, expr_t>::const_iterator it = first_chain_rule_derivatives.find(make_pair(eqr, make_pair(varr, lag))); - if (it != first_chain_rule_derivatives.end()) - (it->second)->writeOutput(output, output_type, temporary_terms); - else - output << 0; -} - -void -StaticModel::writeLatexFile(const string &basename, bool write_equation_tags) const -{ - writeLatexModelFile(basename + "_static", oLatexStaticModel, write_equation_tags); -} - -void -StaticModel::writeAuxVarInitval(ostream &output, ExprNodeOutputType output_type) const -{ - for (int i = 0; i < (int) aux_equations.size(); i++) - { - dynamic_cast(aux_equations[i])->writeOutput(output, output_type); - output << ";" << endl; - } -} - -void -StaticModel::writeSetAuxiliaryVariables(const string &basename, const bool julia) const -{ - ostringstream output_func_body; - writeAuxVarRecursiveDefinitions(output_func_body, oMatlabStaticModel); - - if (output_func_body.str().empty()) - return; - - string func_name = basename + "_set_auxiliary_variables"; - string filename = julia ? func_name + ".jl" : func_name + ".m"; - string comment = julia ? "#" : "%"; - - ofstream output; - output.open(filename.c_str(), ios::out | ios::binary); - if (!output.is_open()) - { - cerr << "ERROR: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - output << "function y = " << func_name + "(y, x, params)" << endl - << comment << endl - << comment << " Status : Computes static model for Dynare" << endl - << comment << endl - << comment << " Warning : this file is generated automatically by Dynare" << endl - << comment << " from model file (.mod)" << endl << endl - << output_func_body.str(); -} - -void -StaticModel::writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType output_type) const -{ - deriv_node_temp_terms_t tef_terms; - temporary_terms_t temporary_terms; - for (int i = 0; i < (int) aux_equations.size(); i++) - if (dynamic_cast(aux_equations[i])->containsExternalFunction()) - dynamic_cast(aux_equations[i])->writeExternalFunctionOutput(output, oMatlabStaticModel, - temporary_terms, tef_terms); - for (int i = 0; i < (int) aux_equations.size(); i++) - { - dynamic_cast(aux_equations[i]->substituteStaticAuxiliaryDefinition())->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ";" << endl; - } -} - -void -StaticModel::writeLatexAuxVarRecursiveDefinitions(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - temporary_terms_t temporary_terms; - for (int i = 0; i < (int) aux_equations.size(); i++) - if (dynamic_cast(aux_equations[i])->containsExternalFunction()) - dynamic_cast(aux_equations[i])->writeExternalFunctionOutput(output, oLatexStaticModel, - temporary_terms, tef_terms); - for (int i = 0; i < (int) aux_equations.size(); i++) - { - output << "\\begin{dmath}" << endl; - dynamic_cast(aux_equations[i]->substituteStaticAuxiliaryDefinition())->writeOutput(output, oLatexStaticModel); - output << endl << "\\end{dmath}" << endl; - } -} - -void -StaticModel::writeJsonAuxVarRecursiveDefinitions(ostream &output) const -{ - deriv_node_temp_terms_t tef_terms; - temporary_terms_t temporary_terms; - - for (int i = 0; i < (int) aux_equations.size(); i++) - if (dynamic_cast(aux_equations[i])->containsExternalFunction()) - { - vector efout; - dynamic_cast(aux_equations[i])->writeJsonExternalFunctionOutput(efout, - temporary_terms, - tef_terms, - false); - for (vector::const_iterator it = efout.begin(); it != efout.end(); it++) - { - if (it != efout.begin()) - output << ", "; - output << *it; - } - } - - for (int i = 0; i < (int) aux_equations.size(); i++) - { - output << ", {\"lhs\": \""; - aux_equations[i]->get_arg1()->writeJsonOutput(output, temporary_terms, tef_terms, false); - output << "\", \"rhs\": \""; - dynamic_cast(aux_equations[i]->substituteStaticAuxiliaryDefinition())->get_arg2()->writeJsonOutput(output, temporary_terms, tef_terms, false); - output << "\"}"; - } -} - -void -StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) const -{ - if (!residuals_params_derivatives.size() - && !residuals_params_second_derivatives.size() - && !jacobian_params_derivatives.size() - && !jacobian_params_second_derivatives.size() - && !hessian_params_derivatives.size()) - return; - - ExprNodeOutputType output_type = (julia ? oJuliaStaticModel : oMatlabStaticModel); - - ostringstream model_local_vars_output; // Used for storing model local vars - ostringstream model_output; // Used for storing model - ostringstream jacobian_output; // Used for storing jacobian equations - ostringstream hessian_output; // Used for storing Hessian equations - ostringstream hessian1_output; // Used for storing Hessian equations - ostringstream third_derivs_output; // Used for storing third order derivatives equations - ostringstream third_derivs1_output; // Used for storing third order derivatives equations - - deriv_node_temp_terms_t tef_terms; - writeModelLocalVariables(model_local_vars_output, output_type, tef_terms); - - temporary_terms_t temp_terms_empty; - writeTemporaryTerms(params_derivs_temporary_terms, temp_terms_empty, model_output, output_type, tef_terms); - - for (first_derivatives_t::const_iterator it = residuals_params_derivatives.begin(); - it != residuals_params_derivatives.end(); it++) - { - int eq = it->first.first; - int param = it->first.second; - expr_t d1 = it->second; - - int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; - - jacobian_output << "rp" << LEFT_ARRAY_SUBSCRIPT(output_type) - << eq+1 << ", " << param_col - << RIGHT_ARRAY_SUBSCRIPT(output_type) << " = "; - d1->writeOutput(jacobian_output, output_type, params_derivs_temporary_terms, tef_terms); - jacobian_output << ";" << endl; - } - - for (second_derivatives_t::const_iterator it = jacobian_params_derivatives.begin(); - it != jacobian_params_derivatives.end(); it++) - { - int eq = it->first.first; - int var = it->first.second.first; - int param = it->first.second.second; - expr_t d2 = it->second; - - int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1; - int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; - - hessian_output << "gp" << LEFT_ARRAY_SUBSCRIPT(output_type) - << eq+1 << ", " << var_col << ", " << param_col - << RIGHT_ARRAY_SUBSCRIPT(output_type) << " = "; - d2->writeOutput(hessian_output, output_type, params_derivs_temporary_terms, tef_terms); - hessian_output << ";" << endl; - } - - int i = 1; - for (second_derivatives_t::const_iterator it = residuals_params_second_derivatives.begin(); - it != residuals_params_second_derivatives.end(); ++it, i++) - { - int eq = it->first.first; - int param1 = it->first.second.first; - int param2 = it->first.second.second; - expr_t d2 = it->second; - - int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; - int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; - - hessian1_output << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl - << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl - << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl - << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; - d2->writeOutput(hessian1_output, output_type, params_derivs_temporary_terms, tef_terms); - hessian1_output << ";" << endl; - } - - i = 1; - for (third_derivatives_t::const_iterator it = jacobian_params_second_derivatives.begin(); - it != jacobian_params_second_derivatives.end(); ++it, i++) - { - int eq = it->first.first; - int var = it->first.second.first; - int param1 = it->first.second.second.first; - int param2 = it->first.second.second.second; - expr_t d2 = it->second; - - int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1; - int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; - int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; - - third_derivs_output << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl - << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var_col << ";" << endl - << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl - << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl - << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; - d2->writeOutput(third_derivs_output, output_type, params_derivs_temporary_terms, tef_terms); - third_derivs_output << ";" << endl; - } - - i = 1; - for (third_derivatives_t::const_iterator it = hessian_params_derivatives.begin(); - it != hessian_params_derivatives.end(); ++it, i++) - { - int eq = it->first.first; - int var1 = it->first.second.first; - int var2 = it->first.second.second.first; - int param = it->first.second.second.second; - expr_t d2 = it->second; - - int var1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var1)) + 1; - int var2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var2)) + 1; - int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; - - third_derivs1_output << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl - << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var1_col << ";" << endl - << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var2_col << ";" << endl - << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param_col << ";" << endl - << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; - d2->writeOutput(third_derivs1_output, output_type, params_derivs_temporary_terms, tef_terms); - third_derivs1_output << ";" << endl; - } - - ofstream paramsDerivsFile; - string filename = julia ? basename + "StaticParamsDerivs.jl" : basename + "_static_params_derivs.m"; - paramsDerivsFile.open(filename.c_str(), ios::out | ios::binary); - if (!paramsDerivsFile.is_open()) - { - cerr << "ERROR: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - if (!julia) - { - // Check that we don't have more than 32 nested parenthesis because Matlab does not suppor this. See Issue #1201 - map tmp_paren_vars; - bool message_printed = false; - fixNestedParenthesis(model_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(model_local_vars_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(jacobian_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(hessian_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(hessian1_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(third_derivs_output, tmp_paren_vars, message_printed); - fixNestedParenthesis(third_derivs1_output, tmp_paren_vars, message_printed); - - paramsDerivsFile << "function [rp, gp, rpp, gpp, hp] = " << basename << "_static_params_derivs(y, x, params)" << endl - << "%" << endl - << "% Status : Computes derivatives of the static model with respect to the parameters" << endl - << "%" << endl - << "% Inputs : " << endl - << "% y [M_.endo_nbr by 1] double vector of endogenous variables in declaration order" << endl - << "% x [M_.exo_nbr by 1] double vector of exogenous variables in declaration order" << endl - << "% params [M_.param_nbr by 1] double vector of parameter values in declaration order" << endl - << "%" << endl - << "% Outputs:" << endl - << "% rp [M_.eq_nbr by #params] double Jacobian matrix of static model equations with respect to parameters " << endl - << "% Dynare may prepend or append auxiliary equations, see M_.aux_vars" << endl - << "% gp [M_.endo_nbr by M_.endo_nbr by #params] double Derivative of the Jacobian matrix of the static model equations with respect to the parameters" << endl - << "% rows: variables in declaration order" << endl - << "% rows: equations in order of declaration" << endl - << "% rpp [#second_order_residual_terms by 4] double Hessian matrix of second derivatives of residuals with respect to parameters;" << endl - << "% rows: respective derivative term" << endl - << "% 1st column: equation number of the term appearing" << endl - << "% 2nd column: number of the first parameter in derivative" << endl - << "% 3rd column: number of the second parameter in derivative" << endl - << "% 4th column: value of the Hessian term" << endl - << "% gpp [#second_order_Jacobian_terms by 5] double Hessian matrix of second derivatives of the Jacobian with respect to the parameters;" << endl - << "% rows: respective derivative term" << endl - << "% 1st column: equation number of the term appearing" << endl - << "% 2nd column: column number of variable in Jacobian of the static model" << endl - << "% 3rd column: number of the first parameter in derivative" << endl - << "% 4th column: number of the second parameter in derivative" << endl - << "% 5th column: value of the Hessian term" << endl - << "%" << endl - << "%" << endl - << "% Warning : this file is generated automatically by Dynare" << endl - << "% from model file (.mod)" << endl << endl - << model_local_vars_output.str() - << model_output.str() - << "rp = zeros(" << equations.size() << ", " - << symbol_table.param_nbr() << ");" << endl - << jacobian_output.str() - << "gp = zeros(" << equations.size() << ", " << symbol_table.endo_nbr() << ", " - << symbol_table.param_nbr() << ");" << endl - << hessian_output.str() - << "if nargout >= 3" << endl - << "rpp = zeros(" << residuals_params_second_derivatives.size() << ",4);" << endl - << hessian1_output.str() - << "gpp = zeros(" << jacobian_params_second_derivatives.size() << ",5);" << endl - << third_derivs_output.str() - << "end" << endl - << "if nargout >= 5" << endl - << "hp = zeros(" << hessian_params_derivatives.size() << ",5);" << endl - << third_derivs1_output.str() - << "end" << endl - << "end" << endl; - } - else - paramsDerivsFile << "module " << basename << "StaticParamsDerivs" << endl - << "#" << endl - << "# NB: this file was automatically generated by Dynare" << endl - << "# from " << basename << ".mod" << endl - << "#" << endl - << "export params_derivs" << endl << endl - << "function params_derivs(y, x, params)" << endl - << model_local_vars_output.str() - << model_output.str() - << "rp = zeros(" << equations.size() << ", " - << symbol_table.param_nbr() << ");" << endl - << jacobian_output.str() - << "gp = zeros(" << equations.size() << ", " << symbol_table.endo_nbr() << ", " - << symbol_table.param_nbr() << ");" << endl - << hessian_output.str() - << "rpp = zeros(" << residuals_params_second_derivatives.size() << ",4);" << endl - << hessian1_output.str() - << "gpp = zeros(" << jacobian_params_second_derivatives.size() << ",5);" << endl - << third_derivs_output.str() - << "hp = zeros(" << hessian_params_derivatives.size() << ",5);" << endl - << third_derivs1_output.str() - << "(rp, gp, rpp, gpp, hp)" << endl - << "end" << endl - << "end" << endl; - - paramsDerivsFile.close(); -} - -void -StaticModel::writeJsonOutput(ostream &output) const -{ - writeJsonModelEquations(output, false); -} - -void -StaticModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) const -{ - ostringstream model_local_vars_output; // Used for storing model local vars - ostringstream model_output; // Used for storing model - ostringstream jacobian_output; // Used for storing jacobian equations - ostringstream hessian_output; // Used for storing Hessian equations - ostringstream third_derivatives_output; // Used for storing third order derivatives equations - - deriv_node_temp_terms_t tef_terms; - temporary_terms_t temp_term_empty; - temporary_terms_t temp_term_union = temporary_terms_res; - temporary_terms_t temp_term_union_m_1; - - string concat = ""; - - writeJsonModelLocalVariables(model_local_vars_output, tef_terms); - - writeJsonTemporaryTerms(temporary_terms_res, temp_term_union_m_1, model_output, tef_terms, concat); - model_output << ", "; - writeJsonModelEquations(model_output, true); - - int nrows = equations.size(); - int JacobianColsNbr = symbol_table.endo_nbr(); - int hessianColsNbr = JacobianColsNbr*JacobianColsNbr; - - // Write Jacobian w.r. to endogenous only - temp_term_union_m_1 = temp_term_union; - temp_term_union.insert(temporary_terms_g1.begin(), temporary_terms_g1.end()); - concat = "jacobian"; - writeJsonTemporaryTerms(temp_term_union, temp_term_union_m_1, jacobian_output, tef_terms, concat); - jacobian_output << ", \"jacobian\": {" - << " \"nrows\": " << nrows - << ", \"ncols\": " << JacobianColsNbr - << ", \"entries\": ["; - for (first_derivatives_t::const_iterator it = first_derivatives.begin(); - it != first_derivatives.end(); it++) - { - if (it != first_derivatives.begin()) - jacobian_output << ", "; - - int eq = it->first.first; - int var = it->first.second; - int symb_id = getSymbIDByDerivID(var); - int col = symbol_table.getTypeSpecificID(symb_id); - expr_t d1 = it->second; - - if (writeDetails) - jacobian_output << "{\"eq\": " << eq + 1; - else - jacobian_output << "{\"row\": " << eq + 1; - - jacobian_output << ", \"col\": " << col + 1; - - if (writeDetails) - jacobian_output << ", \"var\": \"" << symbol_table.getName(symb_id) << "\""; - - jacobian_output << ", \"val\": \""; - d1->writeJsonOutput(jacobian_output, temp_term_union, tef_terms); - jacobian_output << "\"}" << endl; - } - jacobian_output << "]}"; - - int g2ncols = symbol_table.endo_nbr() * symbol_table.endo_nbr(); - // Write Hessian w.r. to endogenous only (only if 2nd order derivatives have been computed) - temp_term_union_m_1 = temp_term_union; - temp_term_union.insert(temporary_terms_g2.begin(), temporary_terms_g2.end()); - concat = "hessian"; - writeJsonTemporaryTerms(temp_term_union, temp_term_union_m_1, hessian_output, tef_terms, concat); - hessian_output << ", \"hessian\": {" - << " \"nrows\": " << equations.size() - << ", \"ncols\": " << g2ncols - << ", \"entries\": ["; - for (second_derivatives_t::const_iterator it = second_derivatives.begin(); - it != second_derivatives.end(); it++) - { - if (it != second_derivatives.begin()) - hessian_output << ", "; - - int eq = it->first.first; - int symb_id1 = getSymbIDByDerivID(it->first.second.first); - int symb_id2 = getSymbIDByDerivID(it->first.second.second); - expr_t d2 = it->second; - - int tsid1 = symbol_table.getTypeSpecificID(symb_id1); - int tsid2 = symbol_table.getTypeSpecificID(symb_id2); - - int col = tsid1*symbol_table.endo_nbr()+tsid2; - int col_sym = tsid2*symbol_table.endo_nbr()+tsid1; - - if (writeDetails) - hessian_output << "{\"eq\": " << eq + 1; - else - hessian_output << "{\"row\": " << eq + 1; - - hessian_output << ", \"col\": [" << col + 1; - - if (writeDetails) - hessian_output << ", \"var1\": \"" << symbol_table.getName(symb_id1) << "\"" - << ", \"var2\": \"" << symbol_table.getName(symb_id2) << "\""; - - if (symb_id1 != symb_id2) - hessian_output << ", " << col_sym + 1; - hessian_output << "]" - << ", \"val\": \""; - d2->writeJsonOutput(hessian_output, temp_term_union, tef_terms); - hessian_output << "\"}" << endl; - } - hessian_output << "]}"; - - // Writing third derivatives - temp_term_union_m_1 = temp_term_union; - temp_term_union.insert(temporary_terms_g3.begin(), temporary_terms_g3.end()); - concat = "third_derivatives"; - writeJsonTemporaryTerms(temp_term_union, temp_term_union_m_1, third_derivatives_output, tef_terms, concat); - third_derivatives_output << ", \"third_derivative\": {" - << " \"nrows\": " << equations.size() - << ", \"ncols\": " << hessianColsNbr * JacobianColsNbr - << ", \"entries\": ["; - for (third_derivatives_t::const_iterator it = third_derivatives.begin(); - it != third_derivatives.end(); it++) - { - if (it != third_derivatives.begin()) - third_derivatives_output << ", "; - - int eq = it->first.first; - int var1 = it->first.second.first; - int var2 = it->first.second.second.first; - int var3 = it->first.second.second.second; - expr_t d3 = it->second; - - if (writeDetails) - third_derivatives_output << "{\"eq\": " << eq + 1; - else - third_derivatives_output << "{\"row\": " << eq + 1; - - int id1 = getSymbIDByDerivID(var1); - int id2 = getSymbIDByDerivID(var2); - int id3 = getSymbIDByDerivID(var3); - set cols; - cols.insert(id1 * hessianColsNbr + id2 * JacobianColsNbr + id3); - cols.insert(id1 * hessianColsNbr + id3 * JacobianColsNbr + id2); - cols.insert(id2 * hessianColsNbr + id1 * JacobianColsNbr + id3); - cols.insert(id2 * hessianColsNbr + id3 * JacobianColsNbr + id1); - cols.insert(id3 * hessianColsNbr + id1 * JacobianColsNbr + id2); - cols.insert(id3 * hessianColsNbr + id2 * JacobianColsNbr + id1); - - third_derivatives_output << ", \"col\": ["; - for (set::iterator it2 = cols.begin(); it2 != cols.end(); it2++) - { - if (it2 != cols.begin()) - third_derivatives_output << ", "; - third_derivatives_output << *it2 + 1; - } - third_derivatives_output << "]"; - - if (writeDetails) - third_derivatives_output << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" - << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" - << ", \"var3\": \"" << symbol_table.getName(getSymbIDByDerivID(var3)) << "\""; - - third_derivatives_output << ", \"val\": \""; - d3->writeJsonOutput(third_derivatives_output, temp_term_union, tef_terms); - third_derivatives_output << "\"}" << endl; - } - third_derivatives_output << "]}"; - - if (writeDetails) - output << "\"static_model\": {"; - else - output << "\"static_model_simple\": {"; - output << model_local_vars_output.str() - << ", " << model_output.str() - << ", " << jacobian_output.str() - << ", " << hessian_output.str() - << ", " << third_derivatives_output.str() - << "}"; -} - -void -StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) const -{ - if (!residuals_params_derivatives.size() - && !residuals_params_second_derivatives.size() - && !jacobian_params_derivatives.size() - && !jacobian_params_second_derivatives.size() - && !hessian_params_derivatives.size()) - return; - - ostringstream model_local_vars_output; // Used for storing model local vars - ostringstream model_output; // Used for storing model temp vars and equations - ostringstream jacobian_output; // Used for storing jacobian equations - ostringstream hessian_output; // Used for storing Hessian equations - ostringstream hessian1_output; // Used for storing Hessian equations - ostringstream third_derivs_output; // Used for storing third order derivatives equations - ostringstream third_derivs1_output; // Used for storing third order derivatives equations - - deriv_node_temp_terms_t tef_terms; - writeJsonModelLocalVariables(model_local_vars_output, tef_terms); - - temporary_terms_t temp_terms_empty; - string concat = "all"; - writeJsonTemporaryTerms(params_derivs_temporary_terms, temp_terms_empty, model_output, tef_terms, concat); - jacobian_output << "\"deriv_wrt_params\": {" - << " \"neqs\": " << equations.size() - << ", \"nparamcols\": " << symbol_table.param_nbr() - << ", \"entries\": ["; - for (first_derivatives_t::const_iterator it = residuals_params_derivatives.begin(); - it != residuals_params_derivatives.end(); it++) - { - if (it != residuals_params_derivatives.begin()) - jacobian_output << ", "; - - int eq = it->first.first; - int param = it->first.second; - expr_t d1 = it->second; - - int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; - - if (writeDetails) - jacobian_output << "{\"eq\": " << eq + 1; - else - jacobian_output << "{\"row\": " << eq + 1; - - if (writeDetails) - jacobian_output << ", \"param_col\": " << param_col; - - jacobian_output << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; - - jacobian_output << ", \"val\": \""; - d1->writeJsonOutput(jacobian_output, params_derivs_temporary_terms, tef_terms); - jacobian_output << "\"}" << endl; - } - jacobian_output << "]}"; - hessian_output << "\"deriv_jacobian_wrt_params\": {" - << " \"neqs\": " << equations.size() - << ", \"nvarcols\": " << symbol_table.endo_nbr() - << ", \"nparamcols\": " << symbol_table.param_nbr() - << ", \"entries\": ["; - for (second_derivatives_t::const_iterator it = jacobian_params_derivatives.begin(); - it != jacobian_params_derivatives.end(); it++) - { - if (it != jacobian_params_derivatives.begin()) - hessian_output << ", "; - - int eq = it->first.first; - int var = it->first.second.first; - int param = it->first.second.second; - expr_t d2 = it->second; - - int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1; - int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; - - if (writeDetails) - hessian_output << "{\"eq\": " << eq + 1; - else - hessian_output << "{\"row\": " << eq + 1; - - if (writeDetails) - hessian_output << ", \"var\": \"" << symbol_table.getName(getSymbIDByDerivID(var)) << "\"" - << ", \"param\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; - - hessian_output << ", \"var_col\": " << var_col - << ", \"param_col\": " << param_col - << ", \"val\": \""; - d2->writeJsonOutput(hessian_output, params_derivs_temporary_terms, tef_terms); - hessian_output << "\"}" << endl; - } - hessian_output << "]}"; - - hessian1_output << "\"second_deriv_residuals_wrt_params\": {" - << " \"nrows\": " << equations.size() - << ", \"nparam1cols\": " << symbol_table.param_nbr() - << ", \"nparam2cols\": " << symbol_table.param_nbr() - << ", \"entries\": ["; - for (second_derivatives_t::const_iterator it = residuals_params_second_derivatives.begin(); - it != residuals_params_second_derivatives.end(); ++it) - { - if (it != residuals_params_second_derivatives.begin()) - hessian1_output << ", "; - - int eq = it->first.first; - int param1 = it->first.second.first; - int param2 = it->first.second.second; - expr_t d2 = it->second; - - int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; - int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; - - if (writeDetails) - hessian1_output << "{\"eq\": " << eq + 1; - else - hessian1_output << "{\"row\": " << eq + 1; - - hessian1_output << ", \"param1_col\": " << param1_col - << ", \"param2_col\": " << param2_col; - - if (writeDetails) - hessian1_output << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param1)) << "\"" - << ", \"param2\": \"" << symbol_table.getName(getSymbIDByDerivID(param2)) << "\""; - - hessian1_output << ", \"val\": \""; - d2->writeJsonOutput(hessian1_output, params_derivs_temporary_terms, tef_terms); - hessian1_output << "\"}" << endl; - } - hessian1_output << "]}"; - third_derivs_output << "\"second_deriv_jacobian_wrt_params\": {" - << " \"neqs\": " << equations.size() - << ", \"nvarcols\": " << symbol_table.endo_nbr() - << ", \"nparam1cols\": " << symbol_table.param_nbr() - << ", \"nparam2cols\": " << symbol_table.param_nbr() - << ", \"entries\": ["; - for (third_derivatives_t::const_iterator it = jacobian_params_second_derivatives.begin(); - it != jacobian_params_second_derivatives.end(); ++it) - { - if (it != jacobian_params_second_derivatives.begin()) - third_derivs_output << ", "; - - int eq = it->first.first; - int var = it->first.second.first; - int param1 = it->first.second.second.first; - int param2 = it->first.second.second.second; - expr_t d2 = it->second; - - int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1; - int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1; - int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1; - - if (writeDetails) - third_derivs_output << "{\"eq\": " << eq + 1; - else - third_derivs_output << "{\"row\": " << eq + 1; - third_derivs_output << ", \"var_col\": " << var_col - << ", \"param1_col\": " << param1_col - << ", \"param2_col\": " << param2_col; - - if (writeDetails) - third_derivs_output << ", \"var\": \"" << symbol_table.getName(var) << "\"" - << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param1)) << "\"" - << ", \"param2\": \"" << symbol_table.getName(getSymbIDByDerivID(param2)) << "\""; - - third_derivs_output << ", \"val\": \""; - d2->writeJsonOutput(third_derivs_output, params_derivs_temporary_terms, tef_terms); - third_derivs_output << "\"}" << endl; - } - third_derivs_output << "]}" << endl; - - third_derivs1_output << "\"derivative_hessian_wrt_params\": {" - << " \"neqs\": " << equations.size() - << ", \"nvar1cols\": " << symbol_table.endo_nbr() - << ", \"nvar2cols\": " << symbol_table.endo_nbr() - << ", \"nparamcols\": " << symbol_table.param_nbr() - << ", \"entries\": ["; - for (third_derivatives_t::const_iterator it = hessian_params_derivatives.begin(); - it != hessian_params_derivatives.end(); ++it) - { - if (it != hessian_params_derivatives.begin()) - third_derivs1_output << ", "; - - int eq = it->first.first; - int var1 = it->first.second.first; - int var2 = it->first.second.second.first; - int param = it->first.second.second.second; - expr_t d2 = it->second; - - int var1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var1)) + 1; - int var2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var2)) + 1; - int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1; - - if (writeDetails) - third_derivs1_output << "{\"eq\": " << eq + 1; - else - third_derivs1_output << "{\"row\": " << eq + 1; - - third_derivs1_output << ", \"var1_col\": " << var1_col - << ", \"var2_col\": " << var2_col - << ", \"param_col\": " << param_col; - - if (writeDetails) - third_derivs1_output << ", \"var1\": \"" << symbol_table.getName(getSymbIDByDerivID(var1)) << "\"" - << ", \"var2\": \"" << symbol_table.getName(getSymbIDByDerivID(var2)) << "\"" - << ", \"param1\": \"" << symbol_table.getName(getSymbIDByDerivID(param)) << "\""; - - third_derivs1_output << ", \"val\": \""; - d2->writeJsonOutput(third_derivs1_output, params_derivs_temporary_terms, tef_terms); - third_derivs1_output << "\"}" << endl; - } - third_derivs1_output << "]}" << endl; - - if (writeDetails) - output << "\"static_model_params_derivative\": {"; - else - output << "\"static_model_params_derivatives_simple\": {"; - output << model_local_vars_output.str() - << ", " << model_output.str() - << ", " << jacobian_output.str() - << ", " << hessian_output.str() - << ", " << hessian1_output.str() - << ", " << third_derivs_output.str() - << ", " << third_derivs1_output.str() - << "}"; -} diff --git a/preprocessor/StaticModel.hh b/preprocessor/StaticModel.hh deleted file mode 100644 index ad55f89d9..000000000 --- a/preprocessor/StaticModel.hh +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#ifndef _STATIC_MODEL_HH -#define _STATIC_MODEL_HH - -using namespace std; - -#include - -#include "ModelTree.hh" - -//! Stores a static model, as derived from the "model" block when leads and lags have been removed -class StaticModel : public ModelTree -{ -private: - //! global temporary terms for block decomposed models - vector > v_temporary_terms; - - //! local temporary terms for block decomposed models - vector > v_temporary_terms_local; - - vector v_temporary_terms_inuse; - - typedef map< pair< int, pair< int, int> >, expr_t> first_chain_rule_derivatives_t; - first_chain_rule_derivatives_t first_chain_rule_derivatives; - - //! Writes static model file (standard Matlab version) - void writeStaticMFile(const string &static_basename) const; - - //! Writes static model file (C version) - void writeStaticCFile(const string &func_name) const; - - //! Writes static model file (Julia version) - void writeStaticJuliaFile(const string &basename) const; - - //! Writes the static model equations and its derivatives - void writeStaticModel(ostream &StaticOutput, bool use_dll, bool julia) const; - - //! Writes the static function calling the block to solve (Matlab version) - void writeStaticBlockMFSFile(const string &basename) 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(const string file_name, const string bin_basename, map_idx_t map_idx, vector map_idx2) const; - - //! Writes the code of the model in virtual machine bytecode - void writeModelEquationsCode(const string file_name, const string bin_basename, 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_t *j_m, bool dynamic); - - map_idx_t map_idx; - - vector map_idx2; - - //! 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(temporary_terms_t &temporary_terms, map_idx_t &map_idx); - - //! 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, map_idx_t &map_idx, temporary_terms_t temporary_terms) 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, map_idx_t &map_idx, temporary_terms_t temporary_terms) 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 static Jacobian - void computeStatJacobianCols(); - //! return a map on the block jacobian - map >, pair >, int> get_Derivatives(int block); - //! Computes chain rule derivatives of the Jacobian w.r. to endogenous variables - void computeChainRuleJacobian(blocks_derivatives_t &blocks_derivatives); - //! Collect only the first derivatives - map >, expr_t> collect_first_order_derivatives_endogenous(); - - //! Write chain rule derivative of a recursive equation w.r. to a variable - void writeChainRuleDerivative(ostream &output, int eq, int var, int lag, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const; - - //! Collecte the derivatives w.r. to endogenous of the block, to endogenous of previouys blocks and to exogenous - void collect_block_first_order_derivatives(); - -protected: - //! Indicate if the temporary terms are computed for the overall model (true) or not (false). Default value true - bool global_temporary_terms; - - //! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a expr_t on the new normalized equation - equation_type_and_normalized_equation_t equation_type_and_normalized_equation; - - //! for each block contains pair< Simulation_Type, pair < Block_Size, Recursive_part_Size > > - block_type_firstequation_size_mfs_t block_type_firstequation_size_mfs; - - //! for all blocks derivatives description - blocks_derivatives_t blocks_derivatives; - - //! The jacobian without the elements below the cutoff - dynamic_jacob_map_t dynamic_jacobian; - - //! Vector indicating if the block is linear in endogenous variable (true) or not (false) - vector blocks_linear; - - //! Map the derivatives for a block pair - typedef map >, expr_t> derivative_t; - //! Vector of derivative for each blocks - vector derivative_endo, derivative_other_endo, derivative_exo, derivative_exo_det; - - //!List for each block and for each lag-leag all the other endogenous variables and exogenous variables - typedef set var_t; - typedef map lag_var_t; - vector other_endo_block, exo_block, exo_det_block; - - //! for each block described the number of static, forward, backward and mixed variables in the block - /*! pair< pair, pair > */ - vector, pair > > block_col_type; - - //! List for each variable its block number and its maximum lag and lead inside the block - vector > > variable_block_lead_lag; - //! List for each equation its block number - vector equation_block; - - //!Maximum lead and lag for each block on endogenous of the block, endogenous of the previous blocks, exogenous and deterministic exogenous - vector > endo_max_leadlag_block, other_endo_max_leadlag_block, exo_max_leadlag_block, exo_det_max_leadlag_block, max_leadlag_block; - -public: - StaticModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants, ExternalFunctionsTable &external_functions_table_arg); - - //! Writes information on block decomposition when relevant - void writeOutput(ostream &output, bool block) const; - - //! Execute computations (variable sorting + derivation) - /*! - \param eval_context evaluation context for normalization - \param no_tmp_terms if true, no temporary terms will be computed in the static files - \param hessian whether 2nd derivatives w.r. to exo, exo_det and endo should be computed - \param paramsDerivsOrder order of derivatives w.r. to a pair (endo/exo/exo_det, parameter) to be computed - */ - void computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian, bool thirdDerivatices, int paramsDerivsOrder, bool block, bool bytecode, const bool nopreprocessoroutput); - - //! Adds informations for simulation in a binary file for a block decomposed model - void Write_Inf_To_Bin_File_Block(const string &static_basename, const string &bin_basename, const int &num, - int &u_count_int, bool &file_open) const; - - //! Writes static model file - void writeStaticFile(const string &basename, bool block, bool bytecode, bool use_dll, bool julia) const; - - //! Write JSON Output (used by PlannerObjectiveStatement) - void writeJsonOutput(ostream &output) const; - - //! Write JSON representation of static model - void writeJsonComputingPassOutput(ostream &output, bool writeDetails) const; - - //! Writes file containing static parameters derivatives - void writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) const; - - //! Writes file containing static parameters derivatives - void writeParamsDerivativesFile(const string &basename, bool julia) const; - - //! Writes LaTeX file with the equations of the static model - void writeLatexFile(const string &basename, const bool write_equation_tags) const; - - //! Writes initializations in oo_.steady_state or steady state file for the auxiliary variables - void writeAuxVarInitval(ostream &output, ExprNodeOutputType output_type) const; - - //! Writes definition of the auxiliary variables in a .m or .jl file - void writeSetAuxiliaryVariables(const string &basename, const bool julia) const; - void writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType output_type) const; - void writeLatexAuxVarRecursiveDefinitions(ostream &output) const; - void writeJsonAuxVarRecursiveDefinitions(ostream &output) const; - - //! To ensure that no exogenous is present in the planner objective - //! See #1264 - bool exoPresentInEqs() const; - - virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException); - virtual void addAllParamDerivId(set &deriv_id_set); - - //! Return the number of blocks - virtual unsigned int - getNbBlocks() const - { - return (block_type_firstequation_size_mfs.size()); - }; - //! Determine the simulation type of each block - virtual BlockSimulationType - getBlockSimulationType(int block_number) 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 0; - }; - //! 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 0; - } - //! 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 - { - return 0; - }; - //! 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 the position of variable_number in the block number belonging to the block block_number - virtual int - getBlockInitialExogenousID(int block_number, int variable_number) const - { - return -1; - }; - //! 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 - { - return -1; - }; - //! 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 - { - return -1; - }; -}; - -#endif diff --git a/preprocessor/SteadyStateModel.cc b/preprocessor/SteadyStateModel.cc deleted file mode 100644 index b1385ad8f..000000000 --- a/preprocessor/SteadyStateModel.cc +++ /dev/null @@ -1,316 +0,0 @@ -/* - * 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 . - */ - -#include -#include - -#include "SteadyStateModel.hh" - -SteadyStateModel::SteadyStateModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_arg, const StaticModel &static_model_arg) : - DataTree(symbol_table_arg, num_constants_arg, external_functions_table_arg), static_model(static_model_arg) -{ -} - -void -SteadyStateModel::addDefinition(int symb_id, expr_t expr) -{ - AddVariable(symb_id); // Create the variable node to be used in write method - - assert(symbol_table.getType(symb_id) == eEndogenous - || symbol_table.getType(symb_id) == eModFileLocalVariable - || symbol_table.getType(symb_id) == eParameter); - - // Add the variable - vector v; - v.push_back(symb_id); - def_table.push_back(make_pair(v, expr)); -} - -void -SteadyStateModel::addMultipleDefinitions(const vector &symb_ids, expr_t expr) -{ - for (size_t i = 0; i < symb_ids.size(); i++) - { - AddVariable(symb_ids[i]); // Create the variable nodes to be used in write method - assert(symbol_table.getType(symb_ids[i]) == eEndogenous - || symbol_table.getType(symb_ids[i]) == eModFileLocalVariable - || symbol_table.getType(symb_ids[i]) == eParameter); - } - def_table.push_back(make_pair(symb_ids, expr)); -} - -void -SteadyStateModel::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) const -{ - if (def_table.size() == 0) - return; - - mod_file_struct.steady_state_model_present = true; - vector so_far_defined; - - for (size_t i = 0; i < def_table.size(); i++) - { - const vector &symb_ids = def_table[i].first; - - // Check that symbols are not already defined - for (size_t j = 0; j < symb_ids.size(); j++) - if (find(so_far_defined.begin(), so_far_defined.end(), symb_ids[j]) - != so_far_defined.end()) - warnings << "WARNING: in the 'steady_state_model' block, variable '" << symbol_table.getName(symb_ids[j]) << "' is declared twice" << endl; - - // Check that expression has no undefined symbol - if (!mod_file_struct.ramsey_model_present) - { - set used_symbols; - const expr_t &expr = def_table[i].second; - expr->collectVariables(eEndogenous, used_symbols); - expr->collectVariables(eModFileLocalVariable, used_symbols); - for (set::const_iterator it = used_symbols.begin(); - it != used_symbols.end(); ++it) - if (find(so_far_defined.begin(), so_far_defined.end(), *it) - == so_far_defined.end()) - { - cerr << "ERROR: in the 'steady_state_model' block, variable '" << symbol_table.getName(*it) - << "' is undefined in the declaration of variable '" << symbol_table.getName(symb_ids[0]) << "'" << endl; - exit(EXIT_FAILURE); - } - } - - copy(symb_ids.begin(), symb_ids.end(), back_inserter(so_far_defined)); - } - - set orig_endogs = symbol_table.getOrigEndogenous(); - for (set::const_iterator it = orig_endogs.begin(); - it != orig_endogs.end(); ++it) - { - if (find(so_far_defined.begin(), so_far_defined.end(), *it) - == so_far_defined.end()) - warnings << "WARNING: in the 'steady_state_model' block, variable '" << symbol_table.getName(*it) << "' is not assigned a value" << endl; - } -} - -void -SteadyStateModel::writeLatexSteadyStateFile(const string &basename) const -{ - ofstream output, content_output; - string filename = basename + "_steady_state.tex"; - string content_basename = basename + "_steady_state_content"; - string content_filename = content_basename + ".tex"; - - output.open(filename.c_str(), ios::out | ios::binary); - if (!output.is_open()) - { - cerr << "ERROR: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - content_output.open(content_filename.c_str(), ios::out | ios::binary); - if (!content_output.is_open()) - { - cerr << "ERROR: Can't open file " << content_filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - output << "\\documentclass[10pt,a4paper]{article}" << endl - << "\\usepackage[landscape]{geometry}" << endl - << "\\usepackage{fullpage}" << endl - << "\\usepackage{amsfonts}" << endl - << "\\usepackage{breqn}" << endl - << "\\begin{document}" << endl - << "\\footnotesize" << endl; - - for (vector, expr_t> >::const_iterator it = def_table.begin(); - it != def_table.end(); it++) - for (vector::const_iterator it1 = it->first.begin(); it1 != it->first.end(); it1++) - { - int id = *it1; - expr_t value = it->second; - content_output << "\\begin{dmath}" << endl - << symbol_table.getTeXName(id) << " = "; - value->writeOutput(content_output, oLatexStaticModel); - content_output << endl << "\\end{dmath}" << endl; - } - - static_model.writeLatexAuxVarRecursiveDefinitions(content_output); - - output << "\\include{" << content_basename << "}" << endl - << "\\end{document}" << endl; - - output.close(); - content_output.close(); -} - -void -SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_model, bool julia) const -{ - if (def_table.size() == 0) - return; - - string filename = julia ? basename + "SteadyState2.jl" : basename + "_steadystate2.m"; - ofstream output; - output.open(filename.c_str(), ios::out | ios::binary); - if (!output.is_open()) - { - cerr << "ERROR: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - ExprNodeOutputType output_type = (julia ? oJuliaSteadyStateFile : oSteadyStateFile); - - if (!julia) - output << "function [ys_, params, info] = " << basename << "_steadystate2(" - << "ys_, exo_, params)" << endl - << "% Steady state generated by Dynare preprocessor" << endl - << " info = 0;" << endl; - else - output << "module " << basename << "SteadyState2" << endl - << "#" << endl - << "# NB: this file was automatically generated by Dynare" << endl - << "# from " << basename << ".mod" << endl - << "#" << endl - << "export steady_state!" << endl << endl - << "function steady_state!(ys_::Vector{Float64}, exo_::Vector{Float64}, " - << "params::Vector{Float64})" << endl; - - for (size_t i = 0; i < def_table.size(); i++) - { - const vector &symb_ids = def_table[i].first; - output << " "; - if (symb_ids.size() > 1) - output << "["; - for (size_t j = 0; j < symb_ids.size(); j++) - { - variable_node_map_t::const_iterator it = variable_node_map.find(make_pair(symb_ids[j], 0)); - assert(it != variable_node_map.end()); - dynamic_cast(it->second)->writeOutput(output, output_type); - if (j < symb_ids.size()-1) - output << ","; - } - if (symb_ids.size() > 1) - output << "]"; - - output << "="; - def_table[i].second->writeOutput(output, output_type); - output << ";" << endl; - } - if (!julia) - output << " % Auxiliary equations" << endl; - else - output << " # Auxiliary equations" << endl; - static_model.writeAuxVarRecursiveDefinitions(output, output_type); - - if (!julia) - output << " check_=0;" << endl; - - output << "end" << endl; - if (julia) - output << "end" << endl; -} - -void -SteadyStateModel::writeSteadyStateFileC(const string &basename, bool ramsey_model) const -{ - string filename = basename + "_steadystate.c"; - - ofstream output; - output.open(filename.c_str(), ios::out | ios::binary); - if (!output.is_open()) - { - cerr << "ERROR: Can't open file " << filename << " for writing" << endl; - exit(EXIT_FAILURE); - } - - output << "#include " << endl; - - output << "void steadystate(" - << "const double *exo_, const double *params, double *ys_, int *info)" << endl - << "// Steady state file generated by Dynare preprocessor" << endl - << "{" << endl - << " *info = 0;" << endl; - - if (def_table.size() == 0) - { - output << " return;" << endl - << "}" << endl; - return; - } - - for (size_t i = 0; i < def_table.size(); i++) - { - const vector &symb_ids = def_table[i].first; - output << " "; - if (symb_ids.size() > 1) - std::cout << "Error: in C, multiple returns are not permitted in steady_state_model" << std::endl; - variable_node_map_t::const_iterator it = variable_node_map.find(make_pair(symb_ids[0], 0)); - assert(it != variable_node_map.end()); - if (it->second->get_type() == eModFileLocalVariable) - output << "double "; - dynamic_cast(it->second)->writeOutput(output, oCSteadyStateFile); - output << "="; - def_table[i].second->writeOutput(output, oCSteadyStateFile); - output << ";" << endl; - } - output << " // Auxiliary equations" << endl; - static_model.writeAuxVarInitval(output, oCSteadyStateFile); - output << "}" << endl; -} - -void -SteadyStateModel::writeJsonSteadyStateFile(ostream &output, bool transformComputingPass) const -{ - if (def_table.size() == 0) - return; - - deriv_node_temp_terms_t tef_terms; - vector > eqtags; - temporary_terms_t tt_empty; - - output << "{\"steady_state_model\": ["; - - for (size_t i = 0; i < def_table.size(); i++) - { - const vector &symb_ids = def_table[i].first; - if (i != 0) - output << ","; - output << "{\"lhs\": "; - if (symb_ids.size() > 1) - output << "["; - for (size_t j = 0; j < symb_ids.size(); j++) - { - if (j != 0) - output << ","; - variable_node_map_t::const_iterator it = - variable_node_map.find(make_pair(symb_ids[j], 0)); - assert(it != variable_node_map.end()); - output << "\""; - dynamic_cast(it->second)->writeJsonOutput(output, tt_empty, tef_terms, false); - output << "\""; - } - if (symb_ids.size() > 1) - output << "]"; - output << ", \"rhs\":\""; - def_table[i].second->writeJsonOutput(output, tt_empty, tef_terms, false); - output << "\"}" << endl; - } - - if (transformComputingPass) - static_model.writeJsonAuxVarRecursiveDefinitions(output); - - output << "]}"; -} diff --git a/preprocessor/SteadyStateModel.hh b/preprocessor/SteadyStateModel.hh deleted file mode 100644 index 2c3a23c5f..000000000 --- a/preprocessor/SteadyStateModel.hh +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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 . - */ - -#ifndef _STEADY_STATE_MODEL_HH -#define _STEADY_STATE_MODEL_HH - -#include "DataTree.hh" -#include "Statement.hh" -#include "StaticModel.hh" -#include "WarningConsolidation.hh" - -class SteadyStateModel : public DataTree -{ -private: - //! Associates a set of symbol IDs (the variable(s) assigned in a given statement) to an expression (their assigned value) - vector, expr_t> > def_table; - - //! Reference to static model (for writing auxiliary equations) - const StaticModel &static_model; - -public: - SteadyStateModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_arg, const StaticModel &static_model_arg); - //! Add an expression of the form "var = expr;" - void addDefinition(int symb_id, expr_t expr); - //! Add an expression of the form "[ var1, var2, ... ] = expr;" - void addMultipleDefinitions(const vector &symb_ids, expr_t expr); - //! Checks that definitions are in a recursive order, and that no variable is declared twice - /*! - \param[in] ramsey_model Is there a Ramsey model in the MOD file? If yes, then disable the check on the recursivity of the declarations - */ - void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) const; - //! Write the steady state file - /*! - \param[in] ramsey_model Is there a Ramsey model in the MOD file? If yes, then use the "ys" in argument of the steady state file as initial values - */ - void writeSteadyStateFile(const string &basename, bool ramsey_model, bool julia) const; - void writeSteadyStateFileC(const string &basename, bool ramsey_model) const; - //! Writes LaTeX file with the equations of the dynamic model (for the steady state model) - void writeLatexSteadyStateFile(const string &basename) const; - //! Writes JSON output - void writeJsonSteadyStateFile(ostream &output, bool transformComputingPass) const; -}; - -#endif diff --git a/preprocessor/SymbolList.cc b/preprocessor/SymbolList.cc deleted file mode 100644 index 5d7efd4f3..000000000 --- a/preprocessor/SymbolList.cc +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2003-2018 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 . - */ - -#include "SymbolList.hh" - -void -SymbolList::addSymbol(const string &symbol) -{ - symbols.push_back(symbol); -} - -void -SymbolList::writeOutput(const string &varname, ostream &output) const -{ - output << varname << " = {"; - for (vector::const_iterator it = symbols.begin(); - it != symbols.end(); ++it) - { - if (it != symbols.begin()) - output << ";"; - output << "'" << *it << "'"; - } - output << "};" << endl; -} - -void -SymbolList::writeJsonOutput(ostream &output) const -{ - output << "\"symbol_list\": ["; - for (vector::const_iterator it = symbols.begin(); - it != symbols.end(); ++it) - { - if (it != symbols.begin()) - output << ","; - output << "\"" << *it << "\""; - } - output << "]"; -} - -void -SymbolList::clear() -{ - symbols.clear(); -} diff --git a/preprocessor/SymbolList.hh b/preprocessor/SymbolList.hh deleted file mode 100644 index 26c61c503..000000000 --- a/preprocessor/SymbolList.hh +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#ifndef _SYMBOL_LIST_HH -#define _SYMBOL_LIST_HH - -#include -#include -#include - -using namespace std; - -//! Used to store a list of symbols -/*! This class is no more than a vector, with a pretty-printer for Matlab */ -class SymbolList -{ -private: - //! Internal container for symbol list - vector symbols; -public: - //! Adds a symbol to the list - void addSymbol(const string &symbol); - //! Output content in Matlab format - /*! Creates a string array for Matlab, stored in variable "varname" */ - void writeOutput(const string &varname, ostream &output) const; - //! Write JSON output - void writeJsonOutput(ostream &output) const; - //! Clears all content - void clear(); - //! Get a copy of the string vector - vector - get_symbols() const - { - return symbols; - }; - //! Is Empty - int - empty() const - { - return symbols.empty(); - }; -}; - -#endif diff --git a/preprocessor/SymbolTable.cc b/preprocessor/SymbolTable.cc deleted file mode 100644 index 5b71e5e12..000000000 --- a/preprocessor/SymbolTable.cc +++ /dev/null @@ -1,986 +0,0 @@ -/* - * Copyright (C) 2003-2018 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 . - */ - -#include -#include -#include -#include -#include - -#include "SymbolTable.hh" - -AuxVarInfo::AuxVarInfo(int symb_id_arg, aux_var_t type_arg, int orig_symb_id_arg, int orig_lead_lag_arg, - int equation_number_for_multiplier_arg, int information_set_arg, - expr_t expr_node_arg) : - symb_id(symb_id_arg), - type(type_arg), - orig_symb_id(orig_symb_id_arg), - orig_lead_lag(orig_lead_lag_arg), - equation_number_for_multiplier(equation_number_for_multiplier_arg), - information_set(information_set_arg), - expr_node(expr_node_arg) -{ -} - -SymbolTable::SymbolTable() : frozen(false) -{ -} - -int -SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_name, const vector *> *partition_value) throw (AlreadyDeclaredException, FrozenException) -{ - if (frozen) - throw FrozenException(); - - if (exists(name)) - { - if (type_table[getID(name)] == type) - throw AlreadyDeclaredException(name, true); - else - throw AlreadyDeclaredException(name, false); - } - - string final_tex_name = tex_name; - if (final_tex_name.empty()) - { - final_tex_name = name; - size_t pos = 0; - while ((pos = final_tex_name.find('_', pos)) != string::npos) - { - final_tex_name.insert(pos, "\\"); - pos += 2; - } - } - - string final_long_name = name; - bool non_long_name_partition_exists = false; - if (partition_value) - for (vector *>::const_iterator it = partition_value->begin(); - it != partition_value->end(); it++) - if (*((*it)->first) == "long_name") - final_long_name = *((*it)->second); - else - non_long_name_partition_exists = true; - - int id = symbol_table.size(); - - symbol_table[name] = id; - type_table.push_back(type); - name_table.push_back(name); - tex_name_table.push_back(final_tex_name); - long_name_table.push_back(final_long_name); - if (non_long_name_partition_exists) - { - map pmv; - for (vector *>::const_iterator it = partition_value->begin(); - it != partition_value->end(); it++) - pmv[*((*it)->first)] = *((*it)->second); - partition_value_map[id] = pmv; - } - return id; -} - -int -SymbolTable::addSymbol(const string &name, SymbolType type) throw (AlreadyDeclaredException, FrozenException) -{ - return addSymbol(name, type, "", NULL); -} - -void -SymbolTable::freeze() throw (FrozenException) -{ - if (frozen) - throw FrozenException(); - - frozen = true; - - for (int i = 0; i < (int) symbol_table.size(); i++) - { - int tsi; - switch (getType(i)) - { - case eEndogenous: - tsi = endo_ids.size(); - endo_ids.push_back(i); - break; - case eExogenous: - tsi = exo_ids.size(); - exo_ids.push_back(i); - break; - case eExogenousDet: - tsi = exo_det_ids.size(); - exo_det_ids.push_back(i); - break; - case eParameter: - tsi = param_ids.size(); - param_ids.push_back(i); - break; - default: - tsi = -1; - break; - } - type_specific_ids.push_back(tsi); - } -} - -void -SymbolTable::unfreeze() -{ - frozen = false; - endo_ids.clear(); - exo_ids.clear(); - exo_det_ids.clear(); - param_ids.clear(); - type_specific_ids.clear(); -} - -void -SymbolTable::changeType(int id, SymbolType newtype) throw (UnknownSymbolIDException, FrozenException) -{ - if (frozen) - throw FrozenException(); - - validateSymbID(id); - - type_table[id] = newtype; -} - -int -SymbolTable::getID(SymbolType type, int tsid) const throw (UnknownTypeSpecificIDException, NotYetFrozenException) -{ - if (!frozen) - throw NotYetFrozenException(); - - switch (type) - { - case eEndogenous: - if (tsid < 0 || tsid >= (int) endo_ids.size()) - throw UnknownTypeSpecificIDException(tsid, type); - else - return endo_ids[tsid]; - case eExogenous: - if (tsid < 0 || tsid >= (int) exo_ids.size()) - throw UnknownTypeSpecificIDException(tsid, type); - else - return exo_ids[tsid]; - case eExogenousDet: - if (tsid < 0 || tsid >= (int) exo_det_ids.size()) - throw UnknownTypeSpecificIDException(tsid, type); - else - return exo_det_ids[tsid]; - case eParameter: - if (tsid < 0 || tsid >= (int) param_ids.size()) - throw UnknownTypeSpecificIDException(tsid, type); - else - return param_ids[tsid]; - default: - throw UnknownTypeSpecificIDException(tsid, type); - } -} - -map > -SymbolTable::getPartitionsForType(enum SymbolType st) const throw (UnknownSymbolIDException) -{ - map > partitions; - for (map >::const_iterator it = partition_value_map.begin(); - it != partition_value_map.end(); it++) - if (getType(it->first) == st) - for (map::const_iterator it1 = it->second.begin(); - it1 != it->second.end(); it1++) - { - if (partitions.find(it1->first) == partitions.end()) - partitions[it1->first] = map (); - partitions[it1->first][it->first] = it1->second; - } - return partitions; -} - -void -SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException) -{ - if (!frozen) - throw NotYetFrozenException(); - - if (exo_nbr() > 0) - { - output << "M_.exo_names = cell(" << exo_nbr() << ",1);" << endl; - output << "M_.exo_names_tex = cell(" << exo_nbr() << ",1);" << endl; - output << "M_.exo_names_long = cell(" << exo_nbr() << ",1);" << endl; - for (int id = 0; id < exo_nbr(); id++) - output << "M_.exo_names(" << id+1 << ") = {'" << getName(exo_ids[id]) << "'};" << endl - << "M_.exo_names_tex(" << id+1 << ") = {'" << getTeXName(exo_ids[id]) << "'};" << endl - << "M_.exo_names_long(" << id+1 << ") = {'" << getLongName(exo_ids[id]) << "'};" << endl; - map > partitions = getPartitionsForType(eExogenous); - for (map >::const_iterator it = partitions.begin(); - it != partitions.end(); it++) - if (it->first != "long_name") - { - map::const_iterator it1; - output << "M_.exo_partitions." << it->first << " = { "; - for (int id = 0; id < exo_nbr(); id++) - { - output << "'"; - it1 = it->second.find(exo_ids[id]); - if (it1 != it->second.end()) - output << it1->second; - output << "' "; - } - output << "};" << endl; - } - } - - if (exo_det_nbr() > 0) - { - output << "M_.exo_det_names = cell(" << exo_det_nbr() << ",1);" << endl; - output << "M_.exo_det_names_tex = cell(" << exo_det_nbr() << ",1);" << endl; - output << "M_.exo_det_names_long = cell(" << exo_det_nbr() << ",1);" << endl; - for (int id = 0; id < exo_det_nbr(); id++) - output << "M_.exo_det_names(" << id+1 << ") = {'" << getName(exo_det_ids[id]) << "'};" << endl - << "M_.exo_det_names_tex(" << id+1 << ") = {'" << getTeXName(exo_det_ids[id]) << "'};" << endl - << "M_.exo_det_names_long(" << id+1 << ") = {'" << getLongName(exo_det_ids[id]) << "'};" << endl; - output << "M_.exo_det_partitions = struct();" << endl; - map > partitions = getPartitionsForType(eExogenousDet); - for (map >::const_iterator it = partitions.begin(); - it != partitions.end(); it++) - if (it->first != "long_name") - { - map::const_iterator it1; - output << "M_.exo_det_partitions." << it->first << " = { "; - for (int id = 0; id < exo_det_nbr(); id++) - { - output << "'"; - it1 = it->second.find(exo_det_ids[id]); - if (it1 != it->second.end()) - output << it1->second; - output << "' "; - } - output << "};" << endl; - } - } - - if (endo_nbr() > 0) - { - output << "M_.endo_names = cell(" << endo_nbr() << ",1);" << endl; - output << "M_.endo_names_tex = cell(" << endo_nbr() << ",1);" << endl; - output << "M_.endo_names_long = cell(" << endo_nbr() << ",1);" << endl; - for (int id = 0; id < endo_nbr(); id++) - output << "M_.endo_names(" << id+1 << ") = {'" << getName(endo_ids[id]) << "'};" << endl - << "M_.endo_names_tex(" << id+1 << ") = {'" << getTeXName(endo_ids[id]) << "'};" << endl - << "M_.endo_names_long(" << id+1 << ") = {'" << getLongName(endo_ids[id]) << "'};" << endl; - output << "M_.endo_partitions = struct();" << endl; - map > partitions = getPartitionsForType(eEndogenous); - for (map >::const_iterator it = partitions.begin(); - it != partitions.end(); it++) - if (it->first != "long_name") - { - map::const_iterator it1; - output << "M_.endo_partitions." << it->first << " = { "; - for (int id = 0; id < endo_nbr(); id++) - { - output << "'"; - it1 = it->second.find(endo_ids[id]); - if (it1 != it->second.end()) - output << it1->second; - output << "' "; - } - output << "};" << endl; - } - } - - if (param_nbr() > 0) - { - output << "M_.param_names = cell(" << param_nbr() << ",1);" << endl; - output << "M_.param_names_tex = cell(" << param_nbr() << ",1);" << endl; - output << "M_.param_names_long = cell(" << param_nbr() << ",1);" << endl; - for (int id = 0; id < param_nbr(); id++) - { - output << "M_.param_names(" << id+1 << ") = {'" << getName(param_ids[id]) << "'};" << endl - << "M_.param_names_tex(" << id+1 << ") = {'" << getTeXName(param_ids[id]) << "'};" << endl - << "M_.param_names_long(" << id+1 << ") = {'" << getLongName(param_ids[id]) << "'};" << endl; - if (getName(param_ids[id]) == "dsge_prior_weight") - output << "options_.dsge_var = 1;" << endl; - } - output << "M_.param_partitions = struct();" << endl; - map > partitions = getPartitionsForType(eParameter); - for (map >::const_iterator it = partitions.begin(); - it != partitions.end(); it++) - if (it->first != "long_name") - { - map::const_iterator it1; - output << "M_.param_partitions." << it->first << " = { "; - for (int id = 0; id < param_nbr(); id++) - { - output << "'"; - it1 = it->second.find(param_ids[id]); - if (it1 != it->second.end()) - output << it1->second; - output << "' "; - } - output << "};" << endl; - } - } - - output << "M_.exo_det_nbr = " << exo_det_nbr() << ";" << endl - << "M_.exo_nbr = " << exo_nbr() << ";" << endl - << "M_.endo_nbr = " << endo_nbr() << ";" << endl - << "M_.param_nbr = " << param_nbr() << ";" << endl; - - // Write the auxiliary variable table - output << "M_.orig_endo_nbr = " << orig_endo_nbr() << ";" << endl; - if (aux_vars.size() == 0) - output << "M_.aux_vars = [];" << endl; - else - for (int i = 0; i < (int) aux_vars.size(); i++) - { - output << "M_.aux_vars(" << i+1 << ").endo_index = " << getTypeSpecificID(aux_vars[i].get_symb_id())+1 << ";" << endl - << "M_.aux_vars(" << i+1 << ").type = " << aux_vars[i].get_type() << ";" << endl; - switch (aux_vars[i].get_type()) - { - case avEndoLead: - case avExoLead: - break; - case avEndoLag: - case avExoLag: - output << "M_.aux_vars(" << i+1 << ").orig_index = " << getTypeSpecificID(aux_vars[i].get_orig_symb_id())+1 << ";" << endl - << "M_.aux_vars(" << i+1 << ").orig_lead_lag = " << aux_vars[i].get_orig_lead_lag() << ";" << endl; - break; - case avMultiplier: - output << "M_.aux_vars(" << i+1 << ").eq_nbr = " << aux_vars[i].get_equation_number_for_multiplier() + 1 << ";" << endl; - break; - case avDiffForward: - output << "M_.aux_vars(" << i+1 << ").orig_index = " << getTypeSpecificID(aux_vars[i].get_orig_symb_id())+1 << ";" << endl; - break; - case avExpectation: - output << "M_.aux_vars(" << i+1 << ").orig_expr = '\\mathbb{E}_{t" - << (aux_vars[i].get_information_set() < 0 ? "" : "+") - << aux_vars[i].get_information_set() << "}("; - aux_vars[i].get_expr_node()->writeOutput(output, oLatexDynamicModel); - output << ")';" << endl; - break; - } - } - - if (predeterminedNbr() > 0) - { - output << "M_.predetermined_variables = [ "; - for (set::const_iterator it = predetermined_variables.begin(); - it != predetermined_variables.end(); it++) - output << getTypeSpecificID(*it)+1 << " "; - output << "];" << endl; - } - - if (observedVariablesNbr() > 0) - { - int ic = 1; - output << "options_.varobs = cell(" << observedVariablesNbr() << ", 1);" << endl; - for (vector::const_iterator it = varobs.begin(); - it != varobs.end(); it++, ic++) - output << "options_.varobs(" << ic << ") = {'" << getName(*it) << "'};" << endl; - - output << "options_.varobs_id = [ "; - for (vector::const_iterator it = varobs.begin(); - it != varobs.end(); it++) - output << getTypeSpecificID(*it)+1 << " "; - output << " ];" << endl; - } -} - -void -SymbolTable::writeCOutput(ostream &output) const throw (NotYetFrozenException) -{ - if (!frozen) - throw NotYetFrozenException(); - - output << endl - << "int exo_nbr = " << exo_nbr() << ";" << endl; - if (exo_nbr() > 0) - { - output << "char *exo_names[" << exo_nbr() << "];" << endl; - for (int id = 0; id < exo_nbr(); id++) - output << "exo_names[" << id << "] = \"" << getName(exo_ids[id]) << "\";" << endl; - } - - output << endl - << "int exo_det_nbr = " << exo_det_nbr() << ";" << endl; - if (exo_det_nbr() > 0) - { - output << "char *exo_det_names[" << exo_det_nbr() << "];" << endl; - for (int id = 0; id < exo_det_nbr(); id++) - output << "exo_det_names[" << id << "] = \"" << getName(exo_det_ids[id]) << "\";" << endl; - } - - output << endl - << "int endo_nbr = " << endo_nbr() << ";" << endl; - if (endo_nbr() > 0) - { - output << "char *endo_names[" << endo_nbr() << "];" << endl; - for (int id = 0; id < endo_nbr(); id++) - output << "endo_names[" << id << "] = \"" << getName(endo_ids[id]) << "\";" << endl; - } - - output << endl - << "int param_nbr = " << param_nbr() << ";" << endl; - if (param_nbr() > 0) - { - output << "char *param_names[" << param_nbr() << "];" << endl; - for (int id = 0; id < param_nbr(); id++) - output << "param_names[" << id << "] = \"" << getName(param_ids[id]) << "\";" << endl; - } - - // Write the auxiliary variable table - output << "int aux_var_nbr = " << aux_vars.size() << ";" << endl; - if (aux_vars.size() > 0) - { - output << "struct aux_vars_t *av[" << aux_vars.size() << "];" << endl; - for (int i = 0; i < (int) aux_vars.size(); i++) - { - output << "av[" << i << "].endo_index = " << getTypeSpecificID(aux_vars[i].get_symb_id()) << ";" << endl - << "av[" << i << "].type = " << aux_vars[i].get_type() << ";" << endl; - switch (aux_vars[i].get_type()) - { - case avEndoLead: - case avExoLead: - case avExpectation: - case avMultiplier: - case avDiffForward: - break; - case avEndoLag: - case avExoLag: - output << "av[" << i << "].orig_index = " << getTypeSpecificID(aux_vars[i].get_orig_symb_id()) << ";" << endl - << "av[" << i << "].orig_lead_lag = " << aux_vars[i].get_orig_lead_lag() << ";" << endl; - break; - } - } - } - - output << "int predeterminedNbr = " << predeterminedNbr() << ";" << endl; - if (predeterminedNbr() > 0) - { - output << "int predetermined_variables[" << predeterminedNbr() << "] = {"; - for (set::const_iterator it = predetermined_variables.begin(); - it != predetermined_variables.end(); it++) - { - if (it != predetermined_variables.begin()) - output << ","; - output << getTypeSpecificID(*it); - } - output << "};" << endl; - } - - output << "int observedVariablesNbr = " << observedVariablesNbr() << ";" << endl; - if (observedVariablesNbr() > 0) - { - output << "int varobs[" << observedVariablesNbr() << "] = {"; - for (vector::const_iterator it = varobs.begin(); - it != varobs.end(); it++) - { - if (it != varobs.begin()) - output << ","; - output << getTypeSpecificID(*it); - } - output << "};" << endl; - } -} - -void -SymbolTable::writeCCOutput(ostream &output) const throw (NotYetFrozenException) -{ - if (!frozen) - throw NotYetFrozenException(); - - output << endl - << "exo_nbr = " << exo_nbr() << ";" << endl; - for (int id = 0; id < exo_nbr(); id++) - output << "exo_names[\"" << getName(exo_ids[id]) << "\"] = " << id << ";" << endl; - - output << endl - << "exo_det_nbr = " << exo_det_nbr() << ";" << endl; - for (int id = 0; id < exo_det_nbr(); id++) - output << "exo_det_names[\"" << getName(exo_det_ids[id]) << "\"] = " << id << " ;" << endl; - - output << endl - << "endo_nbr = " << endo_nbr() << ";" << endl; - for (int id = 0; id < endo_nbr(); id++) - output << "endo_names[\"" << getName(endo_ids[id]) << "\"] = " << id << ";" << endl; - - output << endl - << "param_nbr = " << param_nbr() << ";" << endl; - for (int id = 0; id < param_nbr(); id++) - output << "param_names[\"" << getName(param_ids[id]) << "\"] = " << id << ";" << endl; - - // Write the auxiliary variable table - for (int i = 0; i < (int) aux_vars.size(); i++) - { - output << "aux_vars_t av" << i << ";" << endl; - output << "av" << i << ".endo_index = " << getTypeSpecificID(aux_vars[i].get_symb_id()) << ";" << endl - << "av" << i << ".type = " << aux_vars[i].get_type() << ";" << endl; - switch (aux_vars[i].get_type()) - { - case avEndoLead: - case avExoLead: - case avExpectation: - case avMultiplier: - case avDiffForward: - break; - case avEndoLag: - case avExoLag: - output << "av" << i << ".orig_index = " << getTypeSpecificID(aux_vars[i].get_orig_symb_id()) << ";" << endl - << "av" << i << ".orig_lead_lag = " << aux_vars[i].get_orig_lead_lag() << ";" << endl; - break; - } - output << "aux_vars.push_back(" << "av" << i << ");" << endl; - } - - for (set::const_iterator it = predetermined_variables.begin(); - it != predetermined_variables.end(); it++) - output << "predetermined_variables.push_back(" << getTypeSpecificID(*it) << ");" << endl; - - for (vector::const_iterator it = varobs.begin(); - it != varobs.end(); it++) - output << "varobs.push_back(" << getTypeSpecificID(*it) << ");" << endl; -} - -int -SymbolTable::addLeadAuxiliaryVarInternal(bool endo, int index, expr_t expr_arg) throw (FrozenException) -{ - ostringstream varname; - if (endo) - varname << "AUX_ENDO_LEAD_"; - else - varname << "AUX_EXO_LEAD_"; - varname << index; - int symb_id; - try - { - symb_id = addSymbol(varname.str(), eEndogenous); - } - catch (AlreadyDeclaredException &e) - { - cerr << "ERROR: you should rename your variable called " << varname.str() << ", this name is internally used by Dynare" << endl; - exit(EXIT_FAILURE); - } - - aux_vars.push_back(AuxVarInfo(symb_id, (endo ? avEndoLead : avExoLead), 0, 0, 0, 0, expr_arg)); - - return symb_id; -} - -int -SymbolTable::addLagAuxiliaryVarInternal(bool endo, int orig_symb_id, int orig_lead_lag, expr_t expr_arg) throw (FrozenException) -{ - ostringstream varname; - if (endo) - varname << "AUX_ENDO_LAG_"; - else - varname << "AUX_EXO_LAG_"; - varname << orig_symb_id << "_" << -orig_lead_lag; - - int symb_id; - try - { - symb_id = addSymbol(varname.str(), eEndogenous); - } - catch (AlreadyDeclaredException &e) - { - cerr << "ERROR: you should rename your variable called " << varname.str() << ", this name is internally used by Dynare" << endl; - exit(EXIT_FAILURE); - } - - aux_vars.push_back(AuxVarInfo(symb_id, (endo ? avEndoLag : avExoLag), orig_symb_id, orig_lead_lag, 0, 0, expr_arg)); - - return symb_id; -} - -int -SymbolTable::addEndoLeadAuxiliaryVar(int index, expr_t expr_arg) throw (FrozenException) -{ - return addLeadAuxiliaryVarInternal(true, index, expr_arg); -} - -int -SymbolTable::addEndoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t expr_arg) throw (FrozenException) -{ - return addLagAuxiliaryVarInternal(true, orig_symb_id, orig_lead_lag, expr_arg); -} - -int -SymbolTable::addExoLeadAuxiliaryVar(int index, expr_t expr_arg) throw (FrozenException) -{ - return addLeadAuxiliaryVarInternal(false, index, expr_arg); -} - -int -SymbolTable::addExoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t expr_arg) throw (FrozenException) -{ - return addLagAuxiliaryVarInternal(false, orig_symb_id, orig_lead_lag, expr_arg); -} - -int -SymbolTable::addExpectationAuxiliaryVar(int information_set, int index, expr_t expr_arg) throw (FrozenException) -{ - ostringstream varname; - int symb_id; - - varname << "AUX_EXPECT_" << (information_set < 0 ? "LAG" : "LEAD") << "_" - << abs(information_set) << "_" << index; - - try - { - symb_id = addSymbol(varname.str(), eEndogenous); - } - catch (AlreadyDeclaredException &e) - { - cerr << "ERROR: you should rename your variable called " << varname.str() << ", this name is internally used by Dynare" << endl; - exit(EXIT_FAILURE); - } - - aux_vars.push_back(AuxVarInfo(symb_id, avExpectation, 0, 0, 0, information_set, expr_arg)); - - return symb_id; -} - -int -SymbolTable::addMultiplierAuxiliaryVar(int index) throw (FrozenException) -{ - ostringstream varname; - int symb_id; - varname << "MULT_" << index+1; - - try - { - symb_id = addSymbol(varname.str(), eEndogenous); - } - catch (AlreadyDeclaredException &e) - { - cerr << "ERROR: you should rename your variable called " << varname.str() << ", this name is internally used by Dynare" << endl; - exit(EXIT_FAILURE); - } - - aux_vars.push_back(AuxVarInfo(symb_id, avMultiplier, 0, 0, index, 0, NULL)); - return symb_id; -} - -int -SymbolTable::addDiffForwardAuxiliaryVar(int orig_symb_id, expr_t expr_arg) throw (FrozenException) -{ - ostringstream varname; - int symb_id; - varname << "AUX_DIFF_FWRD_" << orig_symb_id+1; - - try - { - symb_id = addSymbol(varname.str(), eEndogenous); - } - catch (AlreadyDeclaredException &e) - { - cerr << "ERROR: you should rename your variable called " << varname.str() << ", this name is internally used by Dynare" << endl; - exit(EXIT_FAILURE); - } - - aux_vars.push_back(AuxVarInfo(symb_id, avDiffForward, orig_symb_id, 0, 0, 0, expr_arg)); - return symb_id; -} - -int -SymbolTable::searchAuxiliaryVars(int orig_symb_id, int orig_lead_lag) const throw (SearchFailedException) -{ - for (size_t i = 0; i < aux_vars.size(); i++) - if ((aux_vars[i].get_type() == avEndoLag || aux_vars[i].get_type() == avExoLag) - && aux_vars[i].get_orig_symb_id() == orig_symb_id && aux_vars[i].get_orig_lead_lag() == orig_lead_lag) - return aux_vars[i].get_symb_id(); - throw SearchFailedException(orig_symb_id, orig_lead_lag); -} - -expr_t -SymbolTable::getAuxiliaryVarsExprNode(int symb_id) const throw (SearchFailedException) -// throw exception if it is a Lagrange multiplier -{ - for (size_t i = 0; i < aux_vars.size(); i++) - if (aux_vars[i].get_symb_id() == symb_id) - { - expr_t expr_node = aux_vars[i].get_expr_node(); - if (expr_node != NULL) - return expr_node; - else - throw SearchFailedException(symb_id); - } - throw SearchFailedException(symb_id); -} - -void -SymbolTable::markPredetermined(int symb_id) throw (UnknownSymbolIDException, FrozenException) -{ - validateSymbID(symb_id); - - if (frozen) - throw FrozenException(); - - assert(getType(symb_id) == eEndogenous); - - predetermined_variables.insert(symb_id); -} - -bool -SymbolTable::isPredetermined(int symb_id) const throw (UnknownSymbolIDException) -{ - validateSymbID(symb_id); - return (predetermined_variables.find(symb_id) != predetermined_variables.end()); -} - -int -SymbolTable::predeterminedNbr() const -{ - return (predetermined_variables.size()); -} - -void -SymbolTable::addObservedVariable(int symb_id) throw (UnknownSymbolIDException) -{ - validateSymbID(symb_id); - assert(getType(symb_id) == eEndogenous); - varobs.push_back(symb_id); -} - -int -SymbolTable::observedVariablesNbr() const -{ - return (int) varobs.size(); -} - -bool -SymbolTable::isObservedVariable(int symb_id) const -{ - return (find(varobs.begin(), varobs.end(), symb_id) != varobs.end()); -} - -int -SymbolTable::getObservedVariableIndex(int symb_id) const -{ - vector::const_iterator it = find(varobs.begin(), varobs.end(), symb_id); - assert(it != varobs.end()); - return (int) (it - varobs.begin()); -} - -vector -SymbolTable::getTrendVarIds() const -{ - vector trendVars; - for (symbol_table_type::const_iterator it = symbol_table.begin(); - it != symbol_table.end(); it++) - if (getType(it->second) == eTrend || getType(it->second) == eLogTrend) - trendVars.push_back(it->second); - return trendVars; -} - -set -SymbolTable::getExogenous() const -{ - set exogs; - for (symbol_table_type::const_iterator it = symbol_table.begin(); - it != symbol_table.end(); it++) - if (getType(it->second) == eExogenous) - exogs.insert(it->second); - return exogs; -} - -set -SymbolTable::getEndogenous() const -{ - set endogs; - for (symbol_table_type::const_iterator it = symbol_table.begin(); - it != symbol_table.end(); it++) - if (getType(it->second) == eEndogenous) - endogs.insert(it->second); - return endogs; -} - -bool -SymbolTable::isAuxiliaryVariable(int symb_id) const -{ - for (int i = 0; i < (int) aux_vars.size(); i++) - if (aux_vars[i].get_symb_id() == symb_id) - return true; - return false; -} - -bool -SymbolTable::isAuxiliaryVariableButNotMultiplier(int symb_id) const -{ - for (int i = 0; i < (int) aux_vars.size(); i++) - if (aux_vars[i].get_symb_id() == symb_id && aux_vars[i].get_type() != avMultiplier) - return true; - return false; -} - -set -SymbolTable::getOrigEndogenous() const -{ - set origendogs; - for (symbol_table_type::const_iterator it = symbol_table.begin(); - it != symbol_table.end(); it++) - if (getType(it->second) == eEndogenous && !isAuxiliaryVariable(it->second)) - origendogs.insert(it->second); - return origendogs; -} - -void -SymbolTable::writeJuliaOutput(ostream &output) const throw (NotYetFrozenException) -{ - if (!frozen) - throw NotYetFrozenException(); - - output << "# Endogenous Variables" << endl - << "model_.endo = [" << endl; - if (endo_nbr() > 0) - for (int id = 0; id < endo_nbr(); id++) - output << " DynareModel.Endo(\"" - << getName(endo_ids[id]) << "\", \"" - << getTeXName(endo_ids[id]) << "\", \"" - << getLongName(endo_ids[id]) << "\")" << endl; - output << " ]" << endl; - - output << "# Exogenous Variables" << endl - << "model_.exo = [" << endl; - if (exo_nbr() > 0) - for (int id = 0; id < exo_nbr(); id++) - output << " DynareModel.Exo(\"" - << getName(exo_ids[id]) << "\", \"" - << getTeXName(exo_ids[id]) << "\", \"" - << getLongName(exo_ids[id]) << "\")" << endl; - output << " ]" << endl; - - if (exo_det_nbr() > 0) - { - output << "# Exogenous Deterministic Variables" << endl - << "model_.exo_det = [" << endl; - if (exo_det_nbr() > 0) - for (int id = 0; id < exo_det_nbr(); id++) - output << " DynareModel.ExoDet(\"" - << getName(exo_det_ids[id]) << "\", \"" - << getTeXName(exo_det_ids[id]) << "\", \"" - << getLongName(exo_det_ids[id]) << "\")" << endl; - output << " ]" << endl; - } - - output << "# Parameters" << endl - << "model_.param = [" << endl; - if (param_nbr() > 0) - for (int id = 0; id < param_nbr(); id++) - output << " DynareModel.Param(\"" - << getName(param_ids[id]) << "\", \"" - << getTeXName(param_ids[id]) << "\", \"" - << getLongName(param_ids[id]) << "\")" << endl; - output << " ]" << endl; - - output << "model_.orig_endo_nbr = " << orig_endo_nbr() << endl; - - if (aux_vars.size() > 0) - { - output << "# Auxiliary Variables" << endl - << "model_.aux_vars = [" << endl; - for (int i = 0; i < (int) aux_vars.size(); i++) - { - output << " DynareModel.AuxVars(" - << getTypeSpecificID(aux_vars[i].get_symb_id()) + 1 << ", " - << aux_vars[i].get_type() << ", "; - switch (aux_vars[i].get_type()) - { - case avEndoLead: - case avExoLead: - break; - case avEndoLag: - case avExoLag: - output << getTypeSpecificID(aux_vars[i].get_orig_symb_id()) + 1 << ", " - << aux_vars[i].get_orig_lead_lag() << ", NaN, NaN"; - break; - case avMultiplier: - output << "NaN, NaN, " << aux_vars[i].get_equation_number_for_multiplier() + 1 - << ", NaN"; - break; - case avDiffForward: - output << getTypeSpecificID(aux_vars[i].get_orig_symb_id())+1 << ", NaN, "; - break; - case avExpectation: - output << "NaN, NaN, NaN, \"\\mathbb{E}_{t" - << (aux_vars[i].get_information_set() < 0 ? "" : "+") - << aux_vars[i].get_information_set() << "}("; - aux_vars[i].get_expr_node()->writeOutput(output, oLatexDynamicModel); - output << ")\""; - break; - } - output << ")" << endl; - } - output << "]" << endl; - } - - if (predeterminedNbr() > 0) - { - output << "# Predetermined Variables" << endl - << "model_.pred_vars = [ " << endl; - for (set::const_iterator it = predetermined_variables.begin(); - it != predetermined_variables.end(); it++) - output << " DynareModel.PredVars(" - << getTypeSpecificID(*it)+1 << ")" << endl; - output << " ]" << endl; - } - - if (observedVariablesNbr() > 0) - { - output << "# Observed Variables" << endl - << "options_.obs_vars = [" << endl; - for (vector::const_iterator it = varobs.begin(); - it != varobs.end(); it++) - output << " DynareModel.ObsVars(" - << getTypeSpecificID(*it)+1 << ")" << endl; - output << " ]" << endl; - } -} - -void -SymbolTable::writeJsonOutput(ostream &output) const -{ - output << "\"endogenous\": "; - writeJsonVarVector(output, endo_ids); - - output << ", \"exogenous\":"; - writeJsonVarVector(output, exo_ids); - - output << ", \"exogenous_deterministic\": "; - writeJsonVarVector(output, exo_det_ids); - - output << ", \"parameters\": "; - writeJsonVarVector(output, param_ids); -} - -void -SymbolTable::writeJsonVarVector(ostream &output, const vector &varvec) const -{ - output << "["; - for (size_t i = 0; i < varvec.size(); i++) - { - if (i != 0) - output << ", "; - output << "{" - << "\"name\":\"" << getName(varvec[i]) << "\", " - << "\"texName\":\"" << boost::replace_all_copy(getTeXName(varvec[i]), "\\", "\\\\") << "\", " - << "\"longName\":\"" << boost::replace_all_copy(getLongName(varvec[i]), "\\", "\\\\") << "\"}" - << endl; - } - output << "]" << endl; -} diff --git a/preprocessor/SymbolTable.hh b/preprocessor/SymbolTable.hh deleted file mode 100644 index b27892bde..000000000 --- a/preprocessor/SymbolTable.hh +++ /dev/null @@ -1,490 +0,0 @@ -/* - * Copyright (C) 2003-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 . - */ - -#ifndef _SYMBOLTABLE_HH -#define _SYMBOLTABLE_HH - -using namespace std; - -#include -#include -#include -#include -#include - -#include "CodeInterpreter.hh" -#include "ExprNode.hh" - -typedef class ExprNode *expr_t; - -//! Types of auxiliary variables -enum aux_var_t - { - avEndoLead = 0, //!< Substitute for endo leads >= 2 - avEndoLag = 1, //!< Substitute for endo lags >= 2 - avExoLead = 2, //!< Substitute for exo leads >= 2 - avExoLag = 3, //!< Substitute for exo lags >= 2 - avExpectation = 4, //!< Substitute for Expectation Operator - avDiffForward = 5, //!< Substitute for the differentiate of a forward variable - avMultiplier = 6 //!< Multipliers for FOC of Ramsey Problem - }; - -//! Information on some auxiliary variables -class AuxVarInfo -{ -private: - int symb_id; //!< Symbol ID of the auxiliary variable - aux_var_t type; //!< Its type - int orig_symb_id; //!< Symbol ID of the endo of the original model represented by this aux var. Only used for avEndoLag and avExoLag. - int orig_lead_lag; //!< Lead/lag of the endo of the original model represented by this aux var. Only used for avEndoLag and avExoLag. - int equation_number_for_multiplier; //!< Stores the original constraint equation number associated with this aux var. Only used for avMultiplier. - int information_set; //! Argument of expectation operator. Only used for avExpectation. - expr_t expr_node; //! Auxiliary variable definition -public: - AuxVarInfo(int symb_id_arg, aux_var_t type_arg, int orig_symb_id, int orig_lead_lag, int equation_number_for_multiplier_arg, int information_set_arg, expr_t expr_node_arg); - int - get_symb_id() const - { - return symb_id; - }; - aux_var_t - get_type() const - { - return type; - }; - int - get_orig_symb_id() const - { - return orig_symb_id; - }; - int - get_orig_lead_lag() const - { - return orig_lead_lag; - }; - int - get_equation_number_for_multiplier() const - { - return equation_number_for_multiplier; - }; - int - get_information_set() const - { - return information_set; - }; - expr_t - get_expr_node() const - { - return expr_node; - }; -}; - -//! Stores the symbol table -/*! - A symbol is given by its name, and is internally represented by a unique integer. - - When method freeze() is called, computes a distinct sequence of IDs for some types - (endogenous, exogenous, parameters), which are used by the Matlab/Octave functions. - We call these "type specific IDs". - - Also manages a TeX name for each symbol, which by default is an empty string. -*/ -class SymbolTable -{ -private: - //! Has method freeze() been called? - bool frozen; - - typedef map symbol_table_type; - //! Maps strings to symbol IDs - symbol_table_type symbol_table; - - //! Maps IDs to names - vector name_table; - //! Maps IDs to TeX names - vector tex_name_table; - //! Maps IDs to string names of variables - vector long_name_table; - //! Maps IDs to a pair containing the partition and the partition value - map > partition_value_map; - //! Maps IDs to types - vector type_table; - - //! Maps symbol IDs to type specific IDs - vector type_specific_ids; - - //! Maps type specific IDs of endogenous to symbol IDs - vector endo_ids; - //! Maps type specific IDs of exogenous to symbol IDs - vector exo_ids; - //! Maps type specific IDs of exogenous deterministic to symbol IDs - vector exo_det_ids; - //! Maps type specific IDs of parameters to symbol IDs - vector param_ids; - //! Information about auxiliary variables - vector aux_vars; - - //! Stores the predetermined variables (by symbol IDs) - set predetermined_variables; - - //! Stores the list of observed variables - vector varobs; - -public: - SymbolTable(); - //! Thrown when trying to access an unknown symbol (by name) - class UnknownSymbolNameException - { - public: - //! Symbol name - string name; - UnknownSymbolNameException(const string &name_arg) : name(name_arg) - { - } - }; - //! Thrown when trying to access an unknown symbol (by id) - class UnknownSymbolIDException - { - public: - //! Symbol ID - int id; - UnknownSymbolIDException(int id_arg) : id(id_arg) - { - } - }; - //! Thrown when trying to access an unknown type specific ID - class UnknownTypeSpecificIDException - { - public: - int tsid; - SymbolType type; - UnknownTypeSpecificIDException(int tsid_arg, SymbolType type_arg) : tsid(tsid_arg), type(type_arg) - { - } - }; - //! Thrown when trying to declare a symbol twice - class AlreadyDeclaredException - { - public: - //! Symbol name - string name; - //! Was the previous declaration done with the same symbol type ? - bool same_type; - AlreadyDeclaredException(const string &name_arg, bool same_type_arg) : name(name_arg), same_type(same_type_arg) - { - } - }; - //! Thrown when table is frozen and trying to modify it - class FrozenException - { - }; - //! Thrown when trying to use the result of freeze() while this method has not yet been called - class NotYetFrozenException - { - }; - //! Thrown when searchAuxiliaryVars() failed - class SearchFailedException - { - public: - int orig_symb_id, orig_lead_lag, symb_id; - SearchFailedException(int orig_symb_id_arg, int orig_lead_lag_arg) : orig_symb_id(orig_symb_id_arg), - orig_lead_lag(orig_lead_lag_arg) - { - } - SearchFailedException(int symb_id_arg) : symb_id(symb_id_arg) - { - } - }; - -private: - //! Factorized code for adding aux lag variables - int addLagAuxiliaryVarInternal(bool endo, int orig_symb_id, int orig_lead_lag, expr_t arg) throw (FrozenException); - //! Factorized code for adding aux lead variables - int addLeadAuxiliaryVarInternal(bool endo, int index, expr_t arg) throw (FrozenException); - //! Factorized code for Json writing - void writeJsonVarVector(ostream &output, const vector &varvec) const; - //! Factorized code for asserting that 0 <= symb_id <= symbol_table.size() - inline void validateSymbID(int symb_id) const throw (UnknownSymbolIDException); -public: - //! Add a symbol - /*! Returns the symbol ID */ - int addSymbol(const string &name, SymbolType type, const string &tex_name, const vector *> *partition_value) throw (AlreadyDeclaredException, FrozenException); - //! Add a symbol without its TeX name (will be equal to its name) - /*! Returns the symbol ID */ - int addSymbol(const string &name, SymbolType type) throw (AlreadyDeclaredException, FrozenException); - //! Adds an auxiliary variable for endogenous with lead >= 2 - /*! - \param[in] index Used to construct the variable name - \return the symbol ID of the new symbol */ - int addEndoLeadAuxiliaryVar(int index, expr_t arg) throw (FrozenException); - //! Adds an auxiliary variable for endogenous with lag >= 2 - /*! - \param[in] orig_symb_id symbol ID of the endogenous declared by the user that this new variable will represent - \param[in] orig_lead_lag lag value such that this new variable will be equivalent to orig_symb_id(orig_lead_lag) - \return the symbol ID of the new symbol */ - int addEndoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t arg) throw (FrozenException); - //! Adds an auxiliary variable for endogenous with lead >= 1 - /*! - \param[in] index Used to construct the variable name - \return the symbol ID of the new symbol */ - int addExoLeadAuxiliaryVar(int index, expr_t arg) throw (FrozenException); - //! Adds an auxiliary variable for exogenous with lag >= 1 - /*! - \param[in] orig_symb_id symbol ID of the exogenous declared by the user that this new variable will represent - \param[in] orig_lead_lag lag value such that this new variable will be equivalent to orig_symb_id(orig_lead_lag) - \return the symbol ID of the new symbol */ - int addExoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t arg) throw (FrozenException); - //! Adds an auxiliary variable for the expectation operator - /*! - \param[in] information_set information set (possibly negative) of the expectation operator - \param[in] index Used to construct the variable name - \return the symbol ID of the new symbol - */ - int addExpectationAuxiliaryVar(int information_set, int index, expr_t arg) throw (FrozenException); - //! Adds an auxiliary variable for the multiplier for the FOCs of the Ramsey Problem - /*! - \param[in] index Used to construct the variable name - \return the symbol ID of the new symbol - */ - int addMultiplierAuxiliaryVar(int index) throw (FrozenException); - //! Adds an auxiliary variable for the (time) differentiate of a forward var - /*! - \param[in] orig_symb_id The symb_id of the forward variable - \return the symbol ID of the new symbol - */ - int addDiffForwardAuxiliaryVar(int orig_symb_id, expr_t arg) throw (FrozenException); - //! Searches auxiliary variables which are substitutes for a given symbol_id and lead/lag - /*! - The search is only performed among auxiliary variables of endo/exo lag. - \return the symbol ID of the auxiliary variable - Throws an exception if match not found. - */ - int searchAuxiliaryVars(int orig_symb_id, int orig_lead_lag) const throw (SearchFailedException); - //! Returns the number of auxiliary variables - int - AuxVarsSize() const - { - return aux_vars.size(); - }; - //! Retruns expr_node for an auxiliary variable - expr_t getAuxiliaryVarsExprNode(int symb_id) const throw (SearchFailedException); - //! Tests if symbol already exists - inline bool exists(const string &name) const; - //! Get symbol name (by ID) - inline string getName(int id) const throw (UnknownSymbolIDException); - //! Get TeX name - inline string getTeXName(int id) const throw (UnknownSymbolIDException); - //! Get long name - inline string getLongName(int id) const throw (UnknownSymbolIDException); - //! Returns true if the partition name is the first encountered for the type of variable represented by id - bool isFirstOfPartitionForType(int id) const throw (UnknownSymbolIDException); - //! Returns a list of partitions and symbols that belong to that partition - map > getPartitionsForType(enum SymbolType st) const throw (UnknownSymbolIDException); - //! Get type (by ID) - inline SymbolType getType(int id) const throw (UnknownSymbolIDException); - //! Get type (by name) - inline SymbolType getType(const string &name) const throw (UnknownSymbolNameException); - //! Get ID (by name) - inline int getID(const string &name) const throw (UnknownSymbolNameException); - //! Get ID (by type specific ID) - int getID(SymbolType type, int tsid) const throw (UnknownTypeSpecificIDException, NotYetFrozenException); - //! Freeze symbol table - void freeze() throw (FrozenException); - //! unreeze symbol table - //! Used after having written JSON files - void unfreeze(); - //! Change the type of a symbol - void changeType(int id, SymbolType newtype) throw (UnknownSymbolIDException, FrozenException); - //! Get type specific ID (by symbol ID) - inline int getTypeSpecificID(int id) const throw (UnknownSymbolIDException, NotYetFrozenException); - //! Get type specific ID (by symbol name) - inline int getTypeSpecificID(const string &name) const throw (UnknownSymbolNameException, NotYetFrozenException); - //! Get number of endogenous variables - inline int endo_nbr() const throw (NotYetFrozenException); - //! Get number of exogenous variables - inline int exo_nbr() const throw (NotYetFrozenException); - //! Get number of exogenous deterministic variables - inline int exo_det_nbr() const throw (NotYetFrozenException); - //! Get number of parameters - inline int param_nbr() const throw (NotYetFrozenException); - //! Returns the greatest symbol ID (the smallest is zero) - inline int maxID(); - //! Get number of user-declared endogenous variables (without the auxiliary variables) - inline int orig_endo_nbr() const throw (NotYetFrozenException); - //! Write output of this class - void writeOutput(ostream &output) const throw (NotYetFrozenException); - //! Write JSON Output - void writeJsonOutput(ostream &output) const; - //! Write Julia output of this class - void writeJuliaOutput(ostream &output) const throw (NotYetFrozenException); - //! Write C output of this class - void writeCOutput(ostream &output) const throw (NotYetFrozenException); - //! Write CC output of this class - void writeCCOutput(ostream &output) const throw (NotYetFrozenException); - //! Mark a symbol as predetermined variable - void markPredetermined(int symb_id) throw (UnknownSymbolIDException, FrozenException); - //! Test if a given symbol is a predetermined variable - bool isPredetermined(int symb_id) const throw (UnknownSymbolIDException); - //! Return the number of predetermined variables - int predeterminedNbr() const; - //! Add an observed variable - void addObservedVariable(int symb_id) throw (UnknownSymbolIDException); - //! Return the number of observed variables - int observedVariablesNbr() const; - //! Is a given symbol in the set of observed variables - bool isObservedVariable(int symb_id) const; - //! Return the index of a given observed variable in the vector of all observed variables - int getObservedVariableIndex(int symb_id) const; - vector getTrendVarIds() const; - //! Get list of exogenous variables - set getExogenous() const; - //! Get list of endogenous variables - set getEndogenous() const; - //! Is a given symbol an auxiliary variable - bool isAuxiliaryVariable(int symb_id) const; - //! Is a given symbol an auxiliary variable but not a Lagrange multiplier - bool isAuxiliaryVariableButNotMultiplier(int symb_id) const; - //! Get list of endogenous variables without aux vars - set getOrigEndogenous() const; -}; - -inline void -SymbolTable::validateSymbID(int symb_id) const throw (UnknownSymbolIDException) -{ - if (symb_id < 0 || symb_id > (int) symbol_table.size()) - throw UnknownSymbolIDException(symb_id); -} - -inline bool -SymbolTable::exists(const string &name) const -{ - symbol_table_type::const_iterator iter = symbol_table.find(name); - return (iter != symbol_table.end()); -} - -inline string -SymbolTable::getName(int id) const throw (UnknownSymbolIDException) -{ - validateSymbID(id); - return name_table[id]; -} - -inline string -SymbolTable::getTeXName(int id) const throw (UnknownSymbolIDException) -{ - validateSymbID(id); - return tex_name_table[id]; -} - -inline string -SymbolTable::getLongName(int id) const throw (UnknownSymbolIDException) -{ - validateSymbID(id); - return long_name_table[id]; -} - -inline SymbolType -SymbolTable::getType(int id) const throw (UnknownSymbolIDException) -{ - validateSymbID(id); - return type_table[id]; -} - -inline SymbolType -SymbolTable::getType(const string &name) const throw (UnknownSymbolNameException) -{ - return getType(getID(name)); -} - -inline int -SymbolTable::getID(const string &name) const throw (UnknownSymbolNameException) -{ - symbol_table_type::const_iterator iter = symbol_table.find(name); - if (iter != symbol_table.end()) - return iter->second; - else - throw UnknownSymbolNameException(name); -} - -inline int -SymbolTable::getTypeSpecificID(int id) const throw (UnknownSymbolIDException, NotYetFrozenException) -{ - if (!frozen) - throw NotYetFrozenException(); - - validateSymbID(id); - - return type_specific_ids[id]; -} - -inline int -SymbolTable::getTypeSpecificID(const string &name) const throw (UnknownSymbolNameException, NotYetFrozenException) -{ - return getTypeSpecificID(getID(name)); -} - -inline int -SymbolTable::endo_nbr() const throw (NotYetFrozenException) -{ - if (!frozen) - throw NotYetFrozenException(); - - return endo_ids.size(); -} - -inline int -SymbolTable::exo_nbr() const throw (NotYetFrozenException) -{ - if (!frozen) - throw NotYetFrozenException(); - - return exo_ids.size(); -} - -inline int -SymbolTable::exo_det_nbr() const throw (NotYetFrozenException) -{ - if (!frozen) - throw NotYetFrozenException(); - - return exo_det_ids.size(); -} - -inline int -SymbolTable::param_nbr() const throw (NotYetFrozenException) -{ - if (!frozen) - throw NotYetFrozenException(); - - return param_ids.size(); -} - -inline int -SymbolTable::maxID() -{ - return symbol_table.size() - 1; -} - -inline int -SymbolTable::orig_endo_nbr() const throw (NotYetFrozenException) -{ - return (endo_nbr() - aux_vars.size()); -} - -#endif diff --git a/preprocessor/WarningConsolidation.cc b/preprocessor/WarningConsolidation.cc deleted file mode 100644 index f1c24f4ad..000000000 --- a/preprocessor/WarningConsolidation.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2012-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 . - */ - -#include "WarningConsolidation.hh" -#include - -WarningConsolidation -& -operator<<(WarningConsolidation &wcc, const string &warning) -{ - if (wcc.no_warn) - return wcc; - - cerr << warning; - wcc.addWarning(warning); - return wcc; -}; - -WarningConsolidation & -operator<<(WarningConsolidation &wcc, const Dynare::location &loc) -{ - if (wcc.no_warn) - return wcc; - - stringstream ostr; - Dynare::position last = loc.end - 1; - ostr << loc.begin; - if (last.filename - && (!loc.begin.filename - || *loc.begin.filename != *last.filename)) - ostr << '-' << last; - else if (loc.begin.line != last.line) - ostr << '-' << last.line << '.' << last.column; - else if (loc.begin.column != last.column) - ostr << '-' << last.column; - - cerr << ostr.str(); - wcc.addWarning(ostr.str()); - return wcc; -}; - -WarningConsolidation & -operator<<(WarningConsolidation &wcc, ostream & (*pf)(ostream &)) -{ - if (wcc.no_warn) - return wcc; - - cerr << pf; - wcc.addWarning(pf); - return wcc; -} - -void -WarningConsolidation::writeOutput(ostream &output) const -{ - if (warnings.str().empty()) - return; - - output << "disp([char(10) 'Dynare Preprocessor Warning(s) Encountered:']);" << endl; - - bool writedisp = true; - string warningsstr = warnings.str(); - for (size_t i = 0; i < warningsstr.length(); i++) - { - if (writedisp) - { - output << "disp(' "; - writedisp = false; - } - - if (warningsstr[i] != '\n') - output << warningsstr[i]; - else - { - output << "');" << endl; - if (i+1 < warningsstr.length()) - writedisp = true; - } - } -} - -int -WarningConsolidation::countWarnings() const -{ - size_t p = 0; - int n = 0; - while ((p = warnings.str().find('\n', p)) != string::npos) - { - p++; - n++; - } - return n; -} diff --git a/preprocessor/WarningConsolidation.hh b/preprocessor/WarningConsolidation.hh deleted file mode 100644 index ece47995e..000000000 --- a/preprocessor/WarningConsolidation.hh +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2012-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 . - */ - -#ifndef _WARNINGCONSOLIDATION_HH -#define _WARNINGCONSOLIDATION_HH - -#include -#include -#include "location.hh" - -using namespace std; - -//! Stores Warnings issued by the Preprocessor -class WarningConsolidation -{ -private: - stringstream warnings; - bool no_warn; - -public: - WarningConsolidation(bool no_warn_arg) : no_warn(no_warn_arg) - { - }; - ~WarningConsolidation() - { - }; - - //! Add A Warning to the StringStream - friend WarningConsolidation &operator<<(WarningConsolidation &wcc, const string &warning); - friend WarningConsolidation &operator<<(WarningConsolidation &wcc, const Dynare::location &loc); - friend WarningConsolidation &operator<<(WarningConsolidation &wcc, ostream & (*pf)(ostream &)); - - inline void - addWarning(const string &w) - { - warnings << w; - }; - inline void - addWarning(ostream & (*pf)(ostream &)) - { - warnings << pf; - }; - - //! Write Warnings to m file - void writeOutput(ostream &output) const; - //! Count warnings - /*! This is done in a very lousy way, by counting newlines in the - stringstream... */ - int countWarnings() const; -}; - -#endif diff --git a/preprocessor/macro/MacroBison.yy b/preprocessor/macro/MacroBison.yy deleted file mode 100644 index a2523356c..000000000 --- a/preprocessor/macro/MacroBison.yy +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (C) 2008-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 . - */ - -%skeleton "lalr1.cc" -%require "2.5" -%defines - -%code top { -class MacroDriver; -} - -%name-prefix "Macro" - -%parse-param { MacroDriver &driver } -%parse-param { ostream &out } -%lex-param { MacroDriver &driver } - -%locations -%initial-action -{ - // Initialize the location filenames - @$.begin.filename = @$.end.filename = &driver.file; -}; - -%debug -%error-verbose - -%code requires { -#include "MacroValue.hh" -} - -%union -{ - string *string_val; - int int_val; - const MacroValue *mv; -}; - -%code { -#include // Pour atoi() -#include "MacroDriver.hh" - -/* this "connects" the bison parser in the driver to the flex scanner class - * object. it defines the yylex() function call to pull the next token from the - * current lexer object of the driver context. */ -#undef yylex -#define yylex driver.lexer->lex - -#define TYPERR_CATCH(statement, loc) try \ - { \ - statement; \ - } \ - catch(MacroValue::TypeError &e) \ - { \ - driver.error(loc, e.message); \ - } - -} - -%token DEFINE LINE FOR IN IF ELSE ENDIF ECHO_DIR ERROR IFDEF IFNDEF -%token LPAREN RPAREN LBRACKET RBRACKET EQUAL EOL LENGTH ECHOMACROVARS SAVE - -%token INTEGER -%token NAME STRING - -%left COMMA -%left LOGICAL_OR -%left LOGICAL_AND -%left LESS GREATER LESS_EQUAL GREATER_EQUAL EQUAL_EQUAL EXCLAMATION_EQUAL -%nonassoc IN -%nonassoc COLON -%left PLUS MINUS -%left TIMES DIVIDE -%left UMINUS UPLUS EXCLAMATION -%left LBRACKET - -%type expr array_expr -%% - -%start statement_list_or_nothing; - -statement_list_or_nothing : /* empty */ - | statement_list - ; - -statement_list : statement EOL - | statement_list statement EOL - ; - -statement : expr - { out << $1->toString(); } - | DEFINE NAME EQUAL expr - { driver.set_variable(*$2, $4); delete $2; } - | FOR NAME IN expr - { TYPERR_CATCH(driver.init_loop(*$2, $4), @$); delete $2; } - | IF expr - { TYPERR_CATCH(driver.begin_if($2), @$); } - | IFDEF NAME - { TYPERR_CATCH(driver.begin_ifdef(*$2), @$); delete $2; } - | IFNDEF NAME - { TYPERR_CATCH(driver.begin_ifndef(*$2), @$); delete $2; } - | ECHO_DIR expr - { TYPERR_CATCH(driver.echo(@$, $2), @$); } - | ERROR expr - { TYPERR_CATCH(driver.error(@$, $2), @$); } - | LINE STRING INTEGER - /* Ignore @#line declarations */ - | ECHOMACROVARS - { driver.printvars(@$, true); } - | ECHOMACROVARS LPAREN SAVE RPAREN - { out << driver.printvars(@$, false); } - ; - -expr : INTEGER - { $$ = new IntMV(driver, $1); } - | STRING - { $$ = new StringMV(driver, *$1); delete $1; } - | NAME - { - try - { - $$ = driver.get_variable(*$1); - } - catch(MacroDriver::UnknownVariable(&e)) - { - error(@$, "Unknown variable: " + e.name); - } - delete $1; - } - | LENGTH LPAREN array_expr RPAREN - { TYPERR_CATCH($$ = $3->length(), @$); } - | LPAREN expr RPAREN - { $$ = $2; } - | expr PLUS expr - { TYPERR_CATCH($$ = *$1 + *$3, @$); } - | expr MINUS expr - { TYPERR_CATCH($$ = *$1 - *$3, @$); } - | expr TIMES expr - { TYPERR_CATCH($$ = *$1 * *$3, @$); } - | expr DIVIDE expr - { - if (dynamic_cast($3) != NULL - && ((IntMV *)$3)->get_int_value() == 0) - driver.error(@$, "Division by zero"); - TYPERR_CATCH($$ = *$1 / *$3, @$); - } - | expr LESS expr - { TYPERR_CATCH($$ = *$1 < *$3, @$); } - | expr GREATER expr - { TYPERR_CATCH($$ = *$1 > *$3, @$); } - | expr LESS_EQUAL expr - { TYPERR_CATCH($$ = *$1 <= *$3, @$); } - | expr GREATER_EQUAL expr - { TYPERR_CATCH($$ = *$1 >= *$3, @$); } - | expr EQUAL_EQUAL expr - { TYPERR_CATCH($$ = *$1 == *$3, @$); } - | expr EXCLAMATION_EQUAL expr - { TYPERR_CATCH($$ = *$1 != *$3, @$); } - | expr LOGICAL_OR expr - { TYPERR_CATCH($$ = *$1 || *$3, @$); } - | expr LOGICAL_AND expr - { TYPERR_CATCH($$ = *$1 && *$3, @$); } - | MINUS expr %prec UMINUS - { TYPERR_CATCH($$ = -*$2, @$); } - | PLUS expr %prec UPLUS - { TYPERR_CATCH($$ = +(*$2), @$); } - | EXCLAMATION expr - { TYPERR_CATCH($$ = !*$2, @$); } - | expr LBRACKET array_expr RBRACKET - { - TYPERR_CATCH($$ = (*$1)[*$3], @$) - catch(MacroValue::OutOfBoundsError) - { - error(@$, "Index out of bounds"); - } - } - | LBRACKET array_expr RBRACKET - { $$ = $2; } - | expr COLON expr - { TYPERR_CATCH($$ = IntMV::new_range(driver, $1, $3), @$); } - | expr IN expr - { TYPERR_CATCH($$ = $1->in($3), @$); } - ; - -array_expr : expr - { $$ = $1->toArray(); } - | array_expr COMMA expr - { TYPERR_CATCH($$ = $3->append($1), @$); } - ; - -%% - -void -Macro::parser::error(const Macro::parser::location_type &l, - const string &m) -{ - driver.error(l, m); -} diff --git a/preprocessor/macro/MacroDriver.cc b/preprocessor/macro/MacroDriver.cc deleted file mode 100644 index b0420b441..000000000 --- a/preprocessor/macro/MacroDriver.cc +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (C) 2008-2018 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 . - */ - -#include -#include -#include -#include -#include - -#include "MacroDriver.hh" - -MacroDriver::MacroDriver() -{ -} - -MacroDriver::~MacroDriver() -{ - for (set::iterator it = values.begin(); - it != values.end(); it++) - delete *it; -} - -void -MacroDriver::parse(const string &f, const string &fb, const string &modfiletxt, - ostream &out, bool debug, bool no_line_macro_arg, map defines, - vector path) -{ - file = f; - basename = fb; - no_line_macro = no_line_macro_arg; - - /* - Copy the file into a stringstream, and add an extra end-of-line. This is a - workaround for trac ticket #73: with this workaround, MOD files ending with - an @#endif or an @#endfor - but no newline - no longer trigger an error. - */ - stringstream file_with_endl; - for (map::iterator it = defines.begin(); - it != defines.end(); it++) - try - { - boost::lexical_cast(it->second); - file_with_endl << "@#define " << it->first << " = " << it->second << endl; - } - catch (boost::bad_lexical_cast &) - { - if (!it->second.empty() && it->second.at(0) == '[' && it->second.at(it->second.length()-1) == ']') - // If the input is an array. Issue #1578 - file_with_endl << "@#define " << it->first << " = " << it->second << endl; - else - file_with_endl << "@#define " << it->first << " = \"" << it->second << "\"" << endl; - } - file_with_endl << modfiletxt << endl; - - lexer = new MacroFlex(&file_with_endl, &out, no_line_macro, path); - lexer->set_debug(debug); - - Macro::parser parser(*this, out); - parser.set_debug_level(debug); - - // Output first @#line statement - if (!no_line_macro) - out << "@#line \"" << file << "\" 1" << endl; - - // Launch macro-processing - parser.parse(); - - delete lexer; -} - -void -MacroDriver::error(const Macro::parser::location_type &l, const string &m) const -{ - cerr << "ERROR in macro-processor: " << l << ": " << m << endl; - exit(EXIT_FAILURE); -} - -void -MacroDriver::set_variable(const string &name, const MacroValue *value) -{ - env[name] = value; -} - -const MacroValue * -MacroDriver::get_variable(const string &name) const throw (UnknownVariable) -{ - map::const_iterator it = env.find(name); - if (it == env.end()) - throw UnknownVariable(name); - return it->second; -} - -void -MacroDriver::init_loop(const string &name, const MacroValue *value) throw (MacroValue::TypeError) -{ - const ArrayMV *mv1 = dynamic_cast *>(value); - const ArrayMV *mv2 = dynamic_cast *>(value); - if (!mv1 && !mv2) - throw MacroValue::TypeError("Argument of @#for loop must be an array expression"); - loop_stack.push(make_pair(name, make_pair(value, 0))); -} - -bool -MacroDriver::iter_loop() -{ - if (loop_stack.empty()) - throw "No loop on which to iterate!"; - - int &i = loop_stack.top().second.second; - const MacroValue *mv = loop_stack.top().second.first; - string name = loop_stack.top().first; - - const ArrayMV *mv1 = dynamic_cast *>(mv); - if (mv1) - { - if (i >= (int) mv1->values.size()) - { - loop_stack.pop(); - return false; - } - else - { - env[name] = new IntMV(*this, mv1->values[i++]); - return true; - } - } - else - { - const ArrayMV *mv2 = dynamic_cast *>(mv); - if (i >= (int) mv2->values.size()) - { - loop_stack.pop(); - return false; - } - else - { - env[name] = new StringMV(*this, mv2->values[i++]); - return true; - } - } -} - -void -MacroDriver::begin_if(const MacroValue *value) throw (MacroValue::TypeError) -{ - const IntMV *ival = dynamic_cast(value); - if (!ival) - throw MacroValue::TypeError("Argument of @#if must be an integer"); - last_if = (bool) ival->value; -} - -void -MacroDriver::begin_ifdef(const string &name) -{ - try - { - get_variable(name); - begin_if(new IntMV(*this, 1)); - } - catch (UnknownVariable &) - { - begin_if(new IntMV(*this, 0)); - } -} - -void -MacroDriver::begin_ifndef(const string &name) -{ - try - { - get_variable(name); - begin_if(new IntMV(*this, 0)); - } - catch (UnknownVariable &) - { - begin_if(new IntMV(*this, 1)); - } -} - -void -MacroDriver::echo(const Macro::parser::location_type &l, const MacroValue *value) const throw (MacroValue::TypeError) -{ - const StringMV *sval = dynamic_cast(value); - if (!sval) - throw MacroValue::TypeError("Argument of @#echo must be a string"); - - cerr << "ECHO in macro-processor: " << l << ": " << sval->value << endl; -} - -void -MacroDriver::error(const Macro::parser::location_type &l, const MacroValue *value) const throw (MacroValue::TypeError) -{ - const StringMV *sval = dynamic_cast(value); - if (!sval) - throw MacroValue::TypeError("Argument of @#error must be a string"); - - error(l, sval->value); -} - -string -MacroDriver::printvars(const Macro::parser::location_type &l, const bool tostdout) const -{ - if (tostdout) - { - cout << "Macroprocessor: Printing macro variable values from " << file - << " at line " << l.begin.line << endl; - for (map::const_iterator it = env.begin(); - it != env.end(); it++) - cout << " " << it->first << " = " << it->second->print() << endl; - cout << endl; - return ""; - } - - stringstream intomfile; - if (!no_line_macro) - intomfile << "@#line \"" << file << "\" " << l.begin.line << endl; - - for (map::const_iterator it = env.begin(); - it != env.end(); it++) - intomfile<< "options_.macrovars_line_" << l.begin.line << "." << it->first << " = " << it->second->print() << ";" << endl; - return intomfile.str(); -} diff --git a/preprocessor/macro/MacroDriver.hh b/preprocessor/macro/MacroDriver.hh deleted file mode 100644 index 53b1271d8..000000000 --- a/preprocessor/macro/MacroDriver.hh +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2008-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 . - */ - -#ifndef _MACRO_DRIVER_HH -#define _MACRO_DRIVER_HH - -#ifdef _PARSING_DRIVER_HH -# error Impossible to include both ParsingDriver.hh and MacroDriver.hh -#endif - -#include -#include -#include -#include -#include - -#include "MacroValue.hh" -#include "MacroBison.hh" - -using namespace std; - -// Declare MacroFlexLexer class -#ifndef __FLEX_LEXER_H -# define yyFlexLexer MacroFlexLexer -# include -# undef yyFlexLexer -#endif - -//! The lexer class -/*! Actually it was necessary to subclass the MacroFlexLexer class generated by Flex, - since the prototype for MacroFlexLexer::yylex() was not convenient. -*/ -class MacroFlex : public MacroFlexLexer -{ -private: - //! Used to backup all the information related to a given scanning context - class ScanContext - { - public: - istream *input; - struct yy_buffer_state *buffer; - const Macro::parser::location_type yylloc; - const bool is_for_context; - const string for_body; - const Macro::parser::location_type for_body_loc; - ScanContext(istream *input_arg, struct yy_buffer_state *buffer_arg, - Macro::parser::location_type &yylloc_arg, bool is_for_context_arg, - const string &for_body_arg, - Macro::parser::location_type &for_body_loc_arg) : - input(input_arg), buffer(buffer_arg), yylloc(yylloc_arg), is_for_context(is_for_context_arg), - for_body(for_body_arg), for_body_loc(for_body_loc_arg) - { - } - }; - - //! The stack used to keep track of nested scanning contexts - stack context_stack; - - //! Input stream used for initialization of current scanning context - /*! Kept for deletion at end of current scanning buffer */ - istream *input; - - //! Should we omit the @#line statements ? - const bool no_line_macro; - //! The paths to search when looking for .mod files - vector path; - //! True iff current context is the body of a loop - bool is_for_context; - //! If current context is the body of a loop, contains the string of the loop body - string for_body; - //! If current context is the body of a loop, contains the location of the beginning of the body - Macro::parser::location_type for_body_loc; - - //! Temporary variable used in FOR_BODY mode - string for_body_tmp; - //! Temporary variable used in FOR_BODY mode - Macro::parser::location_type for_body_loc_tmp; - //! Temporary variable used in FOR_BODY mode. Keeps track of the location of the @#for statement, for reporting messages - Macro::parser::location_type for_stmt_loc_tmp; - //! Temporary variable used in FOR_BODY mode. Keeps track of number of nested @#for/@#endfor - int nested_for_nb; - //! Set to true while parsing a FOR statement (only the statement, not the loop body) - bool reading_for_statement; - - //! Temporary variable used in THEN_BODY and ELSE_BODY modes. Keeps track of number of nested @#if - int nested_if_nb; - //! Temporary variable used in THEN_BODY mode - string then_body_tmp; - //! Temporary variable used in THEN_BODY mode - Macro::parser::location_type then_body_loc_tmp; - //! Temporary variable used in THEN_BODY mode. Keeps track of the location of the @#if statement, for reporting messages - Macro::parser::location_type if_stmt_loc_tmp; - //! Temporary variable used in ELSE_BODY mode - string else_body_tmp; - //! Temporary variable used in ELSE_BODY mode - Macro::parser::location_type else_body_loc_tmp; - //! Set to true while parsing an IF statement (only the statement, not the body) - bool reading_if_statement; - - //! Output the @#line declaration - void output_line(Macro::parser::location_type *yylloc) const; - - //! Save current scanning context - void save_context(Macro::parser::location_type *yylloc); - - //! Restore last scanning context - void restore_context(Macro::parser::location_type *yylloc); - - //! pushes the colon-separated paths passed to @#includepath onto the path vector - void push_path(string *includepath, Macro::parser::location_type *yylloc, - MacroDriver &driver); - - //! Saves current scanning context and create a new context with content of filename - /*! Filename must be a newly allocated string which will be deleted by the lexer */ - void create_include_context(string *filename, Macro::parser::location_type *yylloc, - MacroDriver &driver); - - //! Saves current scanning context and create a new context based on the "then" body - void create_then_context(Macro::parser::location_type *yylloc); - - //! Saves current scanning context and create a new context based on the "else" body - void create_else_context(Macro::parser::location_type *yylloc); - - //! Initialise a new flex buffer with the loop body - void new_loop_body_buffer(Macro::parser::location_type *yylloc); - -public: - MacroFlex(istream *in, ostream *out, bool no_line_macro_arg, vector path_arg); - - //! The main lexing function - Macro::parser::token_type lex(Macro::parser::semantic_type *yylval, - Macro::parser::location_type *yylloc, - MacroDriver &driver); -}; - -//! Implements the macro expansion using a Flex scanner and a Bison parser -class MacroDriver -{ - friend class MacroValue; -private: - //! Stores all created macro values - set values; - - //! Environment: maps macro variables to their values - map env; - - //! Stack used to keep track of (possibly nested) loops - //! First element is loop variable name, second is the array over which iteration is done, and third is subscript to be used by next call of iter_loop() (beginning with 0) */ - stack > > loop_stack; -public: - //! Exception thrown when value of an unknown variable is requested - class UnknownVariable - { - public: - const string name; - UnknownVariable(const string &name_arg) : name(name_arg) - { - } - }; - - //! Constructor - MacroDriver(); - //! Destructor - virtual - ~MacroDriver(); - - //! Starts parsing a file, returns output in out - /*! \param no_line_macro should we omit the @#line statements ? */ - void parse(const string &f, const string &fb, const string &modfiletxt, ostream &out, bool debug, bool no_line_macro_arg, - map defines, vector path); - - //! Name of main file being parsed - string file; - - //! Basename of main file being parsed - string basename; - - //! Whether or not to print @#line - bool no_line_macro; - - //! Reference to the lexer - class MacroFlex *lexer; - - //! Used to store the value of the last @#if condition - bool last_if; - - //! Error handler - void error(const Macro::parser::location_type &l, const string &m) const; - - //! Print variables - string printvars(const Macro::parser::location_type &l, const bool save) const; - - //! Set a variable - void set_variable(const string &name, const MacroValue *value); - - //! Get a variable - /*! Returns a newly allocated value (clone of the value stored in environment). */ - const MacroValue *get_variable(const string &name) const throw (UnknownVariable); - - //! Initiate a for loop - /*! Does not set name = value[1]. You must call iter_loop() for that. */ - void init_loop(const string &name, const MacroValue *value) throw (MacroValue::TypeError); - - //! Iterate innermost loop - /*! Returns false if iteration is no more possible (end of loop); in that case it destroys the pointer given to init_loop() */ - bool iter_loop(); - - //! Begins an @#if statement - void begin_if(const MacroValue *value) throw (MacroValue::TypeError); - - //! Begins an @#ifdef statement - void begin_ifdef(const string &name); - - //! Begins an @#ifndef statement - void begin_ifndef(const string &name); - - //! Executes @#echo directive - void echo(const Macro::parser::location_type &l, const MacroValue *value) const throw (MacroValue::TypeError); - - //! Executes @#error directive - void error(const Macro::parser::location_type &l, const MacroValue *value) const throw (MacroValue::TypeError); -}; - -#endif // ! MACRO_DRIVER_HH diff --git a/preprocessor/macro/MacroFlex.ll b/preprocessor/macro/MacroFlex.ll deleted file mode 100644 index 21a35a1c9..000000000 --- a/preprocessor/macro/MacroFlex.ll +++ /dev/null @@ -1,567 +0,0 @@ -/* - * Copyright (C) 2008-2018 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 . - */ - -%{ -using namespace std; - -#include -#include -#include -#include - -#include "MacroDriver.hh" - -// Announce to Flex the prototype we want for lexing function -#define YY_DECL \ - Macro::parser::token_type \ - MacroFlex::lex(Macro::parser::semantic_type *yylval, \ - Macro::parser::location_type *yylloc, \ - MacroDriver &driver) - -// Shortcut to access tokens defined by Bison -typedef Macro::parser::token token; - -/* By default yylex returns int, we use token_type. - Unfortunately yyterminate by default returns 0, which is - not of token_type. */ -#define yyterminate() return Macro::parser::token_type (0); -%} - -%option c++ - -%option prefix="Macro" - -%option case-insensitive noyywrap nounput batch debug never-interactive - -%x STMT -%x EXPR -%x FOR_BODY -%x THEN_BODY -%x ELSE_BODY - -%{ -// Increments location counter for every token read -#define YY_USER_ACTION yylloc->columns(yyleng); -%} - -SPC [ \t]+ -EOL (\r)?\n -CONT \\\\ - -%% - /* Code put at the beginning of yylex() */ -%{ - // Reset location before reading token - yylloc->step(); -%} - -["/"]["/"].* - -^{SPC}*@#{SPC}*includepath{SPC}+\"([^\"\r\n:;|<>]*){1}(:[^\"\r\n:;|<>]*)*\"{SPC}*{EOL} { - yylloc->lines(1); - yylloc->step(); - - // Get path - string *includepath = new string(yytext); - int dblq_idx1 = includepath->find('"'); - int dblq_idx2 = includepath->find('"', dblq_idx1 + 1); - includepath->erase(dblq_idx2); - includepath->erase(0, dblq_idx1 + 1); - - push_path(includepath, yylloc, driver); - BEGIN(INITIAL); - } - -^{SPC}*@#{SPC}*includepath{SPC}+[^\"\r\n]*{SPC}*{EOL} { - yylloc->lines(1); - yylloc->step(); - - // Get variable name - string pathvar = string(yytext); - int dblq_idx1 = pathvar.find("includepath"); - pathvar.erase(0, dblq_idx1 + 11); - pathvar.erase(0, pathvar.find_first_not_of(" \t")); - size_t p = pathvar.find_last_not_of(" \t\n\r"); - if (string::npos != p) - pathvar.erase(p+1); - - string *includepath = NULL; - try - { - includepath = new string(driver.get_variable(pathvar)->toString()); - } - catch(MacroDriver::UnknownVariable(&e)) - { - driver.error(*yylloc, "Unknown variable: " + pathvar); - } - push_path(includepath, yylloc, driver); - BEGIN(INITIAL); - } - -^{SPC}*@#{SPC}*include{SPC}+\"[^\"\r\n]*\"{SPC}*{EOL} { - yylloc->lines(1); - yylloc->step(); - - // Get filename - string *filename = new string(yytext); - int dblq_idx1 = filename->find('"'); - int dblq_idx2 = filename->find('"', dblq_idx1 + 1); - filename->erase(dblq_idx2); - filename->erase(0, dblq_idx1 + 1); - - create_include_context(filename, yylloc, driver); - - BEGIN(INITIAL); - } - -^{SPC}*@#{SPC}*include{SPC}+[^\"\r\n]*{SPC}*{EOL} { - yylloc->lines(1); - yylloc->step(); - - // Get variable name - string modvarname = string(yytext); - int dblq_idx1 = modvarname.find("include"); - modvarname.erase(0, dblq_idx1 + 7); - modvarname.erase(0, modvarname.find_first_not_of(" \t")); - size_t p = modvarname.find_last_not_of(" \t\n\r"); - if (string::npos != p) - modvarname.erase(p+1); - - string *filename = NULL; - try - { - filename = new string(driver.get_variable(modvarname)->toString()); - } - catch(MacroDriver::UnknownVariable(&e)) - { - driver.error(*yylloc, "Unknown variable: " + modvarname); - } - create_include_context(filename, yylloc, driver); - BEGIN(INITIAL); - } - -^{SPC}*@# { yylloc->step(); BEGIN(STMT); } -@\{ { yylloc->step(); BEGIN(EXPR); } - -\} { BEGIN(INITIAL); return token::EOL; } - -{CONT}{SPC}*{EOL} { yylloc->lines(1); yylloc->step(); } -{EOL} { - /* If parsing a @#for or an @#if, keep the location - for reporting message in case of error */ - if (reading_for_statement) - for_stmt_loc_tmp = *yylloc; - else if (reading_if_statement) - if_stmt_loc_tmp = *yylloc; - - yylloc->lines(1); - yylloc->step(); - if (reading_for_statement) - { - reading_for_statement = false; - for_body_tmp.erase(); - for_body_loc_tmp = *yylloc; - nested_for_nb = 0; - BEGIN(FOR_BODY); - } - else if (reading_if_statement) - { - reading_if_statement = false; - then_body_tmp.erase(); - then_body_loc_tmp = *yylloc; - nested_if_nb = 0; - BEGIN(THEN_BODY); - } - else - { -#if (YY_FLEX_MAJOR_VERSION > 2) || (YY_FLEX_MAJOR_VERSION == 2 && YY_FLEX_MINOR_VERSION >= 6) - yyout << endl; -#else - *yyout << endl; -#endif - BEGIN(INITIAL); - } - return token::EOL; - } - -{SPC}+ { yylloc->step(); } - -[0-9]+ { - yylval->int_val = atoi(yytext); - return token::INTEGER; - } -\( { return token::LPAREN; } -\) { return token::RPAREN; } -\[ { return token::LBRACKET; } -\] { return token::RBRACKET; } -: { return token::COLON; } -, { return token::COMMA; } -= { return token::EQUAL; } -[!] { return token::EXCLAMATION; } -"||" { return token::LOGICAL_OR; } -&& { return token::LOGICAL_AND; } -"<=" { return token::LESS_EQUAL; } -">=" { return token::GREATER_EQUAL; } -"<" { return token::LESS; } -">" { return token::GREATER; } -"==" { return token::EQUAL_EQUAL; } -"!=" { return token::EXCLAMATION_EQUAL; } -[+] { return token::PLUS; } -[-] { return token::MINUS; } -[*] { return token::TIMES; } -[/] { return token::DIVIDE; } -in { return token::IN; } -length { return token::LENGTH; } - -\"[^\"]*\" { - yylval->string_val = new string(yytext + 1); - yylval->string_val->resize(yylval->string_val->length() - 1); - return token::STRING; - } - -line { return token::LINE; } -define { return token::DEFINE; } - -echomacrovars { return token::ECHOMACROVARS; } -save { return token::SAVE; } - -for { reading_for_statement = true; return token::FOR; } -endfor { driver.error(*yylloc, "@#endfor is not matched by a @#for statement"); } - -ifdef { reading_if_statement = true; return token::IFDEF; } -ifndef { reading_if_statement = true; return token::IFNDEF; } - -if { reading_if_statement = true; return token::IF; } -else { driver.error(*yylloc, "@#else is not matched by an @#if/@#ifdef/@#ifndef statement"); } -endif { driver.error(*yylloc, "@#endif is not matched by an @#if/@#ifdef/@#ifndef statement"); } - -echo { return token::ECHO_DIR; } -error { return token::ERROR; } - -[A-Za-z_][A-Za-z0-9_]* { - yylval->string_val = new string(yytext); - return token::NAME; - } - -<> { driver.error(*yylloc, "Unexpected end of file while parsing a macro expression"); } -<> { driver.error(*yylloc, "Unexpected end of file while parsing a macro statement"); } - -{EOL} { yylloc->lines(1); yylloc->step(); for_body_tmp.append(yytext); } -^{SPC}*@#{SPC}*for({SPC}|{CONT}) { - nested_for_nb++; - for_body_tmp.append(yytext); - yylloc->step(); - } -. { for_body_tmp.append(yytext); yylloc->step(); } -<> { driver.error(for_stmt_loc_tmp, "@#for loop not matched by an @#endfor or file does not end with a new line (unexpected end of file)"); } -^{SPC}*@#{SPC}*endfor{SPC}*(\/\/.*)?{EOL} { - yylloc->lines(1); - yylloc->step(); - if (nested_for_nb) - { - /* This @#endfor is not the end of the loop body, - but only that of a nested @#for loop */ - nested_for_nb--; - for_body_tmp.append(yytext); - } - else - { - // Switch to loop body context, except if iterating over an empty array - if (driver.iter_loop()) - { - // Save old buffer state and location - save_context(yylloc); - - is_for_context = true; - for_body = for_body_tmp; - for_body_loc = for_body_loc_tmp; - - new_loop_body_buffer(yylloc); - } - - BEGIN(INITIAL); - } - } - -{EOL} { yylloc->lines(1); yylloc->step(); then_body_tmp.append(yytext); } -^{SPC}*@#{SPC}*if({SPC}|{CONT}) { - nested_if_nb++; - then_body_tmp.append(yytext); - yylloc->step(); - } -^{SPC}*@#{SPC}*ifdef({SPC}|{CONT}) { - nested_if_nb++; - then_body_tmp.append(yytext); - yylloc->step(); - } -^{SPC}*@#{SPC}*ifndef({SPC}|{CONT}) { - nested_if_nb++; - then_body_tmp.append(yytext); - yylloc->step(); - } -. { then_body_tmp.append(yytext); yylloc->step(); } -<> { driver.error(if_stmt_loc_tmp, "@#if/@#ifdef/@#ifndef not matched by an @#endif or file does not end with a new line (unexpected end of file)"); } -^{SPC}*@#{SPC}*else{SPC}*(\/\/.*)?{EOL} { - yylloc->lines(1); - yylloc->step(); - if (nested_if_nb) - then_body_tmp.append(yytext); - else - { - else_body_tmp.erase(); - else_body_loc_tmp = *yylloc; - BEGIN(ELSE_BODY); - } - } - -^{SPC}*@#{SPC}*endif{SPC}*(\/\/.*)?{EOL} { - yylloc->lines(1); - yylloc->step(); - if (nested_if_nb) - { - /* This @#endif is not the end of the @#if we're parsing, - but only that of a nested @#if */ - nested_if_nb--; - then_body_tmp.append(yytext); - } - else - { - if (driver.last_if) - create_then_context(yylloc); - else - output_line(yylloc); - - BEGIN(INITIAL); - } - } - -{EOL} { yylloc->lines(1); yylloc->step(); else_body_tmp.append(yytext); } -^{SPC}*@#{SPC}*if({SPC}|{CONT}) { - nested_if_nb++; - else_body_tmp.append(yytext); - yylloc->step(); - } -. { else_body_tmp.append(yytext); yylloc->step(); } -<> { driver.error(if_stmt_loc_tmp, "@#if/@#ifdef/@#ifndef not matched by an @#endif or file does not end with a new line (unexpected end of file)"); } - -^{SPC}*@#{SPC}*endif{SPC}*(\/\/.*)?{EOL} { - yylloc->lines(1); - yylloc->step(); - if (nested_if_nb) - { - /* This @#endif is not the end of the @#if we're parsing, - but only that of a nested @#if */ - nested_if_nb--; - else_body_tmp.append(yytext); - } - else - { - if (driver.last_if) - create_then_context(yylloc); - else - create_else_context(yylloc); - - BEGIN(INITIAL); - } - } - -<> { - // Quit lexer if end of main file - if (context_stack.empty()) - { - yyterminate(); - } - - // Else clean current scanning context - yy_delete_buffer(YY_CURRENT_BUFFER); - delete input; - delete yylloc->begin.filename; - - /* If we are not in a loop body, or if the loop has terminated, - pop a context */ - if (is_for_context && driver.iter_loop()) - new_loop_body_buffer(yylloc); - else - restore_context(yylloc); - } - - /* We don't use echo, because under Cygwin it will add an extra \r */ -{EOL} { yylloc->lines(1); yylloc->step(); -#if (YY_FLEX_MAJOR_VERSION > 2) || (YY_FLEX_MAJOR_VERSION == 2 && YY_FLEX_MINOR_VERSION >= 6) - yyout << endl; -#else - *yyout << endl; -#endif - } - - /* Copy everything else to output */ -. { yylloc->step(); ECHO; } - -<*>. { driver.error(*yylloc, "Macro lexer error: '" + string(yytext) + "'"); } -%% - -MacroFlex::MacroFlex(istream* in, ostream* out, bool no_line_macro_arg, vector path_arg) - : MacroFlexLexer(in, out), input(in), no_line_macro(no_line_macro_arg), path(path_arg), - reading_for_statement(false), reading_if_statement(false) -{ -} - -void -MacroFlex::output_line(Macro::parser::location_type *yylloc) const -{ - if (!no_line_macro) -#if (YY_FLEX_MAJOR_VERSION > 2) || (YY_FLEX_MAJOR_VERSION == 2 && YY_FLEX_MINOR_VERSION >= 6) - const_cast(yyout) -#else - *yyout -#endif - << endl << "@#line \"" << *yylloc->begin.filename << "\" " - << yylloc->begin.line << endl; -} - -void -MacroFlex::save_context(Macro::parser::location_type *yylloc) -{ - context_stack.push(ScanContext(input, YY_CURRENT_BUFFER, *yylloc, is_for_context, - for_body, for_body_loc)); -} - -void -MacroFlex::restore_context(Macro::parser::location_type *yylloc) -{ - input = context_stack.top().input; - yy_switch_to_buffer(context_stack.top().buffer); - *yylloc = context_stack.top().yylloc; - is_for_context = context_stack.top().is_for_context; - for_body = context_stack.top().for_body; - for_body_loc = context_stack.top().for_body_loc; - // Remove top of stack - context_stack.pop(); - // Dump @#line instruction - output_line(yylloc); -} - -void -MacroFlex::push_path(string *includepath, Macro::parser::location_type *yylloc, - MacroDriver &driver) -{ - using namespace boost; - vector tokenizedPath; - split(tokenizedPath, *includepath, is_any_of(":"), token_compress_on); - for (vector::iterator it = tokenizedPath.begin(); - it != tokenizedPath.end(); it++ ) - if (!it->empty()) - { - trim(*it); - path.push_back(*it); - } -} - -void -MacroFlex::create_include_context(string *filename, Macro::parser::location_type *yylloc, - MacroDriver &driver) -{ -#ifdef _WIN32 - string FILESEP = "\\"; -#else - string FILESEP = "/"; -#endif - save_context(yylloc); - // Open new file - input = new ifstream(filename->c_str(), ios::binary); - if (input->fail()) - { - ostringstream dirs; - dirs << "." << FILESEP << endl; - for (vector::const_iterator it = path.begin(); it != path.end(); it++) - { - string testfile = *it + FILESEP + *filename; - input = new ifstream(testfile.c_str(), ios::binary); - if (input->good()) - break; - dirs << *it << endl; - } - if (input->fail()) - driver.error(*yylloc, "Could not open " + *filename + - ". The following directories were searched:\n" + dirs.str()); - } - - // Reset location - yylloc->begin.filename = yylloc->end.filename = filename; - yylloc->begin.line = yylloc->end.line = 1; - yylloc->begin.column = yylloc->end.column = 0; - // We are not in a loop body - is_for_context = false; - for_body.clear(); - // Output @#line information - output_line(yylloc); - // Switch to new buffer - yy_switch_to_buffer(yy_create_buffer(input, YY_BUF_SIZE)); -} - -void -MacroFlex::create_then_context(Macro::parser::location_type *yylloc) -{ - save_context(yylloc); - input = new stringstream(then_body_tmp); - *yylloc = then_body_loc_tmp; - yylloc->begin.filename = yylloc->end.filename = new string(*then_body_loc_tmp.begin.filename); - is_for_context = false; - for_body.clear(); - output_line(yylloc); - yy_switch_to_buffer(yy_create_buffer(input, YY_BUF_SIZE)); -} - -void -MacroFlex::create_else_context(Macro::parser::location_type *yylloc) -{ - save_context(yylloc); - input = new stringstream(else_body_tmp); - *yylloc = else_body_loc_tmp; - yylloc->begin.filename = yylloc->end.filename = new string(*else_body_loc_tmp.begin.filename); - is_for_context = false; - for_body.clear(); - output_line(yylloc); - yy_switch_to_buffer(yy_create_buffer(input, YY_BUF_SIZE)); -} - -void -MacroFlex::new_loop_body_buffer(Macro::parser::location_type *yylloc) -{ - input = new stringstream(for_body); - *yylloc = for_body_loc; - yylloc->begin.filename = yylloc->end.filename = new string(*for_body_loc.begin.filename); - output_line(yylloc); - yy_switch_to_buffer(yy_create_buffer(input, YY_BUF_SIZE)); -} - -/* This implementation of MacroFlexLexer::yylex() is required to fill the - * vtable of the class MacroFlexLexer. We define the scanner's main yylex - * function via YY_DECL to reside in the MacroFlex class instead. */ - -#ifdef yylex -# undef yylex -#endif - -int -MacroFlexLexer::yylex() -{ - cerr << "MacroFlexLexer::yylex() has been called, that should never happen!" << endl; - exit(EXIT_FAILURE); -} diff --git a/preprocessor/macro/MacroValue.cc b/preprocessor/macro/MacroValue.cc deleted file mode 100644 index db8c8ac29..000000000 --- a/preprocessor/macro/MacroValue.cc +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (C) 2008-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 . - */ - -#include "MacroDriver.hh" - -MacroValue::MacroValue(MacroDriver &driver_arg) : driver(driver_arg) -{ - driver.values.insert(this); -} - -MacroValue::~MacroValue() -{ -} - -const MacroValue * -MacroValue::operator+() const throw (TypeError) -{ - throw TypeError("Unary operator + does not exist for this type"); -} - -const MacroValue * -MacroValue::operator-(const MacroValue &mv) const throw (TypeError) -{ - throw TypeError("Operator - does not exist for this type"); -} - -const MacroValue * -MacroValue::operator-() const throw (TypeError) -{ - throw TypeError("Unary operator - does not exist for this type"); -} - -const MacroValue * -MacroValue::operator*(const MacroValue &mv) const throw (TypeError) -{ - throw TypeError("Operator * does not exist for this type"); -} - -const MacroValue * -MacroValue::operator/(const MacroValue &mv) const throw (TypeError) -{ - throw TypeError("Operator / does not exist for this type"); -} - -const MacroValue * -MacroValue::operator<(const MacroValue &mv) const throw (TypeError) -{ - throw TypeError("Operator < does not exist for this type"); -} - -const MacroValue * -MacroValue::operator>(const MacroValue &mv) const throw (TypeError) -{ - throw TypeError("Operator > does not exist for this type"); -} - -const MacroValue * -MacroValue::operator<=(const MacroValue &mv) const throw (TypeError) -{ - throw TypeError("Operator <= does not exist for this type"); -} - -const MacroValue * -MacroValue::operator>=(const MacroValue &mv) const throw (TypeError) -{ - throw TypeError("Operator >= does not exist for this type"); -} - -const MacroValue * -MacroValue::operator&&(const MacroValue &mv) const throw (TypeError) -{ - throw TypeError("Operator && does not exist for this type"); -} - -const MacroValue * -MacroValue::operator||(const MacroValue &mv) const throw (TypeError) -{ - throw TypeError("Operator || does not exist for this type"); -} - -const MacroValue * -MacroValue::operator!() const throw (TypeError) -{ - throw TypeError("Operator ! does not exist for this type"); -} - -const MacroValue * -MacroValue::operator[](const MacroValue &mv) const throw (TypeError, OutOfBoundsError) -{ - throw TypeError("Operator [] does not exist for this type"); -} - -const MacroValue * -MacroValue::length() const throw (TypeError) -{ - throw TypeError("Length not supported for this type"); -} - -const MacroValue * -MacroValue::append(const MacroValue *mv) const throw (TypeError) -{ - throw TypeError("Cannot append an array at the end of another one. Should use concatenation."); -} - -const MacroValue * -MacroValue::in(const MacroValue *array) const throw (TypeError) -{ - throw TypeError("First argument of 'in' operator cannot be an array"); -} - -const MacroValue * -MacroValue::new_base_value(MacroDriver &driver, int i) -{ - return new IntMV(driver, i); -} - -const MacroValue * -MacroValue::new_base_value(MacroDriver &driver, const string &s) -{ - return new StringMV(driver, s); -} - -IntMV::IntMV(MacroDriver &driver, int value_arg) : MacroValue(driver), value(value_arg) -{ -} - -IntMV::~IntMV() -{ -} - -const MacroValue * -IntMV::operator+(const MacroValue &mv) const throw (TypeError) -{ - const IntMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - throw TypeError("Type mismatch for operands of + operator"); - return new IntMV(driver, value + mv2->value); -} - -const MacroValue * -IntMV::operator+() const throw (TypeError) -{ - return this; -} - -const MacroValue * -IntMV::operator-(const MacroValue &mv) const throw (TypeError) -{ - const IntMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - throw TypeError("Type mismatch for operands of - operator"); - return new IntMV(driver, value - mv2->value); -} - -const MacroValue * -IntMV::operator-() const throw (TypeError) -{ - return new IntMV(driver, -value); -} - -const MacroValue * -IntMV::operator*(const MacroValue &mv) const throw (TypeError) -{ - const IntMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - throw TypeError("Type mismatch for operands of * operator"); - return new IntMV(driver, value * mv2->value); -} - -const MacroValue * -IntMV::operator/(const MacroValue &mv) const throw (TypeError) -{ - const IntMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - throw TypeError("Type mismatch for operands of / operator"); - return new IntMV(driver, value / mv2->value); -} - -const MacroValue * -IntMV::operator<(const MacroValue &mv) const throw (TypeError) -{ - const IntMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - throw TypeError("Type mismatch for operands of < operator"); - return new IntMV(driver, value < mv2->value); -} - -const MacroValue * -IntMV::operator>(const MacroValue &mv) const throw (TypeError) -{ - const IntMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - throw TypeError("Type mismatch for operands of > operator"); - return new IntMV(driver, value > mv2->value); -} - -const MacroValue * -IntMV::operator<=(const MacroValue &mv) const throw (TypeError) -{ - const IntMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - throw TypeError("Type mismatch for operands of <= operator"); - return new IntMV(driver, value <= mv2->value); -} - -const MacroValue * -IntMV::operator>=(const MacroValue &mv) const throw (TypeError) -{ - const IntMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - throw TypeError("Type mismatch for operands of >= operator"); - return new IntMV(driver, value >= mv2->value); -} - -const MacroValue * -IntMV::operator==(const MacroValue &mv) const throw (TypeError) -{ - const IntMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - return new IntMV(driver, 0); - else - return new IntMV(driver, value == mv2->value); -} - -const MacroValue * -IntMV::operator!=(const MacroValue &mv) const throw (TypeError) -{ - const IntMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - return new IntMV(driver, 1); - else - return new IntMV(driver, value != mv2->value); -} - -const MacroValue * -IntMV::operator&&(const MacroValue &mv) const throw (TypeError) -{ - const IntMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - throw TypeError("Type mismatch for operands of && operator"); - return new IntMV(driver, value && mv2->value); -} - -const MacroValue * -IntMV::operator||(const MacroValue &mv) const throw (TypeError) -{ - const IntMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - throw TypeError("Type mismatch for operands of || operator"); - return new IntMV(driver, value || mv2->value); -} - -const MacroValue * -IntMV::operator!() const throw (TypeError) -{ - return new IntMV(driver, !value); -} - -string -IntMV::toString() const -{ - ostringstream ss; - ss << value; - return ss.str(); -} - -string -IntMV::print() const -{ - return toString(); -} - -const MacroValue * -IntMV::toArray() const -{ - vector v; - v.push_back(value); - return new ArrayMV(driver, v); -} - -const MacroValue * -IntMV::append(const MacroValue *array) const throw (TypeError) -{ - const ArrayMV *array2 = dynamic_cast *>(array); - if (array2 == NULL) - throw TypeError("Type mismatch for append operation"); - - vector v(array2->values); - v.push_back(value); - return new ArrayMV(driver, v); -} - -const MacroValue * -IntMV::in(const MacroValue *array) const throw (TypeError) -{ - const ArrayMV *array2 = dynamic_cast *>(array); - if (array2 == NULL) - throw TypeError("Type mismatch for 'in' operator"); - - int result = 0; - for (vector::const_iterator it = array2->values.begin(); - it != array2->values.end(); it++) - if (*it == value) - { - result = 1; - break; - } - - return new IntMV(driver, result); -} - -const MacroValue * -IntMV::new_range(MacroDriver &driver, const MacroValue *mv1, const MacroValue *mv2) throw (TypeError) -{ - const IntMV *mv1i = dynamic_cast(mv1); - const IntMV *mv2i = dynamic_cast(mv2); - if (mv1i == NULL || mv2i == NULL) - throw TypeError("Arguments of range operator (:) must be integers"); - - int v1 = mv1i->value; - int v2 = mv2i->value; - - vector result; - for (; v1 <= v2; v1++) - result.push_back(v1); - return new ArrayMV(driver, result); -} - -StringMV::StringMV(MacroDriver &driver, const string &value_arg) : - MacroValue(driver), value(value_arg) -{ -} - -StringMV::~StringMV() -{ -} - -const MacroValue * -StringMV::operator+(const MacroValue &mv) const throw (TypeError) -{ - const StringMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - throw TypeError("Type mismatch for operands of + operator"); - return new StringMV(driver, value + mv2->value); -} - -const MacroValue * -StringMV::operator==(const MacroValue &mv) const throw (TypeError) -{ - const StringMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - return new IntMV(driver, 0); - else - return new IntMV(driver, value == mv2->value); -} - -const MacroValue * -StringMV::operator!=(const MacroValue &mv) const throw (TypeError) -{ - const StringMV *mv2 = dynamic_cast(&mv); - if (mv2 == NULL) - return new IntMV(driver, 1); - else - return new IntMV(driver, value != mv2->value); -} - -const MacroValue * -StringMV::operator[](const MacroValue &mv) const throw (TypeError, OutOfBoundsError) -{ - const ArrayMV *mv2 = dynamic_cast *>(&mv); - if (mv2 == NULL) - throw TypeError("Expression inside [] must be an integer array"); - string result; - for (vector::const_iterator it = mv2->values.begin(); - it != mv2->values.end(); it++) - { - if (*it < 1 || *it > (int) value.length()) - throw OutOfBoundsError(); - char c = value.at(*it - 1); - result.append(1, c); - } - return new StringMV(driver, result); -} - -string -StringMV::toString() const -{ - return value; -} - -string -StringMV::print() const -{ - return "'" + value + "'"; -} - -const MacroValue * -StringMV::toArray() const -{ - vector v; - v.push_back(value); - return new ArrayMV(driver, v); -} - -const MacroValue * -StringMV::append(const MacroValue *array) const throw (TypeError) -{ - const ArrayMV *array2 = dynamic_cast *>(array); - if (array2 == NULL) - throw TypeError("Type mismatch for append operation"); - - vector v(array2->values); - v.push_back(value); - return new ArrayMV(driver, v); -} - -const MacroValue * -StringMV::in(const MacroValue *array) const throw (TypeError) -{ - const ArrayMV *array2 = dynamic_cast *>(array); - if (array2 == NULL) - throw TypeError("Type mismatch for 'in' operator"); - - int result = 0; - for (vector::const_iterator it = array2->values.begin(); - it != array2->values.end(); it++) - if (*it == value) - { - result = 1; - break; - } - - return new IntMV(driver, result); -} diff --git a/preprocessor/macro/MacroValue.hh b/preprocessor/macro/MacroValue.hh deleted file mode 100644 index ced291895..000000000 --- a/preprocessor/macro/MacroValue.hh +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright (C) 2008-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 . - */ - -#ifndef _MACRO_VALUE_HH -#define _MACRO_VALUE_HH - -#include -#include -#include -#include - -using namespace std; - -class MacroDriver; - -//! Base class for representing values in macro language -class MacroValue -{ -protected: - //! Reference to enclosing MacroDriver - MacroDriver &driver; -public: - //! Exception thrown when type error occurs in macro language - class TypeError - { - public: - const string message; - TypeError(const string &message_arg) : message(message_arg) - { - }; - }; - //! Exception thrown when doing an out-of-bounds access through [] operator - class OutOfBoundsError - { - }; - MacroValue(MacroDriver &driver_arg); - virtual - ~MacroValue(); - //! Applies + operator - virtual const MacroValue *operator+(const MacroValue &mv) const throw (TypeError) = 0; - //! Applies unary + operator - virtual const MacroValue *operator+() const throw (TypeError); - //! Applies - operator - virtual const MacroValue *operator-(const MacroValue &mv) const throw (TypeError); - //! Applies unary - operator - virtual const MacroValue *operator-() const throw (TypeError); - //! Applies * operator - virtual const MacroValue *operator*(const MacroValue &mv) const throw (TypeError); - //! Applies / operator - virtual const MacroValue *operator/(const MacroValue &mv) const throw (TypeError); - //! Less comparison - /*! Returns an IntMV, equal to 0 or 1 */ - virtual const MacroValue *operator<(const MacroValue &mv) const throw (TypeError); - //! Greater comparision - /*! Returns an IntMV, equal to 0 or 1 */ - virtual const MacroValue *operator>(const MacroValue &mv) const throw (TypeError); - //! Less or equal comparison - /*! Returns an IntMV, equal to 0 or 1 */ - virtual const MacroValue *operator<=(const MacroValue &mv) const throw (TypeError); - //! Greater or equal comparison - /*! Returns an IntMV, equal to 0 or 1 */ - virtual const MacroValue *operator>=(const MacroValue &mv) const throw (TypeError); - //! Equal comparison - /*! Returns an IntMV, equal to 0 or 1 */ - virtual const MacroValue *operator==(const MacroValue &mv) const throw (TypeError) = 0; - //! Not equal comparison - /*! Returns an IntMV, equal to 0 or 1 */ - virtual const MacroValue *operator!=(const MacroValue &mv) const throw (TypeError) = 0; - //! Applies && operator - virtual const MacroValue *operator&&(const MacroValue &mv) const throw (TypeError); - //! Applies || operator - virtual const MacroValue *operator||(const MacroValue &mv) const throw (TypeError); - //! Applies unary ! operator - virtual const MacroValue *operator!() const throw (TypeError); - //! Applies [] operator - virtual const MacroValue *operator[](const MacroValue &mv) const throw (TypeError, OutOfBoundsError); - //! Converts value to string - virtual string toString() const = 0; - //! Converts value to be printed - virtual string print() const = 0; - //! Converts value to array form - virtual const MacroValue *toArray() const = 0; - //! Gets length - virtual const MacroValue *length() const throw (TypeError); - //! Appends value at the end of an array - /*! The argument must be an array. */ - virtual const MacroValue *append(const MacroValue *array) const throw (TypeError); - //! Applies "in" operator - /*! The argument must be an array. Returns an IntMV, equal to 0 or 1 */ - virtual const MacroValue *in(const MacroValue *array) const throw (TypeError); - //! Returns a new IntMV - /*! Necessary for ArrayMV::operator[] (template issue) */ - static const MacroValue *new_base_value(MacroDriver &driver, int i); - //! Returns a new StringMV - /*! Necessary for ArrayMV::operator[] (template issue) */ - static const MacroValue *new_base_value(MacroDriver &driver, const string &s); -}; - -//! Represents an integer value in macro language -class IntMV : public MacroValue -{ - friend class StringMV; - friend class MacroDriver; -private: - //! Underlying integer value - const int value; -public: - IntMV(MacroDriver &driver, int value_arg); - virtual - ~IntMV(); - //! Computes arithmetic addition - virtual const MacroValue *operator+(const MacroValue &mv) const throw (TypeError); - //! Unary plus - /*! Returns itself */ - virtual const MacroValue *operator+() const throw (TypeError); - //! Computes arithmetic substraction - virtual const MacroValue *operator-(const MacroValue &mv) const throw (TypeError); - //! Computes opposite - virtual const MacroValue *operator-() const throw (TypeError); - //! Computes arithmetic multiplication - virtual const MacroValue *operator*(const MacroValue &mv) const throw (TypeError); - //! Computes arithmetic division - virtual const MacroValue *operator/(const MacroValue &mv) const throw (TypeError); - virtual const MacroValue *operator<(const MacroValue &mv) const throw (TypeError); - virtual const MacroValue *operator>(const MacroValue &mv) const throw (TypeError); - virtual const MacroValue *operator<=(const MacroValue &mv) const throw (TypeError); - virtual const MacroValue *operator>=(const MacroValue &mv) const throw (TypeError); - virtual const MacroValue *operator==(const MacroValue &mv) const throw (TypeError); - virtual const MacroValue *operator!=(const MacroValue &mv) const throw (TypeError); - //! Computes logical and - virtual const MacroValue *operator&&(const MacroValue &mv) const throw (TypeError); - //! Computes logical or - virtual const MacroValue *operator||(const MacroValue &mv) const throw (TypeError); - //! Computes logical negation - virtual const MacroValue *operator!() const throw (TypeError); - virtual string toString() const; - virtual string print() const; - //! Converts value to array form - /*! Returns an integer array containing a single value */ - virtual const MacroValue *toArray() const; - //! Appends value at the end of an array - /*! The first argument must be an integer array. */ - virtual const MacroValue *append(const MacroValue *array) const throw (TypeError); - virtual const MacroValue *in(const MacroValue *array) const throw (TypeError); - //! Creates a integer range - /*! Arguments must be of type IntMV. - Returns an integer array containing all integers between mv1 and mv2. - If mv2 < mv1, returns an empty range (for consistency with MATLAB). - */ - static const MacroValue *new_range(MacroDriver &driver, const MacroValue *mv1, const MacroValue *mv2) throw (TypeError); - inline int - get_int_value() const - { - return value; - }; -}; - -//! Represents a string value in macro language -class StringMV : public MacroValue -{ - friend class MacroDriver; -private: - //! Underlying string value - const string value; -public: - StringMV(MacroDriver &driver, const string &value_arg); - virtual - ~StringMV(); - //! Computes string concatenation - virtual const MacroValue *operator+(const MacroValue &mv) const throw (TypeError); - virtual const MacroValue *operator==(const MacroValue &mv) const throw (TypeError); - virtual const MacroValue *operator!=(const MacroValue &mv) const throw (TypeError); - //! Subscripting operator - /*! Argument must be an ArrayMV. Indexes begin at 1. Returns a StringMV. */ - virtual const MacroValue *operator[](const MacroValue &mv) const throw (TypeError, OutOfBoundsError); - //! Returns underlying string value - virtual string toString() const; - virtual string print() const; - //! Converts value to array form - /*! Returns a string array containing a single value */ - virtual const MacroValue *toArray() const; - //! Appends value at the end of an array - /*! The first argument must be a string array. Returns a string array. */ - virtual const MacroValue *append(const MacroValue *array) const throw (TypeError); - virtual const MacroValue *in(const MacroValue *array) const throw (TypeError); -}; - -//! Represents an array in macro language -template -class ArrayMV : public MacroValue -{ - friend class IntMV; - friend class StringMV; - friend class ArrayMV; // Necessary for operator[] to access values of integer array when subscripting a string array - friend class MacroDriver; -private: - //! Underlying vector - const vector values; -public: - ArrayMV(MacroDriver &driver, const vector &values_arg); - virtual - ~ArrayMV(); - //! Computes array concatenation - /*! Both array must be of same type */ - virtual const MacroValue *operator+(const MacroValue &mv) const throw (TypeError); - //! Returns an array in which the elements of the second array have been removed from the first - /*! It is close to a set difference operation, except that if an element appears two times in the first array, it will also be in the returned value (provided it is not in the second array) */ - virtual const MacroValue *operator-(const MacroValue &mv) const throw (TypeError); - virtual const MacroValue *operator==(const MacroValue &mv) const throw (TypeError); - virtual const MacroValue *operator!=(const MacroValue &mv) const throw (TypeError); - //! Subscripting operator - /*! Argument must be an ArrayMV. Indexes begin at 1. - If argument is a one-element array, returns an IntMV or StringMV. - Otherwise returns an array. */ - virtual const MacroValue *operator[](const MacroValue &mv) const throw (TypeError, OutOfBoundsError); - //! Returns a string containing the concatenation of string representations of elements - virtual string toString() const; - virtual string print() const; - //! Returns itself - virtual const MacroValue *toArray() const; - //! Gets length - virtual const MacroValue *length() const throw (TypeError); -}; - -template -ArrayMV::ArrayMV(MacroDriver &driver, const vector &values_arg) : MacroValue(driver), values(values_arg) -{ -} - -template -ArrayMV::~ArrayMV() -{ -} - -template -const MacroValue * -ArrayMV::operator+(const MacroValue &mv) const throw (TypeError) -{ - const ArrayMV *mv2 = dynamic_cast *>(&mv); - if (mv2 == NULL) - throw TypeError("Type mismatch for operands of + operator"); - - vector values_copy(values); - values_copy.insert(values_copy.end(), mv2->values.begin(), mv2->values.end()); - return new ArrayMV(driver, values_copy); -} - -template -const MacroValue * -ArrayMV::operator-(const MacroValue &mv) const throw (TypeError) -{ - const ArrayMV *mv2 = dynamic_cast *>(&mv); - if (mv2 == NULL) - throw TypeError("Type mismatch for operands of - operator"); - - /* Highly inefficient algorithm for computing set difference - (but vector is not suited for that...) */ - vector new_values; - for (typename vector::const_iterator it = values.begin(); - it != values.end(); it++) - { - typename vector::const_iterator it2; - for (it2 = mv2->values.begin(); it2 != mv2->values.end(); it2++) - if (*it == *it2) - break; - if (it2 == mv2->values.end()) - new_values.push_back(*it); - } - - return new ArrayMV(driver, new_values); -} - -template -const MacroValue * -ArrayMV::operator==(const MacroValue &mv) const throw (TypeError) -{ - const ArrayMV *mv2 = dynamic_cast *>(&mv); - if (mv2 == NULL) - return new IntMV(driver, 0); - else - return new IntMV(driver, values == mv2->values); -} - -template -const MacroValue * -ArrayMV::operator!=(const MacroValue &mv) const throw (TypeError) -{ - const ArrayMV *mv2 = dynamic_cast *>(&mv); - if (mv2 == NULL) - return new IntMV(driver, 1); - else - return new IntMV(driver, values != mv2->values); -} - -template -const MacroValue * -ArrayMV::operator[](const MacroValue &mv) const throw (TypeError, OutOfBoundsError) -{ - const ArrayMV *mv2 = dynamic_cast *>(&mv); - if (mv2 == NULL) - throw TypeError("Expression inside [] must be an integer array"); - vector result; - for (vector::const_iterator it = mv2->values.begin(); - it != mv2->values.end(); it++) - { - if (*it < 1 || *it > (int) values.size()) - throw OutOfBoundsError(); - result.push_back(values[*it - 1]); - } - - if (result.size() > 1 || result.size() == 0) - return new ArrayMV(driver, result); - else - return MacroValue::new_base_value(driver, result[0]); -} - -template -string -ArrayMV::toString() const -{ - ostringstream ss; - for (typename vector::const_iterator it = values.begin(); - it != values.end(); it++) - ss << *it; - return ss.str(); -} - -template -string -ArrayMV::print() const -{ - bool printStrArr = false; - try - { - typename vector::const_iterator it = values.begin(); - boost::lexical_cast(*it); - } - catch (boost::bad_lexical_cast &) - { - printStrArr= true; - } - ostringstream ss; - if (printStrArr) - ss << "{"; - else - ss << "["; - for (typename vector::const_iterator it = values.begin(); - it != values.end(); it++) - { - if (it != values.begin()) - ss << ", "; - - if (printStrArr) - ss << "'" << *it << "'"; - else - ss << *it; - } - if (printStrArr) - ss << "}"; - else - ss << "]"; - return ss.str(); -} - -template -const MacroValue * -ArrayMV::toArray() const -{ - return this; -} - -template -const MacroValue * -ArrayMV::length() const throw (TypeError) -{ - return new IntMV(driver, values.size()); -} - -#endif diff --git a/preprocessor/macro/Makefile.am b/preprocessor/macro/Makefile.am deleted file mode 100644 index 08a93d583..000000000 --- a/preprocessor/macro/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -noinst_LIBRARIES = libmacro.a - -BUILT_SOURCES = MacroBison.hh stack.hh position.hh location.hh MacroBison.cc MacroFlex.cc - -# We don't put BUILT_SOURCES in libmacro_a_SOURCES, otherwise MacroBison.o and MacroFlex.o will be linked two times (Automake translates MacroFlex.ll and MacroBison.yy into their respective .o); so BUILT_SOURCES is in EXTRA_DIST -libmacro_a_SOURCES = \ - MacroFlex.ll \ - MacroBison.yy \ - MacroDriver.cc \ - MacroDriver.hh \ - MacroValue.cc \ - MacroValue.hh - -EXTRA_DIST = $(BUILT_SOURCES) - -# The -I.. is for -libmacro_a_CPPFLAGS = $(BOOST_CPPFLAGS) -I.. - -MacroFlex.cc: MacroFlex.ll - $(LEX) -o MacroFlex.cc MacroFlex.ll - -MacroBison.cc MacroBison.hh location.hh stack.hh position.hh: MacroBison.yy - $(YACC) -o MacroBison.cc MacroBison.yy