diff --git a/DynamicModel.cc b/DynamicModel.cc index 8805ceb1..9e767fad 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -261,8 +261,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const { int lag = it->first.first; unsigned int var = it->first.second.first; - //int eqr = getBlockInitialEquationID(block, eq); - //int varr = getBlockInitialVariableID(block, var); if (var != prev_var || lag != prev_lag) { prev_var = var; @@ -280,8 +278,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const { int lag = it->first.first; unsigned int var = it->first.second.first; - //int eqr = getBlockInitialEquationID(block, eq); - //int varr = getBlockInitialVariableID(block, var); if (var != prev_var || lag != prev_lag) { prev_var = var; @@ -299,8 +295,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const { int lag = it->first.first; unsigned int var = it->first.second.first; - //int eqr = getBlockInitialEquationID(block, eq); - //int varr = getBlockInitialVariableID(block, var); if (var != prev_var || lag != prev_lag) { prev_var = var; @@ -318,8 +312,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const { int lag = it->first.first; unsigned int var = it->first.second.first; - //int eqr = getBlockInitialEquationID(block, eq); - //int varr = getBlockInitialVariableID(block, var); if (var != prev_var || lag != prev_lag) { prev_var = var; @@ -2801,89 +2793,6 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de typedef pair > index_KF; vector v_index_KF; - - /* DO 170, J = 1, N - TEMP1 = ALPHA*A( J, J ) - DO 110, I = 1, M - C( I, J ) = TEMP1*B( I, J ) - 11 110 CONTINUE - DO 140, K = 1, J - 1 - TEMP1 = ALPHA*A( K, J ) - DO 130, I = 1, M - C( I, J ) = C( I, J ) + TEMP1*B( I, K ) - 13 130 CONTINUE - 14 140 CONTINUE - DO 160, K = J + 1, N - TEMP1 = ALPHA*A( J, K ) - DO 150, I = 1, M - C( I, J ) = C( I, J ) + TEMP1*B( I, K ) - 15 150 CONTINUE - 16 160 CONTINUE - 17 170 CONTINUE - for(int j = 0; j < n; j++) - { - double temp1 = P_t_t1[j + j * n]; - for (int i = 0; i < n; i++) - tmp[i + j * n] = tmp1 * T[i + j * n]; - for (int k = 0; k < j - 1; k++) - { - temp1 = P_t_t1[k + j * n]; - for (int i = 0; i < n; i++) - tmp[i + j * n] += temp1 * T[i + k * n]; - } - for (int k = j + 1; k < n; k++) - { - temp1 = P_t_t1[j + k * n]; - for (int i = 0; i < n; i++) - tmp[i + j * n] += temp1 * T[i + k * n]; - } - } - - for(int j = n_obs; j < n; j++) - { - int j1 = j - n_obs; - double temp1 = P_t_t1[j1 + j1 * n_state]; - for (int i = 0; i < n; i++) - tmp[i + j1 * n] = tmp1 * T[i + j * n]; - for (int k = n_obs; k < j - 1; k++) - { - int k1 = k - n_obs; - temp1 = P_t_t1[k1 + j1 * n_state]; - for (int i = 0; i < n; i++) - tmp[i + j1 * n] += temp1 * T[i + k * n]; - } - for (int k = max(j + 1, n_obs); k < n; k++) - { - int k1 = k - n_obs; - temp1 = P_t_t1[j1 + k1 * n_state]; - for (int i = 0; i < n; i++) - tmp[i + j1 * n] += temp1 * T[i + k * n]; - } - } - - for(int j = n_obs; j < n; j++) - { - int j1 = j - n_obs; - double temp1 = P_t_t1[j1 + j1 * n_state]; - for (int i = 0; i < n; i++) - tmp[i + j1 * n] = tmp1 * T[i + j * n]; - for (int k = n_obs; k < j - 1; k++) - { - int k1 = k - n_obs; - temp1 = P_t_t1[k1 + j1 * n_state]; - for (int i = 0; i < n; i++) - if ((i < n_obs) || (i >= nb_diag + n_obs) || (j1 >= nb_diag)) - tmp[i + j1 * n] += temp1 * T[i + k * n]; - } - for (int k = max(j + 1, n_obs); k < n; k++) - { - int k1 = k - n_obs; - temp1 = P_t_t1[j1 + k1 * n_state]; - for (int i = 0; i < n; i++) - if ((i < n_obs) || (i >= nb_diag + n_obs) || (j1 >= nb_diag)) - tmp[i + j1 * n] += temp1 * T[i + k * n]; - } - }*/ for (int i = 0; i < n; i++) //int i = 0; for (int j = n_obs; j < n; j++) @@ -2902,7 +2811,6 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de for (vector::iterator it = v_index_KF.begin(); it != v_index_KF.end(); it++) KF_index_file.write(reinterpret_cast(&(*it)), sizeof(index_KF)); - //typedef pair, pair > index_KF_2; vector v_index_KF_2; int n_n_obs = n * n_obs; for (int i = 0; i < n; i++) @@ -4322,5 +4230,117 @@ DynamicModel::dynamicOnlyEquationsNbr() const 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; +} diff --git a/DynamicModel.hh b/DynamicModel.hh index d87093e7..835f09b7 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -24,6 +24,7 @@ using namespace std; #define ZERO_BAND 1e-8 #include +#include #include "StaticModel.hh" @@ -482,6 +483,8 @@ public: 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 diff --git a/DynareBison.yy b/DynareBison.yy index 6c76d416..bd9300e1 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -82,17 +82,17 @@ class ParsingDriver; #define yylex driver.lexer->lex } -%token AIM_SOLVER ANALYTIC_DERIVATION AR AUTOCORR -%token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION -%token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION -%token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA +%token AIM_SOLVER ANALYTIC_DERIVATION AR AUTOCORR TARB_MODE_COMPUTE +%token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION USE_TARB TARB_NEW_BLOCK_PROBABILITY +%token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION DR_DISPLAY_TOL HUGE_NUMBER +%token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA TARB_OPTIM %token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN %token BVAR_REPLIC BYTECODE ALL_VALUES_REQUIRED %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 %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 FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME +%token FILENAME DIRNAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME %token FLOAT_NUMBER DATES %token DEFAULT FIXED_POINT OPT_ALGO %token FORECAST K_ORDER_SOLVER INSTRUMENTS SHIFT MEAN STDEV VARIANCE MODE INTERVAL SHAPE DOMAINN @@ -1094,6 +1094,7 @@ stoch_simul_primary_options : o_dr_algo | o_dr_logarithmic_reduction_tol | o_dr_logarithmic_reduction_maxiter | o_irf_plot_threshold + | o_dr_display_tol ; stoch_simul_options : stoch_simul_primary_options @@ -1712,6 +1713,12 @@ estimation_options : o_datafile | o_filter_algorithm | o_proposal_approximation | o_distribution_approximation + | o_dirname + | o_huge_number + | o_use_tarb + | o_tarb_mode_compute + | o_tarb_new_block_probability + | o_tarb_optim ; list_optim_option : QUOTED_STRING COMMA QUOTED_STRING @@ -1724,6 +1731,16 @@ optim_options : list_optim_option | optim_options COMMA list_optim_option; ; +list_tarb_optim_option : QUOTED_STRING COMMA QUOTED_STRING + { driver.tarb_optim_options_string($1, $3); } + | QUOTED_STRING COMMA signed_number + { driver.tarb_optim_options_num($1, $3); } + ; + +tarb_optim_options : list_tarb_optim_option + | tarb_optim_options COMMA list_tarb_optim_option; + ; + varobs : VAROBS { driver.check_varobs(); } varobs_list ';'; varobs_list : varobs_list symbol @@ -1768,6 +1785,7 @@ osr_options : stoch_simul_primary_options | o_osr_tolf | o_opt_algo | o_optim + | o_huge_number ; osr : OSR ';' @@ -2546,6 +2564,8 @@ o_qz_zero_threshold : QZ_ZERO_THRESHOLD EQUAL non_negative_number { driver.optio 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 @@ -2612,6 +2632,7 @@ o_posterior_max_subsample_draws : POSTERIOR_MAX_SUBSAMPLE_DRAWS EQUAL INT_NUMBER 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_tarb_optim : TARB_OPTIM EQUAL '(' tarb_optim_options ')'; 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); }; @@ -2866,7 +2887,9 @@ o_equations : EQUATIONS EQUAL vec_int | EQUATIONS EQUAL vec_int_number { driver.option_vec_int("ms.equations",$3); } ; - +o_use_tarb : USE_TARB { driver.option_num("TaRB.use_TaRB", "1"); }; +o_tarb_mode_compute : TARB_MODE_COMPUTE EQUAL INT_NUMBER { driver.option_num("TaRB.mode_compute", $3); }; +o_tarb_new_block_probability : TARB_NEW_BLOCK_PROBABILITY EQUAL non_negative_number {driver.option_num("TaRB.new_block_probability",$3); }; 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); }; @@ -2964,6 +2987,7 @@ o_mcmc_jumping_covariance : MCMC_JUMPING_COVARIANCE EQUAL HESSIAN { driver.option_str("MCMC_jumping_covariance", $3); } ; 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"); }; diff --git a/DynareFlex.ll b/DynareFlex.ll index 0e7a31c1..5466487d 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -236,6 +236,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 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;} @@ -566,6 +567,12 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 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;} +use_tarb {return token::USE_TARB;} +tarb_mode_compute {return token::TARB_MODE_COMPUTE;} +tarb_new_block_probability {return token::TARB_NEW_BLOCK_PROBABILITY;} +tarb_optim {return token::TARB_OPTIM;} [\$][^$]*[\$] { strtok(yytext+1, "$"); diff --git a/DynareMain.cc b/DynareMain.cc index 19d773b8..9320a4af 100644 --- a/DynareMain.cc +++ b/DynareMain.cc @@ -38,7 +38,7 @@ 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, const string ¶llel_config_file, const string &cluster_name, bool parallel_slave_open_mode, - bool parallel_test, bool nostrict, FileOutputType output_mode, LanguageOutputType lang + bool parallel_test, bool nostrict, bool check_model_changes, FileOutputType output_mode, LanguageOutputType lang #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -49,7 +49,7 @@ usage() { cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [onlyclearglobals] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [nolog] [warn_uninit]" << " [console] [nograph] [nointeractive] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test] " - << " [-D[=]] [nostrict] [output=dynamic|first|second|third] [language=C|C++]" + << " [-D[=]] [nostrict] [fast] [output=dynamic|first|second|third] [language=C|C++]" #if defined(_WIN32) || defined(__CYGWIN32__) << " [cygwin] [msvc]" #endif @@ -97,6 +97,7 @@ main(int argc, char **argv) bool parallel_slave_open_mode = false; bool parallel_test = false; bool nostrict = false; + bool check_model_changes = false; map defines; FileOutputType output_mode = none; LanguageOutputType language = matlab; @@ -165,6 +166,8 @@ main(int argc, char **argv) parallel_test = true; else if (!strcmp(argv[arg], "nostrict")) nostrict = true; + else if (!strcmp(argv[arg], "fast")) + check_model_changes = true; else if (strlen(argv[arg]) >= 8 && !strncmp(argv[arg], "parallel", 8)) { parallel = true; @@ -285,7 +288,7 @@ main(int argc, char **argv) // 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, parallel_config_file, cluster_name, parallel_slave_open_mode, parallel_test, nostrict, output_mode, language + parallel, parallel_config_file, cluster_name, parallel_slave_open_mode, parallel_test, nostrict, check_model_changes, output_mode, language #if defined(_WIN32) || defined(__CYGWIN32__) , cygwin, msvc #endif diff --git a/DynareMain2.cc b/DynareMain2.cc index 376dd20a..fe1c6942 100644 --- a/DynareMain2.cc +++ b/DynareMain2.cc @@ -27,7 +27,7 @@ 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, const string ¶llel_config_file, const string &cluster_name, bool parallel_slave_open_mode, - bool parallel_test, bool nostrict, FileOutputType output_mode, LanguageOutputType language + bool parallel_test, bool nostrict, bool check_model_changes, FileOutputType output_mode, LanguageOutputType language #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -60,11 +60,12 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear if (output_mode != none) mod_file->writeExternalFiles(basename, output_mode, language); else - mod_file->writeOutputFiles(basename, clear_all, clear_global, no_log, no_warn, console, nograph, nointeractive, config_file + mod_file->writeOutputFiles(basename, clear_all, clear_global, no_log, no_warn, console, nograph, + nointeractive, config_file, check_model_changes #if defined(_WIN32) || defined(__CYGWIN32__) - , cygwin, msvc + , cygwin, msvc #endif - ); + ); delete mod_file; diff --git a/ExprNode.cc b/ExprNode.cc index 66cd230e..a828765d 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -308,6 +308,12 @@ NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type, 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) { @@ -577,6 +583,12 @@ VariableNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, t datatree.local_variables_table[symb_id]->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block); } +bool +VariableNode::containsExternalFunction() const +{ + return false; +} + void VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -1726,6 +1738,12 @@ UnaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, te arg->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block); } +bool +UnaryOpNode::containsExternalFunction() const +{ + return arg->containsExternalFunction(); +} + void UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -2904,6 +2922,13 @@ BinaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, t } } +bool +BinaryOpNode::containsExternalFunction() const +{ + return arg1->containsExternalFunction() + || arg2->containsExternalFunction(); +} + void BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -3990,6 +4015,14 @@ TrinaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, } } +bool +TrinaryOpNode::containsExternalFunction() const +{ + return arg1->containsExternalFunction() + || arg2->containsExternalFunction() + || arg3->containsExternalFunction(); +} + void TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -4333,15 +4366,6 @@ AbstractExternalFunctionNode::AbstractExternalFunctionNode(DataTree &datatree_ar { } -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; -} - void AbstractExternalFunctionNode::prepareForDerivation() { @@ -4372,20 +4396,6 @@ AbstractExternalFunctionNode::computeDerivative(int deriv_id) return composeDerivatives(dargs); } -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; -} - expr_t AbstractExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map &recursive_variables) { @@ -4397,76 +4407,6 @@ AbstractExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map &reference_count, - temporary_terms_t &temporary_terms, - bool is_matlab) const -{ - temporary_terms.insert(const_cast(this)); -} - -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::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; - } -} - -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 || 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); -} - unsigned int AbstractExternalFunctionNode::compileExternalFunctionArguments(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, @@ -4480,184 +4420,6 @@ AbstractExternalFunctionNode::compileExternalFunctionArguments(ostream &CompileC return (arguments.size()); } -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::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::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::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 AbstractExternalFunctionNode::collectDynamicVariables(SymbolType type_arg, set > &result) const { @@ -4686,56 +4448,6 @@ AbstractExternalFunctionNode::eval(const eval_context_t &eval_context) const thr throw EvalExternalFunctionException(); } -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)); -} - -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); -} - -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::cloneDynamicReindex(DataTree &dynamic_datatree, SymbolTable &orig_symbol_table) const -{ - vector dynamic_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - dynamic_arguments.push_back((*it)->cloneDynamicReindex(dynamic_datatree, orig_symbol_table)); - return dynamic_datatree.AddExternalFunction(dynamic_datatree.symbol_table.getID(orig_symbol_table.getName(symb_id)), - dynamic_arguments); -} - int AbstractExternalFunctionNode::maxEndoLead() const { @@ -4858,12 +4570,6 @@ AbstractExternalFunctionNode::differentiateForwardVars(const vector &sub return buildSimilarExternalFunctionNode(arguments_subst, datatree); } -expr_t -ExternalFunctionNode::buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const -{ - return alt_datatree.AddExternalFunction(symb_id, alt_args); -} - bool AbstractExternalFunctionNode::alreadyWrittenAsTefTerm(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const { @@ -4936,10 +4642,342 @@ 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::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; +} + +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, + temporary_terms_t &temporary_terms, + bool is_matlab) const +{ + temporary_terms.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::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 || 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; + } + } +} + +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); +} + +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::cloneDynamicReindex(DataTree &dynamic_datatree, SymbolTable &orig_symbol_table) const +{ + vector dynamic_arguments; + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + dynamic_arguments.push_back((*it)->cloneDynamicReindex(dynamic_datatree, orig_symbol_table)); + return dynamic_datatree.AddExternalFunction(dynamic_datatree.symbol_table.getID(orig_symbol_table.getName(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, diff --git a/ExprNode.hh b/ExprNode.hh index b6c7b9b9..bef4a415 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -187,6 +187,9 @@ public: */ 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; @@ -444,6 +447,7 @@ public: }; 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 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); @@ -490,6 +494,7 @@ 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 bool containsExternalFunction() const; virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, @@ -557,6 +562,7 @@ public: virtual void prepareForDerivation(); virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const; virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) 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; @@ -636,6 +642,7 @@ public: virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const; virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const; virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) 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; @@ -731,6 +738,7 @@ public: virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const; virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const; virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) 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; @@ -803,6 +811,7 @@ public: virtual void prepareForDerivation(); virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) 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 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; diff --git a/ModFile.cc b/ModFile.cc index 8824d84b..0592c620 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -490,55 +490,55 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output) // 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(); + { + 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; - const bool paramsDerivatives = mod_file_struct.identification_present - || mod_file_struct.estimation_analytic_derivation; - static_model.computingPass(global_eval_context, no_tmp_terms, static_hessian, - false, paramsDerivatives, block, byte_code); - } + const bool static_hessian = mod_file_struct.identification_present + || mod_file_struct.estimation_analytic_derivation; + const bool paramsDerivatives = mod_file_struct.identification_present + || mod_file_struct.estimation_analytic_derivation; + static_model.computingPass(global_eval_context, no_tmp_terms, static_hessian, + false, paramsDerivatives, block, byte_code); + } // 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, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code); - 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 - || output == second - || output == third; - bool thirdDerivatives = mod_file_struct.order_option == 3 - || mod_file_struct.estimation_analytic_derivation - || output == third; - bool paramsDerivatives = mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation; - dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivatives, global_eval_context, no_tmp_terms, block, use_dll, byte_code); - } - } - else // No computing task requested, compute derivatives up to 2nd order by default - dynamic_model.computingPass(true, true, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code); + || 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, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code); + 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 + || output == second + || output == third; + bool thirdDerivatives = mod_file_struct.order_option == 3 + || mod_file_struct.estimation_analytic_derivation + || output == third; + bool paramsDerivatives = mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation; + dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivatives, global_eval_context, no_tmp_terms, block, use_dll, byte_code); + } + } + else // No computing task requested, compute derivatives up to 2nd order by default + dynamic_model.computingPass(true, true, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code); } for (vector::iterator it = statements.begin(); @@ -547,7 +547,8 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output) } 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 +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 #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -595,6 +596,9 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo << "global M_ oo_ options_ ys0_ ex0_ estimation_info" << endl << "options_ = [];" << endl << "M_.fname = '" << basename << "';" << endl + << "M_.dynare_version = '" << PACKAGE_VERSION << "';" << endl + << "oo_.dynare_version = '" << PACKAGE_VERSION << "';" << endl + << "options_.dynare_version = '" << PACKAGE_VERSION << "';" << endl << "%" << endl << "% Some global variables initialization" << endl << "%" << endl; @@ -613,7 +617,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo if (nointeractive) mOutputFile << "options_.nointeractive = 1;" << endl; - cout << "Processing outputs ..."; + cout << "Processing outputs ..." << endl; symbol_table.writeOutput(mOutputFile); @@ -667,18 +671,25 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo << " error('DYNARE: Can''t find bytecode DLL. Please compile it or remove the ''bytecode'' option.')" << endl << "end" << endl; - // Erase possible remnants of previous runs - unlink((basename + "_dynamic.m").c_str()); - unlink((basename + "_dynamic.cod").c_str()); - unlink((basename + "_dynamic.bin").c_str()); + 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()); + 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; @@ -713,55 +724,22 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo #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) { - mOutputFile << "if ~exist('OCTAVE_VERSION')" << endl; - // Some mex commands are enclosed in an eval(), because otherwise it will make Octave fail #if defined(_WIN32) || defined(__CYGWIN32__) if (msvc) // MATLAB/Windows + Microsoft Visual C++ - mOutputFile << " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Dynamic\" " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Static\" " << basename << "_static.c "<< basename << "_static_mex.c')" << endl; + mOutputFile << "dyn_mex('msvc', '" << basename << "', " << !check_model_changes << ")" << endl; else if (cygwin) // MATLAB/Windows + Cygwin g++ - mOutputFile << " eval('mex -O PRELINK_CMDS1=\"echo EXPORTS > mex.def & echo mexFunction >> mex.def & echo Dynamic >> mex.def\" " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O PRELINK_CMDS1=\"echo EXPORTS > mex.def & echo mexFunction >> mex.def & echo Static >> mex.def\" " << basename << "_static.c "<< basename << "_static_mex.c')" << endl; + mOutputFile << "dyn_mex('cygwin', '" << basename << "', " << !check_model_changes << ")" << endl; else mOutputFile << " error('When using the USE_DLL option, you must give either ''cygwin'' or ''msvc'' option to the ''dynare'' command')" << endl; #else -# ifdef __linux__ - // MATLAB/Linux - mOutputFile << " if matlab_ver_less_than('8.3')" << endl - << " eval('mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' " << basename << "_static.c "<< basename << "_static_mex.c')" << endl - << " else" << endl - << " eval('mex -O LINKEXPORT='''' " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LINKEXPORT='''' " << basename << "_static.c "<< basename << "_static_mex.c')" << endl - << " end" << endl; -# else // MacOS - // MATLAB/MacOS - mOutputFile << " if matlab_ver_less_than('8.3')" << endl - << " if matlab_ver_less_than('8.1')" << endl - << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " - << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " - << basename << "_static.c " << basename << "_static_mex.c')" << endl - << " else" << endl - << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$MW_SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " - << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$MW_SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " - << basename << "_static.c " << basename << "_static_mex.c')" << endl - << " end" << endl - << " else" << endl - << " eval('mex -O LINKEXPORT='''' " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LINKEXPORT='''' " << basename << "_static.c "<< basename << "_static_mex.c')" << endl - << " end" << endl; -# endif + // other configurations + mOutputFile << "dyn_mex('', '" << basename << "', " << !check_model_changes << ")" << endl; #endif - mOutputFile << "else" << endl // Octave - << " mex " << basename << "_dynamic.c " << basename << "_dynamic_mex.c" << endl - << " mex " << basename << "_static.c " << basename << "_static_mex.c" << endl - << "end" << endl; } // Add path for block option with M-files @@ -842,22 +820,24 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo mOutputFile.close(); - // Create static and dynamic files - if (dynamic_model.equation_number() > 0) + if (hasModelChanged) { - if (!no_static) - { - static_model.writeStaticFile(basename, block, byte_code, use_dll); - static_model.writeParamsDerivativesFile(basename); - } + // Create static and dynamic files + if (dynamic_model.equation_number() > 0) + { + if (!no_static) + { + static_model.writeStaticFile(basename, block, byte_code, use_dll); + static_model.writeParamsDerivativesFile(basename); + } - dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option); - dynamic_model.writeParamsDerivativesFile(basename); + dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option); + dynamic_model.writeParamsDerivativesFile(basename); + } + + // Create steady state file + steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present); } - - // Create steady state file - steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present); - + cout << "done" << endl; } - diff --git a/ModFile.hh b/ModFile.hh index 722ea534..bf363668 100644 --- a/ModFile.hh +++ b/ModFile.hh @@ -24,6 +24,8 @@ using namespace std; #include #include +#include +#include #include "SymbolTable.hh" #include "NumericalConstants.hh" @@ -37,6 +39,11 @@ using namespace std; #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 { @@ -138,7 +145,8 @@ public: \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? */ - 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 + 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 #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -153,6 +161,8 @@ public: //! Writes Cpp output files only => No further Matlab processing void writeCCOutputFiles(const string &basename) const; void writeModelCC(const string &basename) const; + + void computeChecksum(); }; #endif // ! MOD_FILE_HH diff --git a/ParsingDriver.cc b/ParsingDriver.cc index 67c4be45..ba541ec8 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -1630,6 +1630,34 @@ ParsingDriver::optim_options_num(string *name, string *value) delete value; } +void +ParsingDriver::tarb_optim_options_helper(const string &name) +{ + if (options_list.string_options.find("TaRB.optim_opt") == options_list.string_options.end()) + options_list.string_options["TaRB.optim_opt"] = ""; + else + options_list.string_options["TaRB.optim_opt"] += ","; + options_list.string_options["TaRB.optim_opt"] += "''" + name + "'',"; +} + +void +ParsingDriver::tarb_optim_options_string(string *name, string *value) +{ + tarb_optim_options_helper(*name); + options_list.string_options["TaRB.optim_opt"] += "''" + *value + "''"; + delete name; + delete value; +} + +void +ParsingDriver::tarb_optim_options_num(string *name, string *value) +{ + tarb_optim_options_helper(*name); + options_list.string_options["TaRB.optim_opt"] += *value; + delete name; + delete value; +} + void ParsingDriver::check_varobs() { diff --git a/ParsingDriver.hh b/ParsingDriver.hh index d4ebc05d..dd93276c 100644 --- a/ParsingDriver.hh +++ b/ParsingDriver.hh @@ -98,6 +98,7 @@ private: //! 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 tarb_optim_options_helper(const string &name); //! Stores temporary symbol table SymbolList symbol_list; @@ -443,6 +444,10 @@ public: void optim_options_string(string *name, string *value); //! Adds an optimization option (numeric value) void optim_options_num(string *name, string *value); + //! Adds a TaRB optimization option (string value) + void tarb_optim_options_string(string *name, string *value); + //! Adds a TaRB optimization option (numeric value) + void tarb_optim_options_num(string *name, string *value); //! Check that no observed variable has yet be defined void check_varobs(); //! Add a new observed variable diff --git a/StaticModel.cc b/StaticModel.cc index 09fb9261..045e6336 100644 --- a/StaticModel.cc +++ b/StaticModel.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 Dynare Team + * Copyright (C) 2003-2015 Dynare Team * * This file is part of Dynare. * @@ -1927,9 +1927,16 @@ void StaticModel::writeAuxVarRecursiveDefinitions(const string &basename) const << "% from model file (.mod)" << endl << endl; + 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])->writeOutput(output, oMatlabStaticModel); + dynamic_cast(aux_equations[i])->writeOutput(output, oMatlabStaticModel, temporary_terms, tef_terms); output << ";" << endl; } }