diff --git a/CodeInterpreter.hh b/CodeInterpreter.hh index e4e3e103..d39567b8 100644 --- a/CodeInterpreter.hh +++ b/CodeInterpreter.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2013 Dynare Team + * Copyright (C) 2007-2014 Dynare Team * * This file is part of Dynare. * @@ -245,7 +245,8 @@ enum PriorDistributions eInvGamma = 4, eInvGamma1 = 4, eUniform = 5, - eInvGamma2 = 6 + eInvGamma2 = 6, + eDirichlet = 7 }; struct Block_contain_type diff --git a/ComputingTasks.cc b/ComputingTasks.cc index d3c71160..b2aed955 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -94,17 +94,45 @@ SimulStatement::SimulStatement(const OptionsList &options_list_arg) : void SimulStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) { - mod_file_struct.simul_present = true; - - // The following is necessary to allow shocks+endval+simul in a loop - mod_file_struct.shocks_present_but_simul_not_yet = false; + mod_file_struct.perfect_foresight_solver_present = true; } void SimulStatement::writeOutput(ostream &output, const string &basename) const { options_list.writeOutput(output); - output << "simul();\n"; + output << "perfect_foresight_setup;" << endl + << "perfect_foresight_solver;" << endl; +} + +PerfectForesightSetupStatement::PerfectForesightSetupStatement(const OptionsList &options_list_arg) : + options_list(options_list_arg) +{ +} + +void +PerfectForesightSetupStatement::writeOutput(ostream &output, const string &basename) const +{ + options_list.writeOutput(output); + output << "perfect_foresight_setup;" << endl; +} + +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; +} + +void +PerfectForesightSolverStatement::writeOutput(ostream &output, const string &basename) const +{ + options_list.writeOutput(output); + output << "perfect_foresight_solver;" << endl; } StochSimulStatement::StochSimulStatement(const SymbolList &symbol_list_arg, @@ -160,6 +188,54 @@ ForecastStatement::writeOutput(ostream &output, const string &basename) const output << "info = dyn_forecast(var_list_,'simul');" << endl; } +RamseyModelStatement::RamseyModelStatement(const SymbolList &symbol_list_arg, + const OptionsList &options_list_arg) : + symbol_list(symbol_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) 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 + output << "options_.ramsey_policy = 1;\n"; +} + RamseyPolicyStatement::RamseyPolicyStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg) : symbol_list(symbol_list_arg), @@ -170,6 +246,10 @@ RamseyPolicyStatement::RamseyPolicyStatement(const SymbolList &symbol_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 @@ -179,9 +259,9 @@ RamseyPolicyStatement::checkPass(ModFileStructure &mod_file_struct, WarningConso if (it != options_list.num_options.end()) { int order = atoi(it->second.c_str()); - if (order > 1) + if (order > 2) { - cerr << "ERROR: ramsey_policy: order > 1 is not yet implemented" << endl; + 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); @@ -261,11 +341,9 @@ DiscretionaryPolicyStatement::writeOutput(ostream &output, const string &basenam } EstimationStatement::EstimationStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg, - const SymbolTable &symbol_table_arg) : + const OptionsList &options_list_arg) : symbol_list(symbol_list_arg), - options_list(options_list_arg), - symbol_table(symbol_table_arg) + options_list(options_list_arg) { } @@ -337,6 +415,20 @@ EstimationStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsoli 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 @@ -512,6 +604,12 @@ EstimatedParamsStatement::checkPass(ModFileStructure &mod_file_struct, WarningCo } } } + + // 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 @@ -574,15 +672,27 @@ EstimatedParamsStatement::writeOutput(ostream &output, const string &basename) c } EstimatedParamsInitStatement::EstimatedParamsInitStatement(const vector &estim_params_list_arg, - const SymbolTable &symbol_table_arg) : + const SymbolTable &symbol_table_arg, + const bool use_calibration_arg) : estim_params_list(estim_params_list_arg), - symbol_table(symbol_table_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) const { + if (use_calibration) + output << "options_.use_calibration_initialization = 1;" << endl; + vector::const_iterator it; for (it = estim_params_list.begin(); it != estim_params_list.end(); it++) @@ -696,7 +806,8 @@ EstimatedParamsBoundsStatement::writeOutput(ostream &output, const string &basen { if (symb_type == eExogenous) { - output << "tmp1 = find((estim_params_.corrx(:,1)==" << symb_id << ")) & (estim_params_.corrx(:,2)==" << symbol_table.getTypeSpecificID(it->name2)+1 << ");" << endl; + 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); @@ -708,7 +819,8 @@ EstimatedParamsBoundsStatement::writeOutput(ostream &output, const string &basen } else if (symb_type == eEndogenous) { - output << "tmp1 = find((estim_params_.corrn(:,1)==" << symb_id << ")) & (estim_params_.corrn(:,2)==" << symbol_table.getTypeSpecificID(it->name2)+1 << ";" << endl; + 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); @@ -802,7 +914,7 @@ OsrStatement::writeOutput(ostream &output, const string &basename) const { options_list.writeOutput(output); symbol_list.writeOutput("var_list_", output); - output << "osr(var_list_,osr_params_,obj_var_,optim_weights_);\n"; + output << "oo_.osr = osr(var_list_,osr_params_,obj_var_,optim_weights_);\n"; } OptimWeightsStatement::OptimWeightsStatement(const var_weights_t &var_weights_arg, @@ -936,7 +1048,7 @@ PlannerObjectiveStatement::getPlannerObjective() const void PlannerObjectiveStatement::computingPass() { - model_tree->computingPass(eval_context_t(), false, true, false, false, false); + model_tree->computingPass(eval_context_t(), false, true, true, false, false, false); } void @@ -1306,7 +1418,7 @@ void ConditionalForecastStatement::writeOutput(ostream &output, const string &basename) const { options_list.writeOutput(output, "options_cond_fcst_"); - output << "imcforecast(constrained_paths_, constrained_vars_, options_cond_fcst_, constrained_perfect_foresight_);" << endl; + output << "imcforecast(constrained_paths_, constrained_vars_, options_cond_fcst_);" << endl; } PlotConditionalForecastStatement::PlotConditionalForecastStatement(int periods_arg, const SymbolList &symbol_list_arg) : @@ -1580,6 +1692,9 @@ MarkovSwitchingStatement::checkPass(ModFileStructure &mod_file_struct, WarningCo } } } + + if (options_list.symbol_list_options.find("ms.parameters") != options_list.symbol_list_options.end()) + mod_file_struct.ms_dsge_present = true; } void @@ -1617,6 +1732,57 @@ MarkovSwitchingStatement::writeOutput(ostream &output, const string &basename) c << 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; +} + SvarStatement::SvarStatement(const OptionsList &options_list_arg) : options_list(options_list_arg) { @@ -1758,10 +1924,10 @@ SubsamplesStatement::writeOutput(ostream &output, const string &basename) const 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 = dynDate('" - << it->second.first << "');" << endl - << "estimation_info.subsamples(subsamples_indx).range(" << map_indx << ").date2 = dynDate('" - << it->second.second << "');" << 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); @@ -1915,6 +2081,14 @@ BasicPriorStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsoli } } +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 { @@ -1972,6 +2146,76 @@ BasicPriorStatement::writePriorOutput(ostream &output, string &lhs_field, const writeCommonOutput(output, lhs_field); } +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 eNoShape: + assert(prior_shape != eNoShape); + } +} + PriorStatement::PriorStatement(const string &name_arg, const string &subsample_name_arg, const PriorDistributions &prior_shape_arg, @@ -1991,6 +2235,22 @@ PriorStatement::writeOutput(ostream &output, const string &basename) const writePriorOutput(output, lhs_field, ""); } +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, @@ -2015,6 +2275,31 @@ StdPriorStatement::writeOutput(ostream &output, const string &basename) const writePriorOutput(output, lhs_field, ""); } +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, @@ -2076,6 +2361,38 @@ PriorEqualStatement::PriorEqualStatement(const string &to_declaration_type_arg, { } +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; +} + void PriorEqualStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) { @@ -2176,6 +2493,14 @@ BasicOptionsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConso { } +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 { @@ -2203,6 +2528,16 @@ BasicOptionsStatement::writeCommonOutputHelper(ostream &output, const string &fi 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 { @@ -2234,6 +2569,15 @@ OptionsStatement::writeOutput(ostream &output, const string &basename) const writeOptionsOutput(output, lhs_field, ""); } +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, @@ -2256,6 +2600,26 @@ StdOptionsStatement::writeOutput(ostream &output, const string &basename) const writeOptionsOutput(output, lhs_field, ""); } +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, @@ -2402,6 +2766,12 @@ CalibSmootherStatement::CalibSmootherStatement(const SymbolList &symbol_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) const { @@ -2439,8 +2809,8 @@ ExtendedPathStatement::writeOutput(ostream &output, const string &basename) cons if (it->first != string("periods")) output << "options_." << it->first << " = " << it->second << ";" << endl; - output << "oo_.endo_simul = [ oo_.steady_state, extended_path([], " << options_list.num_options.find("periods")->second - << ") ];" << endl + output << "extended_path([], " << options_list.num_options.find("periods")->second + << ");" << endl << "oo_.exo_simul = oo_.ep.shocks;" << endl; } @@ -2453,3 +2823,42 @@ ModelDiagnosticsStatement::writeOutput(ostream &output, const string &basename) { output << "model_diagnostics(M_,options_,oo_);" << endl; } + +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; +} + +Smoother2histvalStatement::Smoother2histvalStatement(const OptionsList &options_list_arg) : + options_list(options_list_arg) +{ +} + +void +Smoother2histvalStatement::writeOutput(ostream &output, const string &basename) const +{ + options_list.writeOutput(output, "options_smoother2histval"); + output << "smoother2histval(options_smoother2histval);" << endl; +} diff --git a/ComputingTasks.hh b/ComputingTasks.hh index 926e082d..b1a009ff 100644 --- a/ComputingTasks.hh +++ b/ComputingTasks.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2012 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -58,6 +58,25 @@ public: virtual void writeOutput(ostream &output, const string &basename) 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) 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) const; +}; + class ModelInfoStatement : public Statement { private: @@ -91,6 +110,18 @@ public: virtual void writeOutput(ostream &output, const string &basename) const; }; +class RamseyModelStatement : public Statement +{ +private: + const SymbolList symbol_list; + const OptionsList options_list; +public: + RamseyModelStatement(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) const; +}; + class RamseyPolicyStatement : public Statement { private: @@ -157,11 +188,9 @@ class EstimationStatement : public Statement private: const SymbolList symbol_list; const OptionsList options_list; - const SymbolTable &symbol_table; public: EstimationStatement(const SymbolList &symbol_list_arg, - const OptionsList &options_list_arg, - const SymbolTable &symbol_table); + const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename) const; }; @@ -290,9 +319,12 @@ 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 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) const; }; @@ -516,6 +548,7 @@ private: 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) const; }; @@ -569,6 +602,7 @@ public: MarkovSwitchingStatement(const OptionsList &options_list_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename) const; + virtual void writeCOutput(ostream &output, const string &basename); }; class SvarStatement : public Statement @@ -656,6 +690,15 @@ protected: 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; }; class PriorStatement : public BasicPriorStatement @@ -667,6 +710,7 @@ public: const expr_t &variance_arg, const OptionsList &options_list_arg); virtual void writeOutput(ostream &output, const string &basename) const; + virtual void writeCOutput(ostream &output, const string &basename); }; class StdPriorStatement : public BasicPriorStatement @@ -681,6 +725,7 @@ public: const OptionsList &options_list_arg, const SymbolTable &symbol_table_arg); virtual void writeOutput(ostream &output, const string &basename) const; + virtual void writeCOutput(ostream &output, const string &basename); }; class CorrPriorStatement : public BasicPriorStatement @@ -698,6 +743,7 @@ public: const SymbolTable &symbol_table_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename) const; + virtual void writeCOutput(ostream &output, const string &basename); }; class PriorEqualStatement : public Statement @@ -743,6 +789,10 @@ protected: 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; }; class OptionsStatement : public BasicOptionsStatement @@ -750,6 +800,7 @@ 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) const; + virtual void writeCOutput(ostream &output, const string &basename); }; class StdOptionsStatement : public BasicOptionsStatement @@ -762,6 +813,7 @@ public: const OptionsList &options_list_arg, const SymbolTable &symbol_table_arg); virtual void writeOutput(ostream &output, const string &basename) const; + virtual void writeCOutput(ostream &output, const string &basename); }; class CorrOptionsStatement : public BasicOptionsStatement @@ -776,6 +828,7 @@ public: const SymbolTable &symbol_table_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename) const; + virtual void writeCOutput(ostream &output, const string &basename); }; class OptionsEqualStatement : public Statement @@ -812,4 +865,13 @@ public: virtual void writeOutput(ostream &output, const string &basename) 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) const; +}; + #endif diff --git a/DataTree.cc b/DataTree.cc index 629365fb..f95ab9ca 100644 --- a/DataTree.cc +++ b/DataTree.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2012 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -512,7 +512,7 @@ DataTree::AddExternalFunction(int symb_id, const vector &arguments) } expr_t -DataTree::AddFirstDerivExternalFunctionNode(int top_level_symb_id, const vector &arguments, int input_index) +DataTree::AddFirstDerivExternalFunction(int top_level_symb_id, const vector &arguments, int input_index) { assert(symbol_table.getType(top_level_symb_id) == eExternalFunction); @@ -526,7 +526,7 @@ DataTree::AddFirstDerivExternalFunctionNode(int top_level_symb_id, const vector< } expr_t -DataTree::AddSecondDerivExternalFunctionNode(int top_level_symb_id, const vector &arguments, int input_index1, int input_index2) +DataTree::AddSecondDerivExternalFunction(int top_level_symb_id, const vector &arguments, int input_index1, int input_index2) { assert(symbol_table.getType(top_level_symb_id) == eExternalFunction); diff --git a/DataTree.hh b/DataTree.hh index 3540a86d..19712e9b 100644 --- a/DataTree.hh +++ b/DataTree.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2012 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -44,6 +44,7 @@ class DataTree friend class UnaryOpNode; friend class BinaryOpNode; friend class TrinaryOpNode; + friend class AbstractExternalFunctionNode; friend class ExternalFunctionNode; friend class FirstDerivExternalFunctionNode; friend class SecondDerivExternalFunctionNode; @@ -68,10 +69,16 @@ protected: 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; @@ -202,9 +209,9 @@ public: //! 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 AddFirstDerivExternalFunctionNode(int top_level_symb_id, const vector &arguments, int input_index); + expr_t AddFirstDerivExternalFunction(int top_level_symb_id, const vector &arguments, int input_index); //! Adds an external function node for the second derivative of an external function - expr_t AddSecondDerivExternalFunctionNode(int top_level_symb_id, const vector &arguments, int input_index1, int input_index2); + expr_t AddSecondDerivExternalFunction(int top_level_symb_id, const vector &arguments, int input_index1, int input_index2); //! Checks if a given symbol is used somewhere in the data tree bool isSymbolUsed(int symb_id) const; //! Checks if a given unary op is used somewhere in the data tree diff --git a/DynamicModel.cc b/DynamicModel.cc index 52eabbed..7dfc7d7e 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -210,13 +210,15 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const ostringstream tmp_output, tmp1_output, global_output; expr_t lhs = NULL, rhs = NULL; BinaryOpNode *eq_node; - ostringstream Uf[symbol_table.endo_nbr()]; + 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) @@ -458,7 +460,7 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const 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) + if (dynamic_cast(*it) != NULL) (*it)->writeExternalFunctionOutput(output, local_output_type, tt2, tef_terms); output << " " << sps; @@ -536,7 +538,9 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const 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; - Uf[equation_ID] << " b(" << i+1-block_recursive << "+Per_J_) = -residual(" << i+1-block_recursive << ", it_)"; + 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: @@ -708,21 +712,24 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const if (eq >= block_recursive && var >= block_recursive) { if (lag == 0) - Uf[eqr] << "+g1(" << eq+1-block_recursive - << "+Per_J_, " << var+1-block_recursive - << "+Per_K_)*y(it_, " << varr+1 << ")"; + Ufoss << "+g1(" << eq+1-block_recursive + << "+Per_J_, " << var+1-block_recursive + << "+Per_K_)*y(it_, " << varr+1 << ")"; else if (lag == 1) - Uf[eqr] << "+g1(" << eq+1-block_recursive - << "+Per_J_, " << var+1-block_recursive - << "+Per_y_)*y(it_+1, " << varr+1 << ")"; + Ufoss << "+g1(" << eq+1-block_recursive + << "+Per_J_, " << var+1-block_recursive + << "+Per_y_)*y(it_+1, " << varr+1 << ")"; else if (lag > 0) - Uf[eqr] << "+g1(" << eq+1-block_recursive - << "+Per_J_, " << var+1-block_recursive - << "+y_size*(it_+" << lag-1 << "))*y(it_+" << lag << ", " << varr+1 << ")"; - else if (lag < 0) - Uf[eqr] << "+g1(" << eq+1-block_recursive - << "+Per_J_, " << var+1-block_recursive - << "+y_size*(it_" << lag-1 << "))*y(it_" << lag << ", " << varr+1 << ")"; + 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_) = "; @@ -751,7 +758,7 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const for (unsigned int i = 0; i < block_size; i++) { if (i >= block_recursive) - output << " " << Uf[getBlockEquationID(block, i)].str() << ";\n"; + output << " " << Uf[getBlockEquationID(block, i)] << ";\n"; #ifdef CONDITION output << " if (fabs(condition(" << i+1 << "))(*it) != NULL) + 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)); @@ -1518,14 +1525,14 @@ DynamicModel::writeDynamicMFile(const string &dynamic_basename) const << "% residual [M_.endo_nbr by 1] double vector of residuals of the dynamic model equations in order of " << endl << "% declaration of the equations" << endl << "% g1 [M_.endo_nbr by #dynamic variables] double Jacobian matrix of the dynamic model equations;" << endl - << "% columns: equations in order of declaration" << endl - << "% rows: variables in order stored in M_.lead_lag_incidence" << endl + << "% rows: equations in order of declaration" << endl + << "% columns: variables in order stored in M_.lead_lag_incidence" << endl << "% g2 [M_.endo_nbr by (#dynamic variables)^2] double Hessian matrix of the dynamic model equations;" << endl - << "% columns: equations in order of declaration" << endl - << "% rows: variables in order stored in M_.lead_lag_incidence" << endl + << "% rows: equations in order of declaration" << endl + << "% columns: variables in order stored in M_.lead_lag_incidence" << endl << "% g3 [M_.endo_nbr by (#dynamic variables)^3] double Third order derivative matrix of the dynamic model equations;" << endl - << "% columns: equations in order of declaration" << endl - << "% rows: variables in order stored in M_.lead_lag_incidence" << endl + << "% rows: equations in order of declaration" << endl + << "% columns: variables in order stored in M_.lead_lag_incidence" << endl << "%" << endl << "%" << endl << "% Warning : this file is generated automatically by Dynare" << endl @@ -1889,7 +1896,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri << " disp (['MODEL SIMULATION: (method=' mthd ')']) ;" << endl << " fprintf('\\n') ;" << endl << " periods=options_.periods;" << endl - << " maxit_=options_.maxit_;" << endl + << " maxit_=options_.simul.maxit;" << endl << " solve_tolf=options_.solve_tolf;" << endl << " y=oo_.endo_simul';" << endl << " x=oo_.exo_simul;" << endl; @@ -1988,7 +1995,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri 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_.maxit_, options_.solve_tolf, options_.slowc, " << cutoff << ", options_.stack_solve_algo, 1, 1, 0);\n"; + <<", 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"; @@ -2018,7 +2025,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri 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_.maxit_, options_.solve_tolf, options_.slowc, " << cutoff << ", options_.stack_solve_algo, 1, 1, 0);\n"; + <<", 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"; @@ -2043,12 +2050,12 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri mDynamicModelFile << " else\n"; mDynamicModelFile << " blck_num = 1;\n"; mDynamicModelFile << " end;\n"; - mDynamicModelFile << " y = solve_two_boundaries('" << dynamic_basename << "_" << block + 1 << "'" + 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_.maxit_, options_.solve_tolf, options_.slowc, " << cutoff << ", options_.stack_solve_algo);\n"; + <<", blck_num, y_kmin, options_.simul.maxit, options_.solve_tolf, options_.slowc, " << cutoff << ", options_.stack_solve_algo, 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"; @@ -2913,26 +2920,23 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de output << "M_.exo_names_orig_ord = [1:" << symbol_table.exo_nbr() << "];" << endl << "M_.maximum_lag = " << max_lag << ";" << endl << "M_.maximum_lead = " << max_lead << ";" << endl; - if (symbol_table.endo_nbr()) - { - output << "M_.maximum_endo_lag = " << max_endo_lag << ";" << endl - << "M_.maximum_endo_lead = " << max_endo_lead << ";" << endl - << "oo_.steady_state = zeros(" << symbol_table.endo_nbr() << ", 1);" << endl; - } - if (symbol_table.exo_nbr()) - { - output << "M_.maximum_exo_lag = " << max_exo_lag << ";" << endl - << "M_.maximum_exo_lead = " << max_exo_lead << ";" << endl - << "oo_.exo_steady_state = zeros(" << symbol_table.exo_nbr() << ", 1);" << endl; - } + + output << "M_.maximum_endo_lag = " << max_endo_lag << ";" << endl + << "M_.maximum_endo_lead = " << max_endo_lead << ";" << endl + << "oo_.steady_state = zeros(" << symbol_table.endo_nbr() << ", 1);" << endl; + + output << "M_.maximum_exo_lag = " << max_exo_lag << ";" << endl + << "M_.maximum_exo_lead = " << max_exo_lead << ";" << endl + << "oo_.exo_steady_state = zeros(" << symbol_table.exo_nbr() << ", 1);" << endl; + if (symbol_table.exo_det_nbr()) { output << "M_.maximum_exo_det_lag = " << max_exo_det_lag << ";" << endl << "M_.maximum_exo_det_lead = " << max_exo_det_lead << ";" << endl << "oo_.exo_det_steady_state = zeros(" << symbol_table.exo_det_nbr() << ", 1);" << endl; } - if (symbol_table.param_nbr()) - output << "M_.params = NaN(" << symbol_table.param_nbr() << ", 1);" << endl; + + output << "M_.params = NaN(" << symbol_table.param_nbr() << ", 1);" << endl; // Write number of non-zero derivatives // Use -1 if the derivatives have not been computed @@ -3423,9 +3427,8 @@ DynamicModel::cloneDynamic(DynamicModel &dynamic_model) const dynamic_model.AddLocalVariable(it->first, it->second->cloneDynamic(dynamic_model)); // Convert equations - for (vector::const_iterator it = equations.begin(); - it != equations.end(); it++) - dynamic_model.addEquation((*it)->cloneDynamic(dynamic_model)); + for (size_t i = 0; i < equations.size(); i++) + dynamic_model.addEquation(equations[i]->cloneDynamic(dynamic_model), equations_lineno[i]); // Convert auxiliary equations for (deque::const_iterator it = aux_equations.begin(); @@ -3433,18 +3436,18 @@ DynamicModel::cloneDynamic(DynamicModel &dynamic_model) const dynamic_model.addAuxEquation((*it)->cloneDynamic(dynamic_model)); // Convert static_only equations - for (vector::const_iterator it = static_only_equations.begin(); - it != static_only_equations.end(); it++) - dynamic_model.addStaticOnlyEquation((*it)->cloneDynamic(dynamic_model)); + 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]); } void DynamicModel::replaceMyEquations(DynamicModel &dynamic_model) const { dynamic_model.equations.clear(); - for (vector::const_iterator it = equations.begin(); - it != equations.end(); it++) - dynamic_model.addEquation((*it)->cloneDynamic(dynamic_model)); + for (size_t i = 0; i < equations.size(); i++) + dynamic_model.addEquation(equations[i]->cloneDynamic(dynamic_model), + equations_lineno[i]); } void @@ -3464,14 +3467,14 @@ DynamicModel::computeRamseyPolicyFOCs(const StaticModel &static_model) // Add Planner Objective to equations to include in computeDerivIDs assert(static_model.equations.size() == 1); - addEquation(static_model.equations[0]->cloneDynamic(*this)); + 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]->collectVariables(eEndogenous, dynvars); + equations[i]->collectDynamicVariables(eEndogenous, dynvars); for (set >::const_iterator it = dynvars.begin(); it != dynvars.end(); it++) @@ -3509,7 +3512,7 @@ DynamicModel::computeRamseyPolicyFOCs(const StaticModel &static_model) } equations.clear(); - addEquation(AddEqual(lagrangian, Zero)); + addEquation(AddEqual(lagrangian, Zero), -1); computeDerivIDs(); //Compute derivatives and overwrite equations @@ -3523,7 +3526,7 @@ DynamicModel::computeRamseyPolicyFOCs(const StaticModel &static_model) // Add new equations equations.clear(); for (int i = 0; i < (int) neweqs.size(); i++) - addEquation(neweqs[i]); + addEquation(neweqs[i], -1); } void @@ -3555,11 +3558,11 @@ DynamicModel::toStatic(StaticModel &static_model) const // 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_model.addEquation(static_only_equations[static_only_index]->toStatic(static_model), static_only_equations_lineno[static_only_index]); static_only_index++; } else - static_model.addEquation(equations[i]->toStatic(static_model)); + static_model.addEquation(equations[i]->toStatic(static_model), equations_lineno[i]); } // Convert auxiliary equations @@ -3568,11 +3571,30 @@ DynamicModel::toStatic(StaticModel &static_model) const static_model.addAuxEquation((*it)->toStatic(static_model)); } -void -DynamicModel::findUnusedEndogenous(set &unusedEndogs) +set +DynamicModel::findUnusedEndogenous() { + set usedEndo, unusedEndo; for (int i = 0; i < (int) equations.size(); i++) - equations[i]->findUnusedEndogenous(unusedEndogs); + 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 @@ -3581,17 +3603,17 @@ DynamicModel::computeDerivIDs() set > dynvars; for (int i = 0; i < (int) equations.size(); i++) - equations[i]->collectVariables(eEndogenous, dynvars); + equations[i]->collectDynamicVariables(eEndogenous, dynvars); dynJacobianColsNbr = dynvars.size(); for (int i = 0; i < (int) equations.size(); i++) { - equations[i]->collectVariables(eExogenous, dynvars); - equations[i]->collectVariables(eExogenousDet, dynvars); - equations[i]->collectVariables(eParameter, dynvars); - equations[i]->collectVariables(eTrend, dynvars); - equations[i]->collectVariables(eLogTrend, dynvars); + 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(); @@ -3757,22 +3779,29 @@ DynamicModel::testTrendDerivativesEqualToZero(const eval_context_t &eval_context || symbol_table.getType(it->first.first) == eLogTrend) for (int eq = 0; eq < (int) equations.size(); eq++) { - expr_t testeq = AddLog(AddMinus(equations[eq]->get_arg1(), // F: a = b -> ln(a - b) - equations[eq]->get_arg2())); - 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) + 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) { - cerr << "ERROR: trends not compatible with balanced growth path; the second-order cross partial of equation " << eq + 1 << " w.r.t. trend variable " - << symbol_table.getName(it->first.first) << " and endogenous variable " - << symbol_table.getName(endogit->first.first) << " is not null. " << endl; - exit(EXIT_FAILURE); + double nearZero = testeq->getDerivative(endogit->second)->eval(eval_context); // eval d F / d Trend d Endog + if (fabs(nearZero) > ZERO_BAND) + { + cerr << "ERROR: 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; + exit(EXIT_FAILURE); + } } - } + } } } @@ -3983,7 +4012,7 @@ DynamicModel::substituteLeadLagInternal(aux_var_t type, bool deterministic_model // Substitute in used model local variables set used_local_vars; for (size_t i = 0; i < equations.size(); i++) - equations[i]->collectModelLocalVariables(used_local_vars); + equations[i]->collectVariables(eModelLocalVariable, used_local_vars); for (set::const_iterator it = used_local_vars.begin(); it != used_local_vars.end(); ++it) @@ -4046,7 +4075,7 @@ DynamicModel::substituteLeadLagInternal(aux_var_t type, bool deterministic_model // Add new equations for (int i = 0; i < (int) neweqs.size(); i++) - addEquation(neweqs[i]); + addEquation(neweqs[i], -1); // Order of auxiliary variable definition equations: // - expectation (entered before this function is called) @@ -4106,7 +4135,7 @@ DynamicModel::substituteExpectation(bool partial_information_model) // Add new equations for (int i = 0; i < (int) neweqs.size(); i++) - addEquation(neweqs[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)); @@ -4134,8 +4163,9 @@ DynamicModel::transformPredeterminedVariables() void DynamicModel::detrendEquations() { - for (nonstationary_symbols_map_t::const_iterator it = nonstationary_symbols_map.begin(); - it != nonstationary_symbols_map.end(); it++) + // 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)); @@ -4219,19 +4249,20 @@ DynamicModel::isModelLocalVariableUsed() const size_t i = 0; while (i < equations.size() && used_local_vars.size() == 0) { - equations[i]->collectModelLocalVariables(used_local_vars); + equations[i]->collectVariables(eModelLocalVariable, used_local_vars); i++; } return used_local_vars.size() > 0; } void -DynamicModel::addStaticOnlyEquation(expr_t eq) +DynamicModel::addStaticOnlyEquation(expr_t eq, int lineno) { BinaryOpNode *beq = dynamic_cast(eq); assert(beq != NULL && beq->get_op_code() == oEqual); static_only_equations.push_back(beq); + static_only_equations_lineno.push_back(lineno); } size_t @@ -4253,3 +4284,4 @@ DynamicModel::dynamicOnlyEquationsNbr() const return eqs.size(); } + diff --git a/DynamicModel.hh b/DynamicModel.hh index 8cc151a3..c752fe0b 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -35,6 +35,9 @@ private: /*! 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; + typedef map, int> deriv_id_table_t; //! Maps a pair (symbol_id, lag) to a deriv ID deriv_id_table_t deriv_id_table; @@ -223,7 +226,9 @@ public: void toStatic(StaticModel &static_model) const; //! Find endogenous variables not used in model - void findUnusedEndogenous(set &unusedEndogs); + set findUnusedEndogenous(); + //! Find exogenous variables not used in model + set findUnusedExogenous(); //! Copies a dynamic model (only the equations) /*! It assumes that the dynamic model given in argument has just been allocated */ @@ -235,7 +240,7 @@ public: void replaceMyEquations(DynamicModel &dynamic_model) const; //! Adds an equation marked as [static] - void addStaticOnlyEquation(expr_t eq); + void addStaticOnlyEquation(expr_t eq, int lineno); //! Returns number of static only equations size_t staticOnlyEquationsNbr() const; @@ -458,6 +463,38 @@ public: return (-1); }; bool isModelLocalVariableUsed() const; + + // in ExternalFiles.cc + //! 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 first order derivatives of model evaluated at steady state + void writeFirstDerivativesC(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; }; +//! 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/DynareBison.yy b/DynareBison.yy index 5207b3a0..c2cb723e 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -18,43 +18,19 @@ */ %skeleton "lalr1.cc" -%require "2.3" +%require "2.5" %defines -/* Prologue: - In Bison <= 2.3, it is inserted in both the .cc and .hh files. - In Bison >= 2.3a, it is inserted only in the .cc file. - Since Bison 2.4, the new %code directives provide a cleaner way of dealing - with the prologue. -*/ -%{ -using namespace std; - +%code top { class ParsingDriver; +} +%code requires { #include "ExprNode.hh" #include "CodeInterpreter.hh" +} -/* 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 = (Rhs)[1].begin; \ - (Current).end = (Rhs)[N].end; \ - } \ - else \ - { \ - (Current).begin = (Current).end = (Rhs)[0].end; \ - } \ - driver.location = (Current); \ - } while(false) - -%} - -%name-prefix="Dynare" +%name-prefix "Dynare" %parse-param { ParsingDriver &driver } %lex-param { ParsingDriver &driver } @@ -79,7 +55,24 @@ class ParsingDriver; 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 @@ -87,51 +80,52 @@ class ParsingDriver; * current lexer object of the driver context. */ #undef yylex #define yylex driver.lexer->lex -%} +} %token AIM_SOLVER ANALYTIC_DERIVATION AR AUTOCORR -%token BAYESIAN_IRF BETA_PDF BLOCK +%token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION %token BVAR_DENSITY BVAR_FORECAST %token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA %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 DATAFILE FILE DETERMINISTIC DOUBLING DR_CYCLE_REDUCTION_TOL DR_LOGARITHMIC_REDUCTION_TOL DR_LOGARITHMIC_REDUCTION_MAXITER DR_ALGO DROP DSAMPLE DYNASAVE DYNATYPE CALIBRATION DIFFERENTIATE_FORWARD_VARS +%token CONSIDER_ALL_ENDOGENOUS CONSIDER_ONLY_OBSERVED +%token DATAFILE FILE 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 FLOAT_NUMBER +%token FLOAT_NUMBER DATES %token DEFAULT FIXED_POINT -%token FORECAST K_ORDER_SOLVER INSTRUMENTS PRIOR SHIFT MEAN STDEV VARIANCE MODE INTERVAL SHAPE DOMAINN +%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 HOMOTOPY_SETUP HOMOTOPY_MODE HOMOTOPY_STEPS HOMOTOPY_FORCE_CONTINUE HP_FILTER HP_NGRID HYBRID -%token IDENTIFICATION INF_CONSTANT INITVAL INITVAL_FILE BOUNDS JSCALE INIT +%token HISTVAL HISTVAL_FILE HOMOTOPY_SETUP HOMOTOPY_MODE HOMOTOPY_STEPS HOMOTOPY_FORCE_CONTINUE HP_FILTER HP_NGRID HYBRID +%token IDENTIFICATION INF_CONSTANT INITVAL INITVAL_FILE BOUNDS JSCALE INIT INFILE INVARS %token INT_NUMBER -%token DATE_NUMBER -%token INV_GAMMA_PDF INV_GAMMA1_PDF INV_GAMMA2_PDF IRF IRF_SHOCKS +%token INV_GAMMA_PDF INV_GAMMA1_PDF INV_GAMMA2_PDF IRF IRF_SHOCKS IRF_PLOT_THRESHOLD IRF_CALIBRATION %token KALMAN_ALGO KALMAN_TOL SUBSAMPLES OPTIONS TOLF -%token LAPLACE LIK_ALGO LIK_INIT LINEAR LOAD_IDENT_FILES LOAD_MH_FILE LOAD_PARAMS_AND_STEADY_STATE LOGLINEAR LYAPUNOV +%token LAPLACE LIK_ALGO LIK_INIT LINEAR LOAD_IDENT_FILES LOAD_MH_FILE LOAD_PARAMS_AND_STEADY_STATE LOGLINEAR LOGDATA LYAPUNOV %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_DROP MH_INIT_SCALE MH_JSCALE MH_MODE MH_NBLOCKS MH_REPLIC MH_RECOVER MIN MINIMAL_SOLVING_PERIODS SOLVE_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 DIFFUSE_FILTER SUB_DRAWS +%token MODEL_DIAGNOSTICS MODIFIEDHARMONICMEAN MOMENTS_VARENDO DIFFUSE_FILTER SUB_DRAWS TAPER_STEPS GEWEKE_INTERVAL MCMC_JUMPING_COVARIANCE MOMENT_CALIBRATION %token NAME -%token NAN_CONSTANT NO_STATIC NOBS NOCONSTANT NODISPLAY NOCORR NODIAGNOSTIC NOFUNCTIONS -%token NOGRAPH NOMOMENTS NOPRINT NORMAL_PDF -%token OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS MAX_DIM_COVA_GROUP ADVANCED -%token PARALLEL_LOCAL_FILES PARAMETERS PARAMETER_SET PARTIAL_INFORMATION PERFECT_FORESIGHT PERIODS PLANNER_OBJECTIVE PLOT_CONDITIONAL_FORECAST PLOT_PRIORS PREFILTER PRESAMPLE +%token NAN_CONSTANT NO_STATIC NOBS NOCONSTANT NODISPLAY NOCORR NODIAGNOSTIC NOFUNCTIONS NO_HOMOTOPY +%token NOGRAPH NOMOMENTS NOPRINT NORMAL_PDF SAVE_DRAWS +%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 PERFECT_FORESIGHT PERIODS PERIOD PLANNER_OBJECTIVE PLOT_CONDITIONAL_FORECAST PLOT_PRIORS PREFILTER PRESAMPLE +%token PERFECT_FORESIGHT_SETUP PERFECT_FORESIGHT_SOLVER %token PRINT PRIOR_MC PRIOR_TRUNC PRIOR_MODE PRIOR_MEAN POSTERIOR_MODE POSTERIOR_MEAN POSTERIOR_MEDIAN 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 SIGMA_E SIMUL SIMUL_ALGO SIMUL_SEED SIMULATION_TYPE -%token SMOOTHER SQUARE_ROOT_SOLVER STACK_SOLVE_ALGO STEADY_STATE_MODEL STOCHASTIC SOLVE_ALGO SOLVER_PERIODS +%token SHOCKS SHOCK_DECOMPOSITION 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 %token STDERR STEADY STOCH_SIMUL SURPRISE SYLVESTER SYLVESTER_FIXED_POINT_TOL REGIMES REGIME -%token TEX RAMSEY_POLICY PLANNER_DISCOUNT DISCRETIONARY_POLICY DISCRETIONARY_TOL +%token TEX RAMSEY_MODEL RAMSEY_POLICY 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 %token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL -%token XLS_SHEET XLS_RANGE +%token XLS_SHEET XLS_RANGE LONG_NAME %left COMMA %left EQUAL_EQUAL EXCLAMATION_EQUAL %left LESS GREATER LESS_EQUAL GREATER_EQUAL @@ -151,7 +145,7 @@ class ParsingDriver; %token VLISTLOG VLISTPER %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 +%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 %token GSIG2_LMDM Q_DIAG FLAT_PRIOR NCSK NSTD %token INDXPARR INDXOVR INDXAP APBAND INDXIMF IMFBAND INDXFORE FOREBAND INDXGFOREHAT INDXGIMFHAT %token INDXESTIMA INDXGDLS EQ_MS FILTER_COVARIANCE FILTER_DECOMPOSITION @@ -160,7 +154,7 @@ class ParsingDriver; %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 +%token MARKOV_SWITCHING CHAIN DURATION NUMBER_OF_REGIMES NUMBER_OF_LAGS %token SVAR 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 @@ -178,12 +172,13 @@ class ParsingDriver; %type expression expression_or_empty %type equation hand_side -%type non_negative_number signed_number signed_integer date_number -%type filename symbol vec_of_vec_value vec_value_list +%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 range vec_value_w_inf vec_value_1_w_inf named_var +%type integer_range signed_integer_range %type change_type_arg -%type change_type_var_list subsamples_eq_opt prior_eq_opt options_eq_opt +%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 %% @@ -239,6 +234,7 @@ statement : parameters | model_comparison | model_info | planner_objective + | ramsey_model | ramsey_policy | discretionary_policy | bvar_density @@ -273,6 +269,12 @@ statement : parameters | calib_smoother | extended_path | model_diagnostics + | moment_calibration + | irf_calibration + | smoother2histval + | histval_file + | perfect_foresight_setup + | perfect_foresight_solver ; dsample : DSAMPLE INT_NUMBER ';' @@ -332,12 +334,24 @@ nonstationary_var_list : nonstationary_var_list 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 ';'; @@ -348,18 +362,34 @@ predetermined_variables : PREDETERMINED_VARIABLES predetermined_variables_list ' parameters : PARAMETERS parameter_list ';'; +named_var : '(' LONG_NAME EQUAL QUOTED_STRING ')' + { $$ = $4; } + ; + 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 @@ -368,12 +398,24 @@ varexo_list : varexo_list 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 @@ -382,12 +424,24 @@ varexo_det_list : varexo_det_list 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 @@ -396,12 +450,24 @@ parameter_list : parameter_list 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 @@ -562,6 +628,10 @@ histval_list : histval_list 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 @@ -699,7 +769,9 @@ comma_hand_side : hand_side pound_expression: '#' symbol EQUAL hand_side ';' { driver.declare_and_init_model_local_variable($2, $4); }; -shocks : SHOCKS ';' shock_list END ';' { driver.end_shocks(); }; +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 @@ -785,6 +857,8 @@ ms_options : o_chain | o_duration | o_restrictions | o_number_of_regimes + | o_number_of_lags + | o_parameters ; svar : SVAR '(' svar_options_list ')' ';' @@ -801,7 +875,9 @@ svar_options : o_coefficients | o_chain ; -mshocks : MSHOCKS ';' mshock_list END ';' { driver.end_mshocks(); }; +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 @@ -821,12 +897,6 @@ period_list : period_list COMMA INT_NUMBER { driver.add_period($1); } ; -expectation_type : PERFECT_FORESIGHT - { driver.add_expectation_pf(true); } - | SURPRISE - { driver.add_expectation_pf(false); } - ; - sigma_e : SIGMA_E EQUAL '[' triangular_matrix ']' ';' { driver.do_sigma_e(); }; value_list : value_list COMMA '(' expression ')' @@ -878,7 +948,7 @@ steady_options : o_solve_algo | o_homotopy_steps | o_homotopy_force_continue | o_markowitz - | o_maxit + | o_steady_maxit | o_nocheck ; @@ -907,6 +977,38 @@ model_info_options_list : model_info_options_list COMMA 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_no_homotopy + ; + simul : SIMUL ';' { driver.simul(); } | SIMUL '(' simul_options_list ')' ';' @@ -917,12 +1019,8 @@ simul_options_list : simul_options_list COMMA simul_options | simul_options ; -simul_options : o_periods - | o_datafile - | o_stack_solve_algo - | o_markowitz - | o_minimal_solving_periods - | o_maxit +simul_options : perfect_foresight_setup_options + | perfect_foresight_solver_options ; external_function : EXTERNAL_FUNCTION '(' external_function_options_list ')' ';' @@ -991,6 +1089,7 @@ stoch_simul_primary_options : o_dr_algo | o_dr_cycle_reduction_tol | o_dr_logarithmic_reduction_tol | o_dr_logarithmic_reduction_maxiter + | o_irf_plot_threshold ; stoch_simul_options : stoch_simul_primary_options @@ -1024,10 +1123,6 @@ non_negative_number : INT_NUMBER | FLOAT_NUMBER ; -date_number : DATE_NUMBER - | INT_NUMBER - ; - signed_number : PLUS non_negative_number { $$ = $2; } | MINUS non_negative_number @@ -1141,7 +1236,12 @@ estimated_elem3 : expression_or_empty COMMA expression_or_empty ; estimated_params_init : ESTIMATED_PARAMS_INIT ';' estimated_init_list END ';' - { driver.estimated_params_init(); }; + { 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(); } @@ -1225,6 +1325,8 @@ prior_distribution : BETA { $$ = eUniform; } | INV_GAMMA2 { $$ = eInvGamma2; } + | DIRICHLET + { $$ = eDirichlet; } ; prior_pdf : BETA_PDF @@ -1243,7 +1345,15 @@ prior_pdf : BETA_PDF { $$ = eInvGamma2; } ; -set_time : SET_TIME '(' date_number ')' ';' +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); } ; @@ -1495,6 +1605,7 @@ estimation_options : o_datafile | o_nodisplay | o_graph_format | o_conf_sig + | o_mh_conf_sig | o_mh_replic | o_mh_drop | o_mh_jscale @@ -1511,6 +1622,7 @@ estimation_options : o_datafile | o_mh_nblocks | o_load_mh_file | o_loglinear + | o_logdata | o_nodiagnostic | o_bayesian_irf | o_dsge_var @@ -1555,7 +1667,14 @@ estimation_options : o_datafile | o_ar | o_endogenous_prior | o_use_univariate_filters_if_singularity_is_detected - | o_qz_zero_threshold + | o_qz_zero_threshold + | o_taper_steps + | o_geweke_interval + | o_mcmc_jumping_covariance + | o_irf_plot_threshold + | o_posterior_max_subsample_draws + | o_consider_all_endogenous + | o_consider_only_observed ; list_optim_option : QUOTED_STRING COMMA QUOTED_STRING @@ -1703,6 +1822,16 @@ mc_filename_list : filename 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_MODEL symbol_list ';' + { driver.ramsey_model(); } + | RAMSEY_MODEL '(' ramsey_model_options_list ')' symbol_list ';' + { driver.ramsey_model(); } + ; + ramsey_policy : RAMSEY_POLICY ';' { driver.ramsey_policy(); } | RAMSEY_POLICY '(' ramsey_policy_options_list ')' ';' @@ -1729,9 +1858,17 @@ discretionary_policy_options_list : discretionary_policy_options_list COMMA disc discretionary_policy_options : ramsey_policy_options | o_discretionary_tol; - | o_solve_maxit; + | 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 ; @@ -1989,6 +2126,7 @@ ms_simulation_option : o_output_file_tag | 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 @@ -2100,6 +2238,7 @@ dynare_sensitivity_option : o_gsa_identification | o_nodisplay | o_graph_format | o_conf_sig + | o_mh_conf_sig | o_loglinear | o_mode_file | o_load_ident_files @@ -2160,7 +2299,6 @@ conditional_forecast_option : o_periods | o_conf_sig | o_controlled_varexo | o_parameter_set - | o_simulation_type ; plot_conditional_forecast : PLOT_CONDITIONAL_FORECAST symbol_list ';' @@ -2179,8 +2317,6 @@ 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); } - | VAR symbol ';' PERIODS period_list ';' VALUES value_list ';' EXPECTATION expectation_type ';' - { driver.add_det_shock($2, true); } ; steady_state_model : STEADY_STATE_MODEL ';' { driver.begin_steady_state_model(); } @@ -2236,6 +2372,81 @@ 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_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 + ; + 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"); @@ -2250,6 +2461,7 @@ o_simul_algo : SIMUL_ALGO EQUAL INT_NUMBER { 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_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); }; @@ -2266,10 +2478,11 @@ 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_maxit : MAXIT EQUAL INT_NUMBER { driver.option_num("maxit_", $3); }; +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_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_solve_maxit : SOLVE_MAXIT EQUAL INT_NUMBER { driver.option_num("solve_maxit", $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); }; @@ -2292,10 +2505,10 @@ o_conditional_variance_decomposition : CONDITIONAL_VARIANCE_DECOMPOSITION EQUAL { driver.option_vec_int("conditional_variance_decomposition", $3); } ; o_first_obs : FIRST_OBS EQUAL INT_NUMBER { driver.option_num("first_obs", $3); }; -o_new_estimation_data_first_obs : FIRST_OBS EQUAL date_number +o_new_estimation_data_first_obs : FIRST_OBS EQUAL date_expr { driver.option_date("first_obs", $3); } ; -o_last_obs : LAST_OBS EQUAL date_number +o_last_obs : LAST_OBS EQUAL date_expr { driver.option_date("last_obs", $3); } ; o_shift : SHIFT EQUAL signed_number { driver.option_num("shift", $3); }; @@ -2339,11 +2552,13 @@ list_allowed_graph_formats : allowed_graph_formats | list_allowed_graph_formats COMMA allowed_graph_formats ; -o_subsample_name : symbol EQUAL date_number ':' date_number +o_subsample_name : symbol EQUAL date_expr ':' date_expr { driver.set_subsample_name_equal_to_date_range($1, $3, $5); } ; o_conf_sig : CONF_SIG EQUAL non_negative_number { driver.option_num("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 ')'; @@ -2360,6 +2575,7 @@ 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_loglinear : LOGLINEAR { driver.option_num("loglinear", "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 @@ -2388,6 +2604,8 @@ 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("taper_steps", $3); }; +o_geweke_interval : GEWEKE_INTERVAL EQUAL vec_value { driver.option_num("geweke_interval",$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"); }; @@ -2485,11 +2703,6 @@ o_parameter_set : PARAMETER_SET EQUAL PRIOR_MODE | PARAMETER_SET EQUAL CALIBRATION { driver.option_str("parameter_set", "calibration"); } ; -o_simulation_type : SIMULATION_TYPE EQUAL DETERMINISTIC - { driver.option_str("simulation_type", "deterministic"); } - | SIMULATION_TYPE EQUAL STOCHASTIC - { driver.option_str("simulation_type", "stochastic"); } - ; 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 @@ -2575,6 +2788,8 @@ o_duration : DURATION EQUAL non_negative_number { 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 @@ -2647,6 +2862,7 @@ o_random_parameter_convergence_criterion : RANDOM_PARAMETER_CONVERGENCE_CRITERIO { 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); } @@ -2670,6 +2886,24 @@ o_discretionary_tol: DISCRETIONARY_TOL EQUAL non_negative_number { driver.option o_analytic_derivation : ANALYTIC_DERIVATION { driver.option_num("analytic_derivation", "1"); } 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_irf_plot_threshold : IRF_PLOT_THRESHOLD EQUAL non_negative_number { driver.option_num("impulse_responses.plot_threshold", $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"); }; range : symbol ':' symbol { @@ -2679,6 +2913,31 @@ range : symbol ':' symbol $$ = $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 @@ -2788,6 +3047,7 @@ symbol : NAME | FIG | NONE | DR + | PRIOR ; %% diff --git a/DynareFlex.ll b/DynareFlex.ll index e4045035..6ab6faab 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -60,6 +60,7 @@ string eofbuff; %x VERBATIM_BLOCK %x NATIVE %x NATIVE_COMMENT +%x DATES_STATEMENT %x LINE1 %x LINE2 %x LINE3 @@ -68,6 +69,9 @@ string eofbuff; // 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() */ %{ @@ -88,13 +92,13 @@ string eofbuff; } /* spaces, tabs and carriage returns are ignored */ -[ \t\r\f]+ { yylloc->step(); } -[\n]+ { yylloc->step(); } +[ \t\r\f]+ { yylloc->step(); } +[\n]+ { yylloc->step(); } /* Comments */ -["%"].* -["/"]["/"].* -"/*" {comment_caller = YY_START; BEGIN COMMENT;} +["%"].* +["/"]["/"].* +"/*" {comment_caller = YY_START; BEGIN COMMENT;} "*/" {BEGIN comment_caller;} . @@ -133,6 +137,7 @@ string eofbuff; 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;} @@ -141,6 +146,7 @@ string eofbuff; 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;} sbvar {BEGIN DYNARE_STATEMENT; return token::SBVAR;} @@ -161,6 +167,9 @@ string eofbuff; 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) @@ -187,6 +196,8 @@ string eofbuff; 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;} /* For the semicolon after an "end" keyword */ ; {return Dynare::parser::token_type (yytext[0]);} @@ -196,11 +207,32 @@ string eofbuff; subsamples {return token::SUBSAMPLES;} options {return token::OPTIONS;} -prior {return token::PRIOR;} +prior { + yylval->string_val = new string(yytext); + return token::PRIOR; +} std {BEGIN DYNARE_STATEMENT; return token::STD;} corr {BEGIN DYNARE_STATEMENT; return token::CORR;} /* 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(); *yyout << yytext + 1; } +dates {dates_parens_nb=0; BEGIN DATES_STATEMENT; yylval->string_val = new string("dates");} file {return token::FILE;} datafile {return token::DATAFILE;} nobs {return token::NOBS;} @@ -222,6 +254,8 @@ string eofbuff; 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;} graph {return token::GRAPH;} nograph {return token::NOGRAPH;} nodisplay {return token::NODISPLAY;} @@ -233,6 +267,7 @@ string eofbuff; 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;} @@ -248,6 +283,7 @@ string eofbuff; mh_nblocks {return token::MH_NBLOCKS;} load_mh_file {return token::LOAD_MH_FILE;} loglinear {return token::LOGLINEAR;} +logdata {return token::LOGDATA;} nodiagnostic {return token::NODIAGNOSTIC;} kalman_algo {return token::KALMAN_ALGO;} kalman_tol {return token::KALMAN_TOL;} @@ -257,6 +293,7 @@ string eofbuff; dsge_var {return token::DSGE_VAR;} dsge_varlag {return token::DSGE_VARLAG;} moments_varendo {return token::MOMENTS_VARENDO;} +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;} @@ -267,6 +304,7 @@ string eofbuff; 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;} @@ -338,6 +376,10 @@ string eofbuff; yylval->string_val = new string(yytext); return token::INV_GAMMA2; } +dirichlet { + yylval->string_val = new string(yytext); + return token::DIRICHLET; +} normal { yylval->string_val = new string(yytext); return token::NORMAL; @@ -390,7 +432,7 @@ string eofbuff; return token::CNUM; } 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;}; @@ -424,7 +466,6 @@ string eofbuff; max_block_iterations {return token::MAX_BLOCK_ITERATIONS;} max_repeated_optimization_runs {return token::MAX_REPEATED_OPTIMIZATION_RUNS;} maxit {return token::MAXIT;} -solve_maxit {return token::SOLVE_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;} @@ -435,6 +476,19 @@ string eofbuff; random_parameter_convergence_criterion {return token::RANDOM_PARAMETER_CONVERGENCE_CRITERION;} tolf {return token::TOLF;} 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; } @@ -464,14 +518,12 @@ string eofbuff; posterior_mode {return token::POSTERIOR_MODE; } posterior_mean {return token::POSTERIOR_MEAN; } posterior_median {return token::POSTERIOR_MEDIAN; } -simulation_type {return token::SIMULATION_TYPE; } -deterministic {return token::DETERMINISTIC; } -stochastic {return token::STOCHASTIC; } k_order_solver {return token::K_ORDER_SOLVER; } filter_covariance {return token::FILTER_COVARIANCE; } filter_decomposition {return token::FILTER_DECOMPOSITION; } 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;} @@ -481,6 +533,14 @@ string eofbuff; analytic_derivation {return token::ANALYTIC_DERIVATION;} solver_periods {return token::SOLVER_PERIODS;} endogenous_prior {return token::ENDOGENOUS_PRIOR;} +long_name {return token::LONG_NAME;} +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;} [\$][^$]*[\$] { strtok(yytext+1, "$"); @@ -493,8 +553,6 @@ string eofbuff; stderr {return token::STDERR;} values {return token::VALUES;} corr {return token::CORR;} -surprise {return token::SURPRISE;} -perfect_foresight {return token::PERFECT_FORESIGHT;} periods {return token::PERIODS;} cutoff {return token::CUTOFF;} mfs {return token::MFS;} @@ -549,14 +607,18 @@ string eofbuff; 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;} 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;} @@ -689,10 +751,16 @@ string eofbuff; return token::INT_NUMBER; } -([1-2][0-9]{3}[Mm](([1-9])|(1[0-2])))|([1-2][0-9]{3}[Qq][1-4])|([1-2][0-9]{3}[Ww](([1-9]{1})|([1-5][0-9]))) { - yylval->string_val = new string(yytext); - return token::DATE_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); @@ -785,7 +853,7 @@ string eofbuff; "*/"[[:space:]]*\n { BEGIN NATIVE; } . -<> { yyterminate(); } +<> { yyterminate(); } <*>. { driver.error(*yylloc, "character unrecognized by lexer"); } %% diff --git a/DynareMain.cc b/DynareMain.cc index 44227c9c..7fed1e78 100644 --- a/DynareMain.cc +++ b/DynareMain.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -17,8 +17,6 @@ * along with Dynare. If not, see . */ -using namespace std; - #include #include #include @@ -31,6 +29,7 @@ using namespace std; #include "macro/MacroDriver.hh" #include +#include "ExtendedPreprocessorTypes.hh" /* Prototype for second part of main function Splitting main() in two parts was necessary because ParsingDriver.h and MacroDriver.h can't be @@ -38,7 +37,7 @@ using namespace std; */ void main2(stringstream &in, string &basename, bool debug, bool clear_all, 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 + bool parallel_test, bool nostrict, FileOutputType output_mode, LanguageOutputType lang #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -49,7 +48,7 @@ usage() { cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [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]" + << " [-D[=]] [nostrict] [output=dynamic|first|second|third] [language=C|C++]" #if defined(_WIN32) || defined(__CYGWIN32__) << " [cygwin] [msvc]" #endif @@ -97,6 +96,8 @@ main(int argc, char **argv) bool parallel_test = false; bool nostrict = false; map defines; + FileOutputType output_mode = none; + LanguageOutputType language = matlab; // Parse options for (int arg = 2; arg < argc; arg++) @@ -191,6 +192,52 @@ main(int argc, char **argv) defines[key] = "1"; } } + else if (strlen(argv[arg]) >= 6 && !strncmp(argv[arg], "output", 6)) + { + if (strlen(argv[arg]) <= 7 || argv[arg][6] != '=') + { + cerr << "Incorrect syntax for ouput 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 ouput 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(); + } + // we don't want temp terms in external functions + 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]) == 14 && !strncmp(argv[arg] + 9, "julia", 5)) + language = julia; + else if (strlen(argv[arg]) == 15 && !strncmp(argv[arg] + 9, "python", 6)) + language = python; + else + { + cerr << "Incorrect syntax for language option" << endl; + usage(); + } + } else { cerr << "Unknown option: " << argv[arg] << endl; @@ -231,7 +278,7 @@ main(int argc, char **argv) // Do the rest main2(macro_output, basename, debug, clear_all, 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 + parallel, parallel_config_file, cluster_name, parallel_slave_open_mode, parallel_test, nostrict, output_mode, language #if defined(_WIN32) || defined(__CYGWIN32__) , cygwin, msvc #endif diff --git a/DynareMain2.cc b/DynareMain2.cc index eb044620..8f82a059 100644 --- a/DynareMain2.cc +++ b/DynareMain2.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2013 Dynare Team + * Copyright (C) 2008-2014 Dynare Team * * This file is part of Dynare. * @@ -17,18 +17,17 @@ * along with Dynare. If not, see . */ -using namespace std; - #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 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 + bool parallel_test, bool nostrict, FileOutputType output_mode, LanguageOutputType language #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -55,10 +54,13 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tm mod_file->evalAllExpressions(warn_uninit); // Do computations - mod_file->computingPass(no_tmp_terms); + mod_file->computingPass(no_tmp_terms, output_mode); // Write outputs - mod_file->writeOutputFiles(basename, clear_all, no_log, no_warn, console, nograph, nointeractive, config_file + if (output_mode != none) + mod_file->writeExternalFiles(basename, output_mode, language); + else + mod_file->writeOutputFiles(basename, clear_all, no_log, no_warn, console, nograph, nointeractive, config_file #if defined(_WIN32) || defined(__CYGWIN32__) , cygwin, msvc #endif @@ -66,6 +68,5 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tm delete mod_file; - cout << "Preprocessing completed." << endl - << "Starting MATLAB/Octave computing." << endl; + cout << "Preprocessing completed." << endl; } diff --git a/ExprNode.cc b/ExprNode.cc index e3a5bad8..d7f7bd4d 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2013 Dynare Team + * Copyright (C) 2007-2014 Dynare Team * * This file is part of Dynare. * @@ -21,15 +21,11 @@ #include #include -// For select1st() -#ifdef __GNUC__ -# include -using namespace __gnu_cxx; -#endif - #include #include +#include + #include "ExprNode.hh" #include "DataTree.hh" #include "ModFile.hh" @@ -84,11 +80,20 @@ ExprNode::cost(const temporary_terms_t &temporary_terms, bool is_matlab) const 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; - collectVariables(eEndogenous, 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)); @@ -98,21 +103,12 @@ void ExprNode::collectExogenous(set > &result) const { set > symb_ids; - collectVariables(eExogenous, 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::collectModelLocalVariables(set &result) const -{ - set > symb_ids; - collectVariables(eModelLocalVariable, symb_ids); - transform(symb_ids.begin(), symb_ids.end(), inserter(result, result.begin()), - select1st >()); -} - void ExprNode::computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, @@ -329,12 +325,7 @@ NumConstNode::compile(ostream &CompileCode, unsigned int &instruction_number, } void -NumConstNode::collectVariables(SymbolType type_arg, set > &result) const -{ -} - -void -NumConstNode::findUnusedEndogenous(set &unusedEndogs) const +NumConstNode::collectDynamicVariables(SymbolType type_arg, set > &result) const { } @@ -682,6 +673,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case oSteadyStateFile: output << "ys_(" << tsid + 1 << ")"; break; + case oCSteadyStateFile: + output << "ys_[" << tsid << "]"; + break; default: cerr << "VariableNode::writeOutput: should not reach this point" << endl; exit(EXIT_FAILURE); @@ -724,6 +718,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case oSteadyStateFile: output << "exo_(" << i << ")"; break; + case oCSteadyStateFile: + output << "exo_[" << i - 1 << "]"; + break; default: cerr << "VariableNode::writeOutput: should not reach this point" << endl; exit(EXIT_FAILURE); @@ -766,6 +763,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case oSteadyStateFile: output << "exo_(" << i << ")"; break; + case oCSteadyStateFile: + output << "exo_[" << i - 1 << "]"; + break; default: cerr << "VariableNode::writeOutput: should not reach this point" << endl; exit(EXIT_FAILURE); @@ -879,20 +879,12 @@ VariableNode::computeTemporaryTerms(map &reference_count, } void -VariableNode::collectVariables(SymbolType type_arg, set > &result) const +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]->collectVariables(type_arg, result); -} - -void -VariableNode::findUnusedEndogenous(set &unusedEndogs) const -{ - set::iterator it = unusedEndogs.find(symb_id); - if (it != unusedEndogs.end()) - unusedEndogs.erase(it); + datatree.local_variables_table[symb_id]->collectDynamicVariables(type_arg, result); } pair @@ -2007,15 +1999,9 @@ UnaryOpNode::compile(ostream &CompileCode, unsigned int &instruction_number, } void -UnaryOpNode::collectVariables(SymbolType type_arg, set > &result) const +UnaryOpNode::collectDynamicVariables(SymbolType type_arg, set > &result) const { - arg->collectVariables(type_arg, result); -} - -void -UnaryOpNode::findUnusedEndogenous(set &unusedEndogs) const -{ - arg->findUnusedEndogenous(unusedEndogs); + arg->collectDynamicVariables(type_arg, result); } pair @@ -3084,17 +3070,10 @@ BinaryOpNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int & } void -BinaryOpNode::collectVariables(SymbolType type_arg, set > &result) const +BinaryOpNode::collectDynamicVariables(SymbolType type_arg, set > &result) const { - arg1->collectVariables(type_arg, result); - arg2->collectVariables(type_arg, result); -} - -void -BinaryOpNode::findUnusedEndogenous(set &unusedEndogs) const -{ - arg1->findUnusedEndogenous(unusedEndogs); - arg2->findUnusedEndogenous(unusedEndogs); + arg1->collectDynamicVariables(type_arg, result); + arg2->collectDynamicVariables(type_arg, result); } expr_t @@ -4061,19 +4040,11 @@ TrinaryOpNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int } void -TrinaryOpNode::collectVariables(SymbolType type_arg, set > &result) const +TrinaryOpNode::collectDynamicVariables(SymbolType type_arg, set > &result) const { - arg1->collectVariables(type_arg, result); - arg2->collectVariables(type_arg, result); - arg3->collectVariables(type_arg, result); -} - -void -TrinaryOpNode::findUnusedEndogenous(set &unusedEndogs) const -{ - arg1->findUnusedEndogenous(unusedEndogs); - arg2->findUnusedEndogenous(unusedEndogs); - arg3->findUnusedEndogenous(unusedEndogs); + arg1->collectDynamicVariables(type_arg, result); + arg2->collectDynamicVariables(type_arg, result); + arg3->collectDynamicVariables(type_arg, result); } pair @@ -4303,19 +4274,26 @@ TrinaryOpNode::isInStaticForm() const return arg1->isInStaticForm() && arg2->isInStaticForm() && arg3->isInStaticForm(); } -ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg, - int symb_id_arg, - const vector &arguments_arg) : +AbstractExternalFunctionNode::AbstractExternalFunctionNode(DataTree &datatree_arg, + int symb_id_arg, + const vector &arguments_arg) : ExprNode(datatree_arg), symb_id(symb_id_arg), arguments(arguments_arg) +{ +} + +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 -ExternalFunctionNode::prepareForDerivation() +AbstractExternalFunctionNode::prepareForDerivation() { if (preparedForDerivation) return; @@ -4335,7 +4313,7 @@ ExternalFunctionNode::prepareForDerivation() } expr_t -ExternalFunctionNode::computeDerivative(int deriv_id) +AbstractExternalFunctionNode::computeDerivative(int deriv_id) { assert(datatree.external_functions_table.getNargs(symb_id) > 0); vector dargs; @@ -4349,9 +4327,8 @@ ExternalFunctionNode::composeDerivatives(const vector &dargs) { vector dNodes; for (int i = 0; i < (int) dargs.size(); i++) - if (dargs.at(i) != 0) - dNodes.push_back(datatree.AddTimes(dargs.at(i), - datatree.AddFirstDerivExternalFunctionNode(symb_id, arguments, i+1))); + 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++) @@ -4360,7 +4337,7 @@ ExternalFunctionNode::composeDerivatives(const vector &dargs) } expr_t -ExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map &recursive_variables) +AbstractExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map &recursive_variables) { assert(datatree.external_functions_table.getNargs(symb_id) > 0); vector dargs; @@ -4379,9 +4356,9 @@ ExternalFunctionNode::computeTemporaryTerms(map &reference_count, } void -ExternalFunctionNode::writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const +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++) @@ -4394,9 +4371,9 @@ ExternalFunctionNode::writeExternalFunctionArguments(ostream &output, ExprNodeOu } void -ExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, const string &ending) const +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; @@ -4414,9 +4391,12 @@ ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_typ const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const { - if (output_type == oMatlabOutsideModel || output_type == oSteadyStateFile) + if (output_type == oMatlabOutsideModel || output_type == oSteadyStateFile + || output_type == oCSteadyStateFile || IS_LATEX(output_type)) { - output << datatree.symbol_table.getName(symb_id) << "("; + 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; @@ -4438,10 +4418,10 @@ ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_typ } unsigned int -ExternalFunctionNode::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 +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++) @@ -4629,25 +4609,17 @@ ExternalFunctionNode::computeTemporaryTerms(map &reference_count, } void -ExternalFunctionNode::collectVariables(SymbolType type_arg, set > &result) const +AbstractExternalFunctionNode::collectDynamicVariables(SymbolType type_arg, set > &result) const { for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - (*it)->collectVariables(type_arg, result); + (*it)->collectDynamicVariables(type_arg, result); } void -ExternalFunctionNode::findUnusedEndogenous(set &unusedEndogs) const +AbstractExternalFunctionNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const { - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->findUnusedEndogenous(unusedEndogs); -} - -void -ExternalFunctionNode::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)); + temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); if (it != temporary_terms.end()) temporary_terms_inuse.insert(idx); else @@ -4659,13 +4631,13 @@ ExternalFunctionNode::collectTemporary_terms(const temporary_terms_t &temporary_ } double -ExternalFunctionNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) +AbstractExternalFunctionNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) { throw EvalExternalFunctionException(); } pair -ExternalFunctionNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const +AbstractExternalFunctionNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const { vector > V_arguments; vector V_expr_t; @@ -4704,7 +4676,7 @@ ExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const } int -ExternalFunctionNode::maxEndoLead() const +AbstractExternalFunctionNode::maxEndoLead() const { int val = 0; for (vector::const_iterator it = arguments.begin(); @@ -4714,7 +4686,7 @@ ExternalFunctionNode::maxEndoLead() const } int -ExternalFunctionNode::maxExoLead() const +AbstractExternalFunctionNode::maxExoLead() const { int val = 0; for (vector::const_iterator it = arguments.begin(); @@ -4724,7 +4696,7 @@ ExternalFunctionNode::maxExoLead() const } int -ExternalFunctionNode::maxEndoLag() const +AbstractExternalFunctionNode::maxEndoLag() const { int val = 0; for (vector::const_iterator it = arguments.begin(); @@ -4734,7 +4706,7 @@ ExternalFunctionNode::maxEndoLag() const } int -ExternalFunctionNode::maxExoLag() const +AbstractExternalFunctionNode::maxExoLag() const { int val = 0; for (vector::const_iterator it = arguments.begin(); @@ -4744,7 +4716,7 @@ ExternalFunctionNode::maxExoLag() const } int -ExternalFunctionNode::maxLead() const +AbstractExternalFunctionNode::maxLead() const { int val = 0; for (vector::const_iterator it = arguments.begin(); @@ -4754,7 +4726,7 @@ ExternalFunctionNode::maxLead() const } expr_t -ExternalFunctionNode::decreaseLeadsLags(int n) const +AbstractExternalFunctionNode::decreaseLeadsLags(int n) const { vector arguments_subst; for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4763,7 +4735,7 @@ ExternalFunctionNode::decreaseLeadsLags(int n) const } expr_t -ExternalFunctionNode::decreaseLeadsLagsPredeterminedVariables() const +AbstractExternalFunctionNode::decreaseLeadsLagsPredeterminedVariables() const { vector arguments_subst; for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4772,7 +4744,7 @@ ExternalFunctionNode::decreaseLeadsLagsPredeterminedVariables() const } expr_t -ExternalFunctionNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +AbstractExternalFunctionNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const { vector arguments_subst; for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4781,7 +4753,7 @@ ExternalFunctionNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_tabl } expr_t -ExternalFunctionNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const +AbstractExternalFunctionNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const { vector arguments_subst; for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4790,7 +4762,7 @@ ExternalFunctionNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table } expr_t -ExternalFunctionNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +AbstractExternalFunctionNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const { vector arguments_subst; for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4799,7 +4771,7 @@ ExternalFunctionNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs) const +AbstractExternalFunctionNode::substituteExoLag(subst_table_t &subst_table, vector &neweqs) const { vector arguments_subst; for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4808,7 +4780,7 @@ ExternalFunctionNode::substituteExoLag(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const +AbstractExternalFunctionNode::substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const { vector arguments_subst; for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4817,7 +4789,7 @@ ExternalFunctionNode::substituteExpectation(subst_table_t &subst_table, vector &subset, subst_table_t &subst_table, vector &neweqs) const +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++) @@ -4832,7 +4804,7 @@ ExternalFunctionNode::buildSimilarExternalFunctionNode(vector &alt_args, } bool -ExternalFunctionNode::alreadyWrittenAsTefTerm(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const +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()) @@ -4841,7 +4813,7 @@ ExternalFunctionNode::alreadyWrittenAsTefTerm(int the_symb_id, deriv_node_temp_t } int -ExternalFunctionNode::getIndxInTefTerms(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const throw (UnknownFunctionNameAndArgs) +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()) @@ -4850,19 +4822,19 @@ ExternalFunctionNode::getIndxInTefTerms(int the_symb_id, deriv_node_temp_terms_t } bool -ExternalFunctionNode::isNumConstNodeEqualTo(double value) const +AbstractExternalFunctionNode::isNumConstNodeEqualTo(double value) const { return false; } bool -ExternalFunctionNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const +AbstractExternalFunctionNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const { return false; } bool -ExternalFunctionNode::containsEndogenous(void) const +AbstractExternalFunctionNode::containsEndogenous(void) const { bool result = false; for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4871,7 +4843,7 @@ ExternalFunctionNode::containsEndogenous(void) const } expr_t -ExternalFunctionNode::replaceTrendVar() const +AbstractExternalFunctionNode::replaceTrendVar() const { vector arguments_subst; for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4880,7 +4852,7 @@ ExternalFunctionNode::replaceTrendVar() const } expr_t -ExternalFunctionNode::detrend(int symb_id, bool log_trend, expr_t trend) const +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++) @@ -4889,7 +4861,7 @@ ExternalFunctionNode::detrend(int symb_id, bool log_trend, expr_t trend) const } expr_t -ExternalFunctionNode::removeTrendLeadLag(map trend_symbols_map) const +AbstractExternalFunctionNode::removeTrendLeadLag(map trend_symbols_map) const { vector arguments_subst; for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) @@ -4898,7 +4870,7 @@ ExternalFunctionNode::removeTrendLeadLag(map trend_symbols_map) con } bool -ExternalFunctionNode::isInStaticForm() const +AbstractExternalFunctionNode::isInStaticForm() const { for (vector::const_iterator it = arguments.begin(); it != arguments.end(); ++it) if (!(*it)->isInStaticForm()) @@ -4911,7 +4883,7 @@ FirstDerivExternalFunctionNode::FirstDerivExternalFunctionNode(DataTree &datatre int top_level_symb_id_arg, const vector &arguments_arg, int inputIndex_arg) : - ExternalFunctionNode(datatree_arg, top_level_symb_id_arg, arguments_arg), + AbstractExternalFunctionNode(datatree_arg, top_level_symb_id_arg, arguments_arg), inputIndex(inputIndex_arg) { // Add myself to the first derivative external function map @@ -4945,9 +4917,8 @@ FirstDerivExternalFunctionNode::composeDerivatives(const vector &dargs) { vector dNodes; for (int i = 0; i < (int) dargs.size(); i++) - if (dargs.at(i) != 0) - dNodes.push_back(datatree.AddTimes(dargs.at(i), - datatree.AddSecondDerivExternalFunctionNode(symb_id, arguments, inputIndex, i+1))); + 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); @@ -4961,6 +4932,15 @@ FirstDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType { 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()) @@ -4972,12 +4952,10 @@ FirstDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType return; } - int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); + const int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - int tmpIndx = inputIndex; - if (IS_C(output_type)) - tmpIndx = tmpIndx - 1; + const int tmpIndx = inputIndex - 1 + ARRAY_SUBSCRIPT_OFFSET(output_type); if (first_deriv_symb_id == symb_id) output << "TEFD_" << getIndxInTefTerms(symb_id, tef_terms) @@ -5019,15 +4997,14 @@ FirstDerivExternalFunctionNode::compile(ostream &CompileCode, unsigned int &inst int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - int tmpIndx = inputIndex; if (!lhs_rhs) { - FLDTEFD_ fldtefd(getIndxInTefTerms(symb_id, tef_terms), tmpIndx); + FLDTEFD_ fldtefd(getIndxInTefTerms(symb_id, tef_terms), inputIndex); fldtefd.write(CompileCode, instruction_number); } else { - FSTPTEFD_ fstptefd(getIndxInTefTerms(symb_id, tef_terms), tmpIndx); + FSTPTEFD_ fstptefd(getIndxInTefTerms(symb_id, tef_terms), inputIndex); fstptefd.write(CompileCode, instruction_number); } } @@ -5041,7 +5018,17 @@ FirstDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Exp 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)) + /* 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)) @@ -5170,12 +5157,40 @@ FirstDerivExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCo } } +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); +} + SecondDerivExternalFunctionNode::SecondDerivExternalFunctionNode(DataTree &datatree_arg, int top_level_symb_id_arg, const vector &arguments_arg, int inputIndex1_arg, int inputIndex2_arg) : - ExternalFunctionNode(datatree_arg, top_level_symb_id_arg, arguments_arg), + AbstractExternalFunctionNode(datatree_arg, top_level_symb_id_arg, arguments_arg), inputIndex1(inputIndex1_arg), inputIndex2(inputIndex2_arg) { @@ -5206,7 +5221,8 @@ SecondDerivExternalFunctionNode::computeTemporaryTerms(map &referen } expr_t -SecondDerivExternalFunctionNode::computeDerivative(int deriv_id) +SecondDerivExternalFunctionNode::composeDerivatives(const vector &dargs) + { cerr << "ERROR: third order derivatives of external functions are not implemented" << endl; exit(EXIT_FAILURE); @@ -5219,6 +5235,15 @@ SecondDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType { 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()) @@ -5230,16 +5255,11 @@ SecondDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType return; } - int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); + const int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); - int tmpIndex1 = inputIndex1; - int tmpIndex2 = inputIndex2; - if (IS_C(output_type)) - { - tmpIndex1 = tmpIndex1 - 1; - tmpIndex2 = tmpIndex2 - 1; - } + 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) @@ -5275,8 +5295,17 @@ SecondDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Ex int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); - if (alreadyWrittenAsTefTerm(second_deriv_symb_id, tef_terms) - || second_deriv_symb_id == symb_id) + /* 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)) @@ -5362,3 +5391,51 @@ SecondDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Ex output << ");" << endl; } } + +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::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/ExprNode.hh b/ExprNode.hh index d251f332..b008333c 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2013 Dynare Team + * Copyright (C) 2007-2014 Dynare Team * * This file is part of Dynare. * @@ -20,13 +20,13 @@ #ifndef _EXPR_NODE_HH #define _EXPR_NODE_HH -using namespace std; - #include #include #include #include +using namespace std; + #include "SymbolTable.hh" #include "CodeInterpreter.hh" #include "ExternalFunctionsTable.hh" @@ -73,7 +73,8 @@ enum ExprNodeOutputType 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 - oSteadyStateFile //!< Matlab code, in the generated steady state file + oSteadyStateFile, //!< Matlab code, in the generated steady state file + oCSteadyStateFile //!< C code, in the generated steady state file }; #define IS_MATLAB(output_type) ((output_type) == oMatlabStaticModel \ @@ -85,7 +86,10 @@ enum ExprNodeOutputType || (output_type) == oMatlabDynamicSparseSteadyStateOperator \ || (output_type) == oSteadyStateFile) -#define IS_C(output_type) ((output_type) == oCDynamicModel || (output_type) == oCStaticModel || (output_type) == oCDynamicSteadyStateOperator) +#define IS_C(output_type) ((output_type) == oCDynamicModel \ + || (output_type) == oCStaticModel \ + || (output_type) == oCDynamicSteadyStateOperator \ + || (output_type) == oCSteadyStateFile) #define IS_LATEX(output_type) ((output_type) == oLatexStaticModel \ || (output_type) == oLatexDynamicModel \ @@ -115,13 +119,13 @@ class ExprNode friend class DynamicModel; friend class StaticModel; friend class ModelTree; - friend class ExprNodeLess; + friend struct ExprNodeLess; friend class NumConstNode; friend class VariableNode; friend class UnaryOpNode; friend class BinaryOpNode; friend class TrinaryOpNode; - friend class ExternalFunctionNode; + 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 */ @@ -202,14 +206,23 @@ public: 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 + //! 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 collectVariables(SymbolType type_arg, set > &result) const = 0; + 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 /*! @@ -227,18 +240,8 @@ public: */ virtual void collectExogenous(set > &result) const; - //! Computes the set of model local variables in the expression - /*! - Symbol IDs of these model local variables are added to the set given in argument. - Note that this method is called recursively on the expressions associated to the model local variables detected. - */ - virtual void collectModelLocalVariables(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; - //! Removes used endogenous variables from the provided list of endogs - virtual void findUnusedEndogenous(set &unusedEndogs) const = 0; - virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, map > &first_occurence, @@ -438,8 +441,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 void collectVariables(SymbolType type_arg, set > &result) const; - virtual void findUnusedEndogenous(set &unusedEndogs) 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; @@ -484,8 +486,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 void collectVariables(SymbolType type_arg, set > &result) const; - virtual void findUnusedEndogenous(set &unusedEndogs) const; + virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, map > &first_occurence, @@ -564,8 +565,7 @@ public: int Curr_block, vector< vector > &v_temporary_terms, int equation) const; - virtual void collectVariables(SymbolType type_arg, set > &result) const; - virtual void findUnusedEndogenous(set &unusedEndogs) 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); @@ -643,8 +643,7 @@ public: int Curr_block, vector< vector > &v_temporary_terms, int equation) const; - virtual void collectVariables(SymbolType type_arg, set > &result) const; - virtual void findUnusedEndogenous(set &unusedEndogs) 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); @@ -738,8 +737,7 @@ public: int Curr_block, vector< vector > &v_temporary_terms, int equation) const; - virtual void collectVariables(SymbolType type_arg, set > &result) const; - virtual void findUnusedEndogenous(set &unusedEndogs) 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); @@ -773,11 +771,11 @@ public: }; //! External function node -class ExternalFunctionNode : public ExprNode +class AbstractExternalFunctionNode : public ExprNode { private: virtual expr_t computeDerivative(int deriv_id); - virtual expr_t composeDerivatives(const vector &dargs); + virtual expr_t composeDerivatives(const vector &dargs) = 0; protected: //! Thrown when trying to access an unknown entry in external_function_node_map class UnknownFunctionNameAndArgs @@ -791,10 +789,69 @@ protected: 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; +public: + AbstractExternalFunctionNode(DataTree &datatree_arg, int symb_id_arg, + const vector &arguments_arg); + 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 void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms) 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 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 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; +}; + +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 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 void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, @@ -810,45 +867,13 @@ public: int Curr_block, vector< vector > &v_temporary_terms, int equation) const; - virtual void collectVariables(SymbolType type_arg, set > &result) const; - virtual void findUnusedEndogenous(set &unusedEndogs) 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; virtual expr_t toStatic(DataTree &static_datatree) 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 buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) 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 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; - virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; - virtual bool isInStaticForm() const; }; -class FirstDerivExternalFunctionNode : public ExternalFunctionNode +class FirstDerivExternalFunctionNode : public AbstractExternalFunctionNode { private: const int inputIndex; @@ -877,14 +902,17 @@ public: 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 expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const; + virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; }; -class SecondDerivExternalFunctionNode : public ExternalFunctionNode +class SecondDerivExternalFunctionNode : public AbstractExternalFunctionNode { private: const int inputIndex1; const int inputIndex2; - virtual expr_t computeDerivative(int deriv_id); + virtual expr_t composeDerivatives(const vector &dargs); public: SecondDerivExternalFunctionNode(DataTree &datatree_arg, int top_level_symb_id_arg, @@ -899,9 +927,20 @@ public: 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 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 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 expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const; + virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; }; #endif diff --git a/ExtendedPreprocessorTypes.hh b/ExtendedPreprocessorTypes.hh new file mode 100644 index 00000000..d9a210e7 --- /dev/null +++ b/ExtendedPreprocessorTypes.hh @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2014 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 (not yet implemented) + python, // outputs files for Python (not yet implemented) (not yet implemented) + }; +#endif diff --git a/ExternalFiles.cc b/ExternalFiles.cc new file mode 100644 index 00000000..9ac2ba72 --- /dev/null +++ b/ExternalFiles.cc @@ -0,0 +1,730 @@ +/* + * Copyright (C) 2006-2013 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 "ModFile.hh" +#include "DynamicModel.hh" +#include "StaticModel.hh" +#include "SteadyStateModel.hh" + +void +ModFile::writeExternalFiles(const string &basename, FileOutputType output, LanguageOutputType language) const +{ + switch(language) + { + case c: + writeExternalFilesC(basename, output); + break; + case cpp: + writeExternalFilesCC(basename, output); + break; + default: + cerr << "This case shouldn't happen. Contact the authors of Dynare" << endl; + exit(EXIT_FAILURE); + } +} + +// C interface + +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); + + if (!no_static) + static_model.writeStaticFile(basename, false, false, true); + + + // 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 +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::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 + << "#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); + + 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 + d1->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms); + mDynamicModelFile << ";" << endl; + } + + mDynamicModelFile << "}" << endl; + + writePowerDeriv(mDynamicModelFile, true); + mDynamicModelFile.close(); + +} + +// using compressed sparse row format (CSR) +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 + << "#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); + + 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, true); + 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 + << "#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); + + 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, true); + mDynamicModelFile.close(); + +} + +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; +} + + +// +// C++ interface +// +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); + + if (!no_static) + static_model.writeStaticFile(basename, false, false, true); + + + // 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::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 +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; +} + + diff --git a/Makefile.am b/Makefile.am index 6556fd44..5b8118a1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -52,7 +52,9 @@ dynare_m_SOURCES = \ SteadyStateModel.hh \ SteadyStateModel.cc \ WarningConsolidation.hh \ - WarningConsolidation.cc + WarningConsolidation.cc \ + ExtendedPreprocessorTypes.hh \ + ExternalFiles.cc # The -I. is for dynare_m_CPPFLAGS = $(BOOST_CPPFLAGS) -I. @@ -61,7 +63,7 @@ dynare_m_LDADD = macro/libmacro.a DynareFlex.cc FlexLexer.h: DynareFlex.ll $(LEX) -oDynareFlex.cc DynareFlex.ll - cp /usr/include/FlexLexer.h . + cp $(LEXINC)/FlexLexer.h . DynareBison.cc DynareBison.hh location.hh stack.hh position.hh: DynareBison.yy $(YACC) -o DynareBison.cc DynareBison.yy diff --git a/ModFile.cc b/ModFile.cc index 4ef0ab43..314fd504 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2013 Dynare Team + * Copyright (C) 2006-2014 Dynare Team * * This file is part of Dynare. * @@ -39,7 +39,7 @@ ModFile::ModFile(WarningConsolidation &warnings_arg) 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), ramsey_policy_orig_eqn_nbr(0), + nonstationary_variables(false), ramsey_model_orig_eqn_nbr(0), warnings(warnings_arg) { } @@ -113,7 +113,7 @@ ModFile::checkPass() (*it)->checkPass(mod_file_struct, warnings); // Check the steady state block - steady_state_model.checkPass(mod_file_struct.ramsey_policy_present); + steady_state_model.checkPass(mod_file_struct.ramsey_model_present, warnings); // If order option has not been set, default to 2 if (!mod_file_struct.order_option) @@ -123,24 +123,25 @@ ModFile::checkPass() || 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.discretionary_policy_present + || mod_file_struct.calib_smoother_present; // Allow empty model only when doing a standalone BVAR estimation if (dynamic_model.equation_number() == 0 && (mod_file_struct.check_present - || mod_file_struct.simul_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_policy_present || mod_file_struct.discretionary_policy_present) + if (((mod_file_struct.ramsey_model_present || mod_file_struct.discretionary_policy_present) && !mod_file_struct.planner_objective_present) - || (!(mod_file_struct.ramsey_policy_present || mod_file_struct.discretionary_policy_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_policy or a discretionary_policy statement and vice versa." << endl; + cerr << "ERROR: A planner_objective statement must be used with a ramsey_model, a ramsey_policy or a discretionary_policy statement and vice versa." << endl; exit(EXIT_FAILURE); } @@ -152,9 +153,9 @@ ModFile::checkPass() exit(EXIT_FAILURE); } - if (mod_file_struct.simul_present && stochastic_statement_present) + if (mod_file_struct.perfect_foresight_solver_present && stochastic_statement_present) { - cerr << "ERROR: A .mod file cannot contain both a simul command and one of {stoch_simul, estimation, osr, ramsey_policy, discretionary_policy}" << endl; + 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); } @@ -245,9 +246,9 @@ ModFile::checkPass() } if (dynamic_model.staticOnlyEquationsNbr() > 0 && - (mod_file_struct.ramsey_policy_present || mod_file_struct.discretionary_policy_present)) + (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_policy or discretionary_policy" << endl; + cerr << "ERROR: marking equations as [static] or [dynamic] is not possible with ramsey_model, ramsey_policy or discretionary_policy" << endl; exit(EXIT_FAILURE); } @@ -263,6 +264,43 @@ ModFile::checkPass() || 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; + + // 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 + set unusedExo = dynamic_model.findUnusedExogenous(); + if (unusedExo.size() > 1) + { + warnings << "WARNING: some exogenous ("; + for (set::const_iterator it = unusedExo.begin(); + it != unusedExo.end(); ) + { + warnings << symbol_table.getName(*it); + if (++it != unusedExo.end()) + warnings << ", "; + } + warnings << ") are declared but not used in the model. This may lead to crashes or unexpected behaviour." << endl; + } } void @@ -270,8 +308,7 @@ ModFile::transformPass(bool nostrict) { if (nostrict) { - set unusedEndogs = symbol_table.getEndogenous(); - dynamic_model.findUnusedEndogenous(unusedEndogs); + set unusedEndogs = dynamic_model.findUnusedEndogenous(); for (set::iterator it = unusedEndogs.begin(); it != unusedEndogs.end(); it++) { symbol_table.changeType(*it, eUnusedEndogenous); @@ -293,7 +330,7 @@ ModFile::transformPass(bool nostrict) dynamic_model.removeTrendVariableFromEquations(); } - if (mod_file_struct.ramsey_policy_present) + if (mod_file_struct.ramsey_model_present) { StaticModel *planner_objective = NULL; for (vector::iterator it = statements.begin(); it != statements.end(); it++) @@ -303,7 +340,7 @@ ModFile::transformPass(bool nostrict) planner_objective = pos->getPlannerObjective(); } assert(planner_objective != NULL); - ramsey_policy_orig_eqn_nbr = dynamic_model.equation_number(); + ramsey_model_orig_eqn_nbr = dynamic_model.equation_number(); /* clone the model then clone the new equations back to the original because @@ -318,7 +355,8 @@ ModFile::transformPass(bool nostrict) || 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.discretionary_policy_present + || mod_file_struct.calib_smoother_present) { // In stochastic models, create auxiliary vars for leads and lags greater than 2, on both endos and exos dynamic_model.substituteEndoLeadGreaterThanTwo(false); @@ -357,11 +395,11 @@ ModFile::transformPass(bool nostrict) /* Enforce the same number of equations and endogenous, except in three cases: - - ramsey_policy is used + - 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_policy_present || mod_file_struct.discretionary_policy_present) + if (!(mod_file_struct.ramsey_model_present || mod_file_struct.discretionary_policy_present) && !(mod_file_struct.bvar_present && dynamic_model.equation_number() == 0) && (dynamic_model.equation_number() != symbol_table.endo_nbr())) { @@ -369,9 +407,9 @@ ModFile::transformPass(bool nostrict) exit(EXIT_FAILURE); } - if (symbol_table.exo_det_nbr() > 0 && mod_file_struct.simul_present) + if (symbol_table.exo_det_nbr() > 0 && mod_file_struct.perfect_foresight_solver_present) { - cerr << "ERROR: A .mod file cannot contain both a simul command and varexo_det declaration (all exogenous variables are deterministic in this case)" << endl; + cerr << "ERROR: A .mod file cannot contain both one of {perfect_foresight_solver,simul} and varexo_det declaration (all exogenous variables are deterministic in this case)" << endl; exit(EXIT_FAILURE); } @@ -381,11 +419,11 @@ ModFile::transformPass(bool nostrict) exit(EXIT_FAILURE); } - if (!mod_file_struct.ramsey_policy_present) + if (!mod_file_struct.ramsey_model_present) cout << "Found " << dynamic_model.equation_number() << " equation(s)." << endl; else { - cout << "Found " << ramsey_policy_orig_eqn_nbr << " equation(s)." << endl; + cout << "Found " << ramsey_model_orig_eqn_nbr << " equation(s)." << endl; cout << "Found " << dynamic_model.equation_number() << " FOC equation(s) for Ramsey Problem." << endl; } @@ -409,7 +447,7 @@ ModFile::transformPass(bool nostrict) } void -ModFile::computingPass(bool no_tmp_terms) +ModFile::computingPass(bool no_tmp_terms, FileOutputType output) { // Mod file may have no equation (for example in a standalone BVAR estimation) if (dynamic_model.equation_number() > 0) @@ -423,7 +461,8 @@ ModFile::computingPass(bool no_tmp_terms) { 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.identification_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 @@ -431,29 +470,37 @@ ModFile::computingPass(bool no_tmp_terms) 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, - paramsDerivatives, block, byte_code); + false, paramsDerivatives, block, byte_code); } // Set things to compute for dynamic model - if (mod_file_struct.simul_present || mod_file_struct.check_present + 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_policy_present || mod_file_struct.identification_present) + || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present + || mod_file_struct.calib_smoother_present) { - if (mod_file_struct.simul_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_policy_present || mod_file_struct.identification_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; - bool thirdDerivatives = mod_file_struct.order_option == 3 || mod_file_struct.estimation_analytic_derivation; + 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); } @@ -532,15 +579,26 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool no_log, b symbol_table.writeOutput(mOutputFile); - // Initialize M_.Sigma_e and M_.H + // 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; + 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; @@ -572,14 +630,16 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool no_log, b << "end" << endl; // Erase possible remnants of previous runs - string dynfile = basename + "_dynamic.m"; - unlink(dynfile.c_str()); + unlink((basename + "_dynamic.m").c_str()); + unlink((basename + "_dynamic.cod").c_str()); + unlink((basename + "_dynamic.bin").c_str()); - string statfile = basename + "_static.m"; - unlink(statfile.c_str()); + unlink((basename + "_static.m").c_str()); + unlink((basename + "_static.cod").c_str()); + unlink((basename + "_static.bin").c_str()); - string steadystatefile = basename + "_steadystate2.m"; - unlink(steadystatefile.c_str()); + unlink((basename + "_steadystate2.m").c_str()); + unlink((basename + "_set_auxiliary_variables.m").c_str()); if (!use_dll) { @@ -633,14 +693,31 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool no_log, b #else # ifdef __linux__ // MATLAB/Linux - mOutputFile << " 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; + 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 << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " + 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; + << " 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 #endif mOutputFile << "else" << endl // Octave @@ -653,8 +730,8 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool no_log, b if (block && !byte_code) mOutputFile << "addpath " << basename << ";" << endl; - if (mod_file_struct.ramsey_policy_present) - mOutputFile << "M_.orig_eq_nbr = " << ramsey_policy_orig_eqn_nbr << ";" << endl; + if (mod_file_struct.ramsey_model_present) + mOutputFile << "M_.orig_eq_nbr = " << ramsey_model_orig_eqn_nbr << ";" << endl; if (dynamic_model.equation_number() > 0) { @@ -693,7 +770,15 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool no_log, b if (block && !byte_code) mOutputFile << "rmpath " << basename << ";" << endl; - mOutputFile << "save('" << basename << "_results.mat', 'oo_', 'M_', 'options_');" << 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; config_file.writeEndParallel(mOutputFile); @@ -730,7 +815,9 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool no_log, b } // Create steady state file - steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_policy_present); + steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present); cout << "done" << endl; } + + diff --git a/ModFile.hh b/ModFile.hh index cdbca445..a561af08 100644 --- a/ModFile.hh +++ b/ModFile.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2013 Dynare Team + * Copyright (C) 2006-2014 Dynare Team * * This file is part of Dynare. * @@ -35,6 +35,7 @@ using namespace std; #include "ExternalFunctionsTable.hh" #include "ConfigFile.hh" #include "WarningConsolidation.hh" +#include "ExtendedPreprocessorTypes.hh" //! The abstract representation of a "mod" file class ModFile @@ -92,7 +93,7 @@ public: eval_context_t global_eval_context; //! Stores the original number of equations in the model_block - int ramsey_policy_orig_eqn_nbr; + int ramsey_model_orig_eqn_nbr; //! Stores the list of extra files to be transefered during a parallel run /*! (i.e. option parallel_local_files of model block) */ @@ -121,7 +122,7 @@ public: void transformPass(bool nostrict); //! Execute computations /*! \param no_tmp_terms if true, no temporary terms will be computed in the static and dynamic files */ - void computingPass(bool no_tmp_terms); + void computingPass(bool no_tmp_terms, FileOutputType output); //! 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 @@ -137,6 +138,16 @@ public: , bool cygwin, bool msvc #endif ) const; + // Functions located in ExternalFiles.cc + void writeExternalFiles(const string &basename, FileOutputType output, LanguageOutputType language) const; + void writeExternalFilesC(const string &basename, FileOutputType output) const; + void writeExternalFilesCC(const string &basename, FileOutputType output) 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; }; #endif // ! MOD_FILE_HH diff --git a/ModelTree.cc b/ModelTree.cc index 2a798017..a83ea06f 100644 --- a/ModelTree.cc +++ b/ModelTree.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -270,7 +270,7 @@ ModelTree::evaluateAndReduceJacobian(const eval_context_t &eval_context, jacob_m } catch (ExprNode::EvalException &e) { - cerr << "ERROR: evaluation of Jacobian failed for equation " << eq+1 << " and variable " << symbol_table.getName(symb) << "(" << lag << ") [" << symb << "] !" << endl; + 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); @@ -1113,7 +1113,7 @@ ModelTree::writeTemporaryTerms(const temporary_terms_t &tt, ostream &output, for (temporary_terms_t::const_iterator it = tt.begin(); it != tt.end(); it++) { - if (dynamic_cast(*it) != NULL) + if (dynamic_cast(*it) != NULL) (*it)->writeExternalFunctionOutput(output, output_type, tt2, tef_terms); if (IS_C(output_type)) @@ -1144,7 +1144,7 @@ ModelTree::compileTemporaryTerms(ostream &code_file, unsigned int &instruction_n for (temporary_terms_t::const_iterator it = tt.begin(); it != tt.end(); it++) { - if (dynamic_cast(*it) != NULL) + if (dynamic_cast(*it) != NULL) { (*it)->compileExternalFunctionOutput(code_file, instruction_number, false, tt2, map_idx, dynamic, steady_dynamic, tef_terms); } @@ -1179,7 +1179,7 @@ ModelTree::writeModelLocalVariables(ostream &output, ExprNodeOutputType output_t const temporary_terms_t tt; for (size_t i = 0; i < equations.size(); i++) - equations[i]->collectModelLocalVariables(used_local_vars); + equations[i]->collectVariables(eModelLocalVariable, used_local_vars); for (set::const_iterator it = used_local_vars.begin(); it != used_local_vars.end(); ++it) @@ -1376,21 +1376,22 @@ ModelTree::writeLatexModelFile(const string &filename, ExprNodeOutputType output } void -ModelTree::addEquation(expr_t eq) +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, vector > &eq_tags) +ModelTree::addEquation(expr_t eq, int lineno, vector > &eq_tags) { int n = equation_number(); for (size_t i = 0; i < eq_tags.size(); i++) equation_tags.push_back(make_pair(n, eq_tags[i])); - addEquation(eq); + addEquation(eq, lineno); } void @@ -1567,3 +1568,10 @@ ModelTree::computeParamsDerivativesTemporaryTerms() it != hessian_params_derivatives.end(); ++it) it->second->computeTemporaryTerms(reference_count, params_derivs_temporary_terms, true); } + +bool ModelTree::isNonstationary(int symb_id) const +{ + return (nonstationary_symbols_map.find(symb_id) + != nonstationary_symbols_map.end()); +} + diff --git a/ModelTree.hh b/ModelTree.hh index 3a29aa90..4d161daf 100644 --- a/ModelTree.hh +++ b/ModelTree.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -54,6 +54,9 @@ 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; @@ -158,7 +161,6 @@ protected: void computeThirdDerivatives(const set &vars); //! Computes derivatives of the Jacobian and Hessian w.r. to parameters void computeParamsDerivatives(); - //! 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) @@ -295,10 +297,10 @@ public: 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 - void addEquation(expr_t eq); + //! 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, vector > &eq_tags); + void addEquation(expr_t eq, int lineno, 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 @@ -307,6 +309,8 @@ public: 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] */ diff --git a/NumericalInitialization.cc b/NumericalInitialization.cc index 4e28a492..3df225fc 100644 --- a/NumericalInitialization.cc +++ b/NumericalInitialization.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -50,6 +50,16 @@ InitParamStatement::writeOutput(ostream &output, const string &basename) const output << symbol_table.getName(symb_id) << " = M_.params( " << id << " );\n"; } +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 { @@ -229,12 +239,6 @@ EndValStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidati if (endogs.size() > 0 || exogs.size() > 0) exit(EXIT_FAILURE); - - if (mod_file_struct.shocks_present_but_simul_not_yet) - { - cerr << "ERROR: Putting a \"shocks\" block before an \"endval\" block is not permitted. Please swap the two blocks. This limitation will be removed in a future release of Dynare." << endl; - exit(EXIT_FAILURE); - } } void @@ -269,7 +273,7 @@ HistValStatement::writeOutput(ostream &output, const string &basename) const output << "%" << endl << "% HISTVAL instructions" << endl << "%" << endl - << "M_.endo_histval = zeros(M_.endo_nbr,M_.maximum_lag);" << endl; + << "M_.endo_histval = zeros(M_.endo_nbr,M_.maximum_endo_lag);" << endl; for (hist_values_t::const_iterator it = hist_values.begin(); it != hist_values.end(); it++) @@ -305,7 +309,7 @@ HistValStatement::writeOutput(ostream &output, const string &basename) const int tsid = symbol_table.getTypeSpecificID(symb_id) + 1; if (type == eEndogenous) - output << "M_.endo_histval( " << tsid << ", M_.maximum_lag + " << lag << ") = "; + output << "M_.endo_histval( " << tsid << ", M_.maximum_endo_lag + " << lag << ") = "; else if (type == eExogenous) output << "oo_.exo_simul( M_.maximum_lag + " << lag << ", " << tsid << " ) = "; else if (type != eExogenousDet) @@ -331,6 +335,17 @@ InitvalFileStatement::writeOutput(ostream &output, const string &basename) const << "initvalf('" << filename << "');" << endl; } +HistvalFileStatement::HistvalFileStatement(const string &filename_arg) : + filename(filename_arg) +{ +} + +void +HistvalFileStatement::writeOutput(ostream &output, const string &basename) const +{ + output << "histvalf('" << filename << "');" << endl; +} + HomotopyStatement::HomotopyStatement(const homotopy_values_t &homotopy_values_arg, const SymbolTable &symbol_table_arg) : homotopy_values(homotopy_values_arg), diff --git a/NumericalInitialization.hh b/NumericalInitialization.hh index f9214410..c61d41e1 100644 --- a/NumericalInitialization.hh +++ b/NumericalInitialization.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2012 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -41,6 +41,7 @@ public: const SymbolTable &symbol_table_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename) const; + virtual void writeCOutput(ostream &output, const string &basename); //! Fill eval context with parameter value void fillEvalContext(eval_context_t &eval_context) const; }; @@ -121,6 +122,15 @@ public: virtual void writeOutput(ostream &output, const string &basename) const; }; +class HistvalFileStatement : public Statement +{ +private: + const string filename; +public: + HistvalFileStatement(const string &filename_arg); + virtual void writeOutput(ostream &output, const string &basename) const; +}; + class HomotopyStatement : public Statement { public: diff --git a/ParsingDriver.cc b/ParsingDriver.cc index 38bf5a78..70ebe871 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -131,14 +131,19 @@ ParsingDriver::warning(const string &m) } void -ParsingDriver::declare_symbol(const string *name, SymbolType type, const string *tex_name) +ParsingDriver::declare_symbol(const string *name, SymbolType type, const string *tex_name, const string *long_name) { try { - if (tex_name == NULL) + if (tex_name == NULL && long_name == NULL) mod_file->symbol_table.addSymbol(*name, type); else - mod_file->symbol_table.addSymbol(*name, type, *tex_name); + if (tex_name == NULL) + mod_file->symbol_table.addSymbol(*name, type, "", *long_name); + else if (long_name == NULL) + mod_file->symbol_table.addSymbol(*name, type, *tex_name, ""); + else + mod_file->symbol_table.addSymbol(*name, type, *tex_name, *long_name); } catch (SymbolTable::AlreadyDeclaredException &e) { @@ -150,39 +155,47 @@ ParsingDriver::declare_symbol(const string *name, SymbolType type, const string } void -ParsingDriver::declare_endogenous(string *name, string *tex_name) +ParsingDriver::declare_endogenous(string *name, string *tex_name, string *long_name) { - declare_symbol(name, eEndogenous, tex_name); + declare_symbol(name, eEndogenous, tex_name, long_name); delete name; if (tex_name != NULL) delete tex_name; + if (long_name != NULL) + delete long_name; } void -ParsingDriver::declare_exogenous(string *name, string *tex_name) +ParsingDriver::declare_exogenous(string *name, string *tex_name, string *long_name) { - declare_symbol(name, eExogenous, tex_name); + declare_symbol(name, eExogenous, tex_name, long_name); delete name; if (tex_name != NULL) delete tex_name; + if (long_name != NULL) + delete long_name; } void -ParsingDriver::declare_exogenous_det(string *name, string *tex_name) +ParsingDriver::declare_exogenous_det(string *name, string *tex_name, string *long_name) { - declare_symbol(name, eExogenousDet, tex_name); + declare_symbol(name, eExogenousDet, tex_name, long_name); delete name; if (tex_name != NULL) delete tex_name; + if (long_name != NULL) + delete long_name; } void -ParsingDriver::declare_parameter(string *name, string *tex_name) +ParsingDriver::declare_parameter(string *name, string *tex_name, string *long_name) { - declare_symbol(name, eParameter, tex_name); + declare_symbol(name, eParameter, tex_name, long_name); delete name; if (tex_name != NULL) delete tex_name; + if (long_name != NULL) + delete long_name; } void @@ -191,7 +204,7 @@ 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); + declare_symbol(name, eStatementDeclaredVariable, NULL, NULL); delete name; } @@ -201,7 +214,7 @@ 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"); if (mod_file->symbol_table.exists(*optimalParName_declare)) - error("Symbol optimal_policy_discount_factor is needed by Dynare when using an ramsey_policy or a discretionary_policy statement"); + error("Symbol optimal_policy_discount_factor is needed by Dynare when using a ramsey_model, a ramsey_policy or a discretionary_policy statement"); declare_parameter(optimalParName_declare, NULL); init_param(optimalParName_init, exprnode); } @@ -215,7 +228,7 @@ ParsingDriver::begin_trend() void ParsingDriver::declare_trend_var(bool log_trend, string *name, string *tex_name) { - declare_symbol(name, log_trend ? eLogTrend : eTrend, 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) @@ -325,6 +338,13 @@ ParsingDriver::add_expression_variable(string *name) 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); @@ -333,17 +353,25 @@ ParsingDriver::add_expression_variable(string *name) } void -ParsingDriver::declare_nonstationary_var(string *name, string *tex_name) +ParsingDriver::declare_nonstationary_var(string *name, string *tex_name, string *long_name) { - if (tex_name != NULL) - declare_endogenous(new string(*name), new string(*tex_name)); + if (tex_name == NULL && long_name == NULL) + declare_endogenous(new string(*name)); else - declare_endogenous(new string(*name), tex_name); + if (tex_name == NULL) + declare_endogenous(new string(*name), NULL, new string(*long_name)); + else if (long_name == NULL) + declare_endogenous(new string(*name), new string(*tex_name)); + else + declare_endogenous(new string(*name), new string(*tex_name), new string(*long_name)); + declared_nonstationary_vars.push_back(mod_file->symbol_table.getID(*name)); mod_file->nonstationary_variables = true; delete name; if (tex_name != NULL) delete tex_name; + if (long_name != NULL) + delete long_name; } void @@ -357,6 +385,13 @@ ParsingDriver::end_nonstationary_var(bool log_deflator, expr_t deflator) { 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(); } @@ -585,9 +620,9 @@ ParsingDriver::begin_model() } void -ParsingDriver::end_shocks() +ParsingDriver::end_shocks(bool overwrite) { - mod_file->addStatement(new ShocksStatement(det_shocks, var_shocks, std_shocks, + 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(); @@ -597,9 +632,9 @@ ParsingDriver::end_shocks() } void -ParsingDriver::end_mshocks() +ParsingDriver::end_mshocks(bool overwrite) { - mod_file->addStatement(new MShocksStatement(det_shocks, mod_file->symbol_table)); + mod_file->addStatement(new MShocksStatement(overwrite, det_shocks, mod_file->symbol_table)); det_shocks.clear(); } @@ -638,12 +673,10 @@ ParsingDriver::add_det_shock(string *var, bool conditional_forecast) v.push_back(dse); } - det_shocks[symb_id].first = v; - det_shocks[symb_id].second = det_shocks_expectation_pf; - + det_shocks[symb_id] = v; + det_shocks_periods.clear(); det_shocks_values.clear(); - det_shocks_expectation_pf = false; delete var; } @@ -763,12 +796,6 @@ ParsingDriver::add_value(string *v) det_shocks_values.push_back(id); } -void -ParsingDriver::add_expectation_pf(bool pf) -{ - det_shocks_expectation_pf = pf; -} - void ParsingDriver::begin_svar_identification() { @@ -1111,6 +1138,15 @@ ParsingDriver::option_symbol_list(const string &name_option) 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(); } @@ -1187,8 +1223,23 @@ ParsingDriver::add_estimated_params_element() if (estim_params.name != "dsge_prior_weight") { check_symbol_existence(estim_params.name); - if (estim_params.name2.size() > 0) - check_symbol_existence(estim_params.name2); + 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); @@ -1202,9 +1253,9 @@ ParsingDriver::estimated_params() } void -ParsingDriver::estimated_params_init() +ParsingDriver::estimated_params_init(bool use_calibration) { - mod_file->addStatement(new EstimatedParamsInitStatement(estim_params_list, mod_file->symbol_table)); + mod_file->addStatement(new EstimatedParamsInitStatement(estim_params_list, mod_file->symbol_table, use_calibration)); estim_params_list.clear(); } @@ -1226,10 +1277,7 @@ ParsingDriver::set_unit_root_vars() void ParsingDriver::set_time(string *arg) { - string arg1 = *arg; - for (size_t i=0; iaddStatement(new SetTimeStatement(options_list)); options_list.clear(); } @@ -1520,7 +1568,7 @@ ParsingDriver::set_corr_options(string *name1, string *name2, string *subsample_ void ParsingDriver::run_estimation() { - mod_file->addStatement(new EstimationStatement(symbol_list, options_list, mod_file->symbol_table)); + mod_file->addStatement(new EstimationStatement(symbol_list, options_list)); symbol_list.clear(); options_list.clear(); } @@ -1720,13 +1768,23 @@ 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); + 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(symbol_list, options_list)); + symbol_list.clear(); + options_list.clear(); +} + void ParsingDriver::ramsey_policy() { @@ -1928,7 +1986,7 @@ ParsingDriver::plot_conditional_forecast(string *periods) void ParsingDriver::conditional_forecast_paths() { - mod_file->addStatement(new ConditionalForecastPathsStatement(det_shocks, mod_file->symbol_table)); + mod_file->addStatement(new ConditionalForecastPathsStatement(det_shocks)); det_shocks.clear(); } @@ -1967,10 +2025,10 @@ ParsingDriver::add_model_equal(expr_t arg1, expr_t arg2) if (!id->isInStaticForm()) error("An equation tagged [static] cannot contain leads, lags, expectations or STEADY_STATE operators"); - dynamic_model->addStaticOnlyEquation(id); + dynamic_model->addStaticOnlyEquation(id, location.begin.line); } else - model_tree->addEquation(id, eq_tags); + model_tree->addEquation(id, location.begin.line, eq_tags); eq_tags.clear(); return id; @@ -2288,7 +2346,7 @@ ParsingDriver::external_function_option(const string &name_option, const string { if (opt.empty()) error("An argument must be passed to the 'name' option of the external_function() statement."); - declare_symbol(&opt, eExternalFunction, NULL); + declare_symbol(&opt, eExternalFunction, NULL, NULL); current_external_function_id = mod_file->symbol_table.getID(opt); } else if (name_option == "first_deriv_provided") @@ -2297,7 +2355,7 @@ ParsingDriver::external_function_option(const string &name_option, const string current_external_function_options.firstDerivSymbID = eExtFunSetButNoNameProvided; else { - declare_symbol(&opt, eExternalFunction, NULL); + declare_symbol(&opt, eExternalFunction, NULL, NULL); current_external_function_options.firstDerivSymbID = mod_file->symbol_table.getID(opt); } } @@ -2307,7 +2365,7 @@ ParsingDriver::external_function_option(const string &name_option, const string current_external_function_options.secondDerivSymbID = eExtFunSetButNoNameProvided; else { - declare_symbol(&opt, eExternalFunction, NULL); + declare_symbol(&opt, eExternalFunction, NULL, NULL); current_external_function_options.secondDerivSymbID = mod_file->symbol_table.getID(opt); } } @@ -2431,7 +2489,7 @@ ParsingDriver::add_model_var_or_external_function(string *function_name, bool in if (in_model_block) 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); + 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); @@ -2547,3 +2605,105 @@ ParsingDriver::add_parallel_local_file(string *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)); + 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(); +} diff --git a/ParsingDriver.hh b/ParsingDriver.hh index 8b9b21e9..a747e896 100644 --- a/ParsingDriver.hh +++ b/ParsingDriver.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -71,6 +71,9 @@ public: //! 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 @@ -91,7 +94,7 @@ private: void check_symbol_is_endogenous_or_exogenous(string *name); //! Helper to add a symbol declaration - void declare_symbol(const string *name, SymbolType type, const string *tex_name); + void declare_symbol(const string *name, SymbolType type, const string *tex_name, const string *long_name); //! 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); @@ -131,8 +134,6 @@ private: vector > det_shocks_periods; //! Temporary storage for values of deterministic shocks vector det_shocks_values; - //! Temporary storage for perfect foresight of deterministic shocks in conditional forecast - bool det_shocks_expectation_pf; //! Temporary storage for variances of shocks ShocksStatement::var_and_std_shocks_t var_shocks; //! Temporary storage for standard errors of shocks @@ -151,6 +152,10 @@ private: HistValStatement::hist_values_t hist_values; //! 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 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 @@ -258,13 +263,13 @@ public: //! 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); + void declare_endogenous(string *name, string *tex_name = NULL, string *long_name = NULL); //! Declares an exogenous variable - void declare_exogenous(string *name, string *tex_name = NULL); + void declare_exogenous(string *name, string *tex_name = NULL, string *long_name = NULL); //! Declares an exogenous deterministic variable - void declare_exogenous_det(string *name, string *tex_name = NULL); + void declare_exogenous_det(string *name, string *tex_name = NULL, string *long_name = NULL); //! Declares a parameter - void declare_parameter(string *name, string *tex_name = NULL); + void declare_parameter(string *name, string *tex_name = NULL, string *long_name = NULL); //! Declares a statement local variable void declare_statement_local_variable(string *name); //! Completes a subsample statement @@ -322,9 +327,9 @@ public: //! Begin a model block void begin_model(); //! Writes a shocks statement - void end_shocks(); + void end_shocks(bool overwrite); //! Writes a mshocks statement - void end_mshocks(); + void end_mshocks(bool overwrite); //! Adds a deterministic chock or a path element inside a conditional_forecast_paths block void add_det_shock(string *var, bool conditional_forecast); //! Adds a std error chock @@ -344,8 +349,6 @@ public: //! Adds a deterministic shock value /*! \param v a string containing a (possibly negative) numeric constant */ void add_value(string *v); - //! Adds a expectation type for conditional forecast with deterministic simulation - void add_expectation_pf(bool pf); //! Writes a Sigma_e block void do_sigma_e(); //! Ends row of Sigma_e block @@ -391,7 +394,7 @@ public: //! Writes estimated params command void estimated_params(); //! Writes estimated params init command - void estimated_params_init(); + 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 @@ -490,6 +493,8 @@ public: void begin_planner_objective(); //! End a planner objective statement void end_planner_objective(expr_t expr); + //! Ramsey model statement + void ramsey_model(); //! Ramsey policy statement void ramsey_policy(); //! Discretionary policy statement @@ -641,7 +646,7 @@ public: //! 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); + void declare_nonstationary_var(string *name, string *tex_name = NULL, string *long_name = 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 @@ -652,6 +657,19 @@ public: 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(); + + void smoother2histval(); + void histval_file(string *filename); + void perfect_foresight_setup(); + void perfect_foresight_solver(); }; #endif // ! PARSING_DRIVER_HH diff --git a/Shocks.cc b/Shocks.cc index ab5b36df..d0aecd96 100644 --- a/Shocks.cc +++ b/Shocks.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -17,8 +17,6 @@ * along with Dynare. If not, see . */ -using namespace std; - #include #include #include @@ -26,9 +24,11 @@ using namespace std; #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) { @@ -44,28 +44,21 @@ AbstractShocksStatement::writeDetShocks(ostream &output) const { int id = symbol_table.getTypeSpecificID(it->first) + 1; bool exo_det = (symbol_table.getType(it->first) == eExogenousDet); - int set_shocks_index = ((int) mshocks) + 2 * ((int) exo_det); - for (size_t i = 0; i < it->second.first.size(); i++) + for (size_t i = 0; i < it->second.size(); i++) { - const int &period1 = it->second.first[i].period1; - const int &period2 = it->second.first[i].period2; - const expr_t value = it->second.first[i].value; + const int &period1 = it->second[i].period1; + const int &period2 = it->second[i].period2; + const expr_t value = it->second[i].value; - if (period1 == period2) - { - output << "set_shocks(" << set_shocks_index << "," << period1 - << ", " << id << ", "; - value->writeOutput(output); - output << ");" << endl; - } - else - { - output << "set_shocks(" << set_shocks_index << "," << period1 - << ":" << period2 << ", " << id << ", "; - value->writeOutput(output); - output << ");" << endl; - } + 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; @@ -74,13 +67,14 @@ AbstractShocksStatement::writeDetShocks(ostream &output) const output << "M_.exo_det_length = " << exo_det_length << ";\n"; } -ShocksStatement::ShocksStatement(const det_shocks_t &det_shocks_arg, +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, det_shocks_arg, 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), @@ -95,15 +89,37 @@ ShocksStatement::writeOutput(ostream &output, const string &basename) const << "% SHOCKS instructions" << endl << "%" << endl; - // Write instruction that initializes a shock - output << "make_ex_;" << 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 + else if (overwrite) output << "M_.sigma_e_is_diagonal = 1;" << endl; } @@ -155,17 +171,19 @@ ShocksStatement::writeCovarOrCorrShock(ostream &output, covar_and_corr_shocks_t: 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; + 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; } @@ -178,6 +196,15 @@ ShocksStatement::writeCovarOrCorrShock(ostream &output, covar_and_corr_shocks_t: 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 @@ -195,9 +222,6 @@ ShocksStatement::writeCovarAndCorrShocks(ostream &output) const void ShocksStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) { - // Workaround for trac ticket #35 - mod_file_struct.shocks_present_but_simul_not_yet = true; - /* 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 */ @@ -211,11 +235,7 @@ ShocksStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidati << symbol_table.getName(it->first) << "' is not allowed, because it is neither an exogenous variable nor an observed endogenous variable" << endl; exit(EXIT_FAILURE); } - - if (symbol_table.isObservedVariable(it->first)) - mod_file_struct.calibrated_measurement_errors = true; } - for (var_and_std_shocks_t::const_iterator it = std_shocks.begin(); it != std_shocks.end(); it++) @@ -227,9 +247,6 @@ ShocksStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidati << symbol_table.getName(it->first) << "' is not allowed, because it is neither an exogenous variable nor an observed endogenous variable" << endl; exit(EXIT_FAILURE); } - - if (symbol_table.isObservedVariable(it->first)) - mod_file_struct.calibrated_measurement_errors = true; } for (covar_and_corr_shocks_t::const_iterator it = covar_shocks.begin(); @@ -248,10 +265,6 @@ ShocksStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidati << 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); } - - if (symbol_table.isObservedVariable(symb_id1) - || symbol_table.isObservedVariable(symb_id2)) - mod_file_struct.calibrated_measurement_errors = true; } for (covar_and_corr_shocks_t::const_iterator it = corr_shocks.begin(); @@ -270,16 +283,59 @@ ShocksStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidati << 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); } - - if (symbol_table.isObservedVariable(it->first.first) - || symbol_table.isObservedVariable(it->first.second)) - mod_file_struct.calibrated_measurement_errors = true; } + + // 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); + } -MShocksStatement::MShocksStatement(const det_shocks_t &det_shocks_arg, +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, det_shocks_arg, symbol_table_arg) + AbstractShocksStatement(true, overwrite_arg, det_shocks_arg, symbol_table_arg) { } @@ -290,22 +346,14 @@ MShocksStatement::writeOutput(ostream &output, const string &basename) const << "% MSHOCKS instructions" << endl << "%" << endl; - // Write instruction that initializes a shock - output << "make_ex_;" << endl; + if (overwrite) + output << "M_.det_shocks = [];" << endl; writeDetShocks(output); } -void -MShocksStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) -{ - // Workaround for trac ticket #35 - mod_file_struct.shocks_present_but_simul_not_yet = true; -} - -ConditionalForecastPathsStatement::ConditionalForecastPathsStatement(const AbstractShocksStatement::det_shocks_t &paths_arg, const SymbolTable &symbol_table_arg) : +ConditionalForecastPathsStatement::ConditionalForecastPathsStatement(const AbstractShocksStatement::det_shocks_t &paths_arg) : paths(paths_arg), - symbol_table(symbol_table_arg), path_length(-1) { } @@ -317,7 +365,7 @@ ConditionalForecastPathsStatement::checkPass(ModFileStructure &mod_file_struct, it != paths.end(); it++) { int this_path_length = 0; - const vector &elems = it->second.first; + 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); @@ -346,16 +394,14 @@ ConditionalForecastPathsStatement::writeOutput(ostream &output, const string &ba if (it == paths.begin()) { output << "constrained_vars_ = " << it->first +1 << ";" << endl; - output << "constrained_perfect_foresight_ = " << it->second.second << ";" << endl; } else { output << "constrained_vars_ = [constrained_vars_; " << it->first +1 << "];" << endl; - output << "constrained_perfect_foresight_ = [constrained_perfect_foresight_; " << it->second.second << "];" << endl; } - const vector &elems = it->second.first; + 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++) { @@ -366,3 +412,47 @@ ConditionalForecastPathsStatement::writeOutput(ostream &output, const string &ba k++; } } + +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) 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; +} + +IrfCalibration::IrfCalibration(const constraints_t &constraints_arg, + const SymbolTable &symbol_table_arg) + : constraints(constraints_arg), symbol_table(symbol_table_arg) +{ +} + +void +IrfCalibration::writeOutput(ostream &output, const string &basename) const +{ + 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; +} diff --git a/Shocks.hh b/Shocks.hh index de20945c..6ab43a64 100644 --- a/Shocks.hh +++ b/Shocks.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -41,15 +41,17 @@ public: }; //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, bool> > det_shocks_t; + 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; - AbstractShocksStatement(bool mshocks_arg, + AbstractShocksStatement(bool mshocks_arg, bool overwrite_arg, const det_shocks_t &det_shocks_arg, const SymbolTable &symbol_table_arg); }; @@ -66,8 +68,10 @@ private: 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(const det_shocks_t &det_shocks_arg, + 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, @@ -80,23 +84,59 @@ public: class MShocksStatement : public AbstractShocksStatement { public: - MShocksStatement(const det_shocks_t &det_shocks_arg, + MShocksStatement(bool overwrite_arg, + const det_shocks_t &det_shocks_arg, const SymbolTable &symbol_table_arg); virtual void writeOutput(ostream &output, const string &basename) const; - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); }; 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); + ConditionalForecastPathsStatement(const AbstractShocksStatement::det_shocks_t &paths_arg); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename) 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) 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; +public: + IrfCalibration(const constraints_t &constraints_arg, + const SymbolTable &symbol_table_arg); + virtual void writeOutput(ostream &output, const string &basename) const; +}; + #endif diff --git a/SigmaeInitialization.hh b/SigmaeInitialization.hh index c2decb3f..ddfcc7f1 100644 --- a/SigmaeInitialization.hh +++ b/SigmaeInitialization.hh @@ -20,8 +20,6 @@ #ifndef _SIGMAEINITIALIZATION_HH #define _SIGMAEINITIALIZATION_HH -using namespace std; - #include #include diff --git a/Statement.cc b/Statement.cc index 59021287..70889c6b 100644 --- a/Statement.cc +++ b/Statement.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2013 Dynare Team + * Copyright (C) 2006-2014 Dynare Team * * This file is part of Dynare. * @@ -18,16 +18,18 @@ */ #include "Statement.hh" +#include ModFileStructure::ModFileStructure() : check_present(false), steady_present(false), - simul_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), @@ -38,7 +40,6 @@ ModFileStructure::ModFileStructure() : identification_present(false), estimation_analytic_derivation(false), partial_information(false), - shocks_present_but_simul_not_yet(false), histval_present(false), k_order_solver(false), calibrated_measurement_errors(false), @@ -47,7 +48,9 @@ ModFileStructure::ModFileStructure() : dsge_var_estimated(false), bayesian_irf_present(false), estimation_data_statement_present(false), - last_markov_switching_chain(0) + last_markov_switching_chain(0), + calib_smoother_present(false), + estim_params_use_calib(false) { } @@ -60,6 +63,11 @@ Statement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &wa { } +void +Statement::writeCOutput(ostream &output, const string &basename) +{ +} + void Statement::computingPass() { @@ -73,7 +81,14 @@ NativeStatement::NativeStatement(const string &native_statement_arg) : void NativeStatement::writeOutput(ostream &output, const string &basename) const { - output << native_statement << endl; + 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 << " = dynDate('" << it->second << "');" << endl; + 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++) @@ -137,7 +152,7 @@ OptionsList::writeOutput(ostream &output, const string &option_group) const for (date_options_t::const_iterator it = date_options.begin(); it != date_options.end(); it++) - output << option_group << "." << it->first << " = dynDate('" << it->second << "');" << endl; + 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++) diff --git a/Statement.hh b/Statement.hh index cd3fd5cf..5bdade39 100644 --- a/Statement.hh +++ b/Statement.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2013 Dynare Team + * Copyright (C) 2006-2014 Dynare Team * * This file is part of Dynare. * @@ -20,11 +20,10 @@ #ifndef _STATEMENT_HH #define _STATEMENT_HH -using namespace std; - #include #include #include +#include #include "SymbolList.hh" #include "WarningConsolidation.hh" @@ -37,8 +36,8 @@ public: bool check_present; //! Whether steady is present bool steady_present; - //! Whether a simul statement is present - bool simul_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 @@ -49,6 +48,8 @@ public: 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 @@ -71,11 +72,6 @@ public: bool estimation_analytic_derivation; //! Whether the option partial_information is given to stoch_simul/estimation/osr/ramsey_policy bool partial_information; - //! Whether a shocks or mshocks block has been parsed and no simul command yet run - /*! Used for the workaround for trac ticket #35. When a simul command is - seen, this flag is cleared in order to allow a sequence - shocks+endval+simul in a loop */ - bool shocks_present_but_simul_not_yet; //! Whether a histval bloc is present /*! Used for the workaround for trac ticket #157 */ bool histval_present; @@ -97,6 +93,29 @@ public: bool estimation_data_statement_present; //! Last chain number for Markov Switching statement 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; }; class Statement @@ -116,6 +135,7 @@ public: \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) const = 0; + virtual void writeCOutput(ostream &output, const string &basename); }; class NativeStatement : public Statement diff --git a/StaticModel.cc b/StaticModel.cc index c78324ea..18be48f1 100644 --- a/StaticModel.cc +++ b/StaticModel.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2012 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -286,7 +286,7 @@ StaticModel::writeModelEquationsOrdered_M(const string &static_basename) const 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) + if (dynamic_cast(*it) != NULL) (*it)->writeExternalFunctionOutput(output, local_output_type, tt2, tef_terms); output << " " << sps; @@ -658,7 +658,7 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string 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) + 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)); @@ -851,7 +851,7 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string 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) + 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)); @@ -1047,7 +1047,7 @@ StaticModel::collect_first_order_derivatives_endogenous() } void -StaticModel::computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian, bool paramsDerivatives, bool block, bool bytecode) +StaticModel::computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian, bool thirdDerivatives, bool paramsDerivatives, bool block, bool bytecode) { initializeVariablesAndEquations(); @@ -1070,6 +1070,12 @@ StaticModel::computingPass(const eval_context_t &eval_context, bool no_tmp_terms computeHessian(vars); } + if (thirdDerivatives) + { + cout << " - order 3" << endl; + computeThirdDerivatives(vars); + } + if (paramsDerivatives) { cout << " - derivatives of Jacobian/Hessian w.r. to parameters" << endl; @@ -1142,7 +1148,7 @@ StaticModel::writeStaticMFile(const string &func_name) const exit(EXIT_FAILURE); } - output << "function [residual, g1, g2] = " << func_name + "_static(y, x, params)" << endl + output << "function [residual, g1, g2, g3] = " << func_name + "_static(y, x, params)" << endl << "%" << endl << "% Status : Computes static model for Dynare" << endl << "%" << endl @@ -1155,11 +1161,14 @@ StaticModel::writeStaticMFile(const string &func_name) const << "% residual [M_.endo_nbr by 1] double vector of residuals of the static model equations " << endl << "% in order of declaration of the equations" << endl << "% g1 [M_.endo_nbr by M_.endo_nbr] double Jacobian matrix of the static model equations;" << endl - << "% columns: equations in order of declaration" << endl - << "% rows: variables in declaration order" << 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: equations in order of declaration" << endl - << "% rows: variables in declaration order" << 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 @@ -1176,6 +1185,7 @@ StaticModel::writeStaticModel(ostream &StaticOutput, bool use_dll) const ostringstream model_output; // Used for storing model 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 ? oCStaticModel : oMatlabStaticModel); deriv_node_temp_terms_t tef_terms; @@ -1185,6 +1195,10 @@ StaticModel::writeStaticModel(ostream &StaticOutput, bool use_dll) const 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 for (first_derivatives_t::const_iterator it = first_derivatives.begin(); it != first_derivatives.end(); it++) @@ -1247,6 +1261,64 @@ StaticModel::writeStaticModel(ostream &StaticOutput, bool use_dll) const } } + // Writing third derivatives + 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; + + 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, temporary_terms, 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) + { + 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 (!use_dll) { StaticOutput << "residual = zeros( " << equations.size() << ", 1);" << endl << endl @@ -1280,6 +1352,20 @@ StaticModel::writeStaticModel(ostream &StaticOutput, bool use_dll) const else StaticOutput << " g2 = sparse([],[],[]," << equations.size() << "," << g2ncols << ");" << endl; StaticOutput << "end" << 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; + } else { @@ -1305,6 +1391,14 @@ StaticModel::writeStaticModel(ostream &StaticOutput, bool use_dll) const << " {" << endl << hessian_output.str() << " }" << endl; + if (third_derivatives.size()) + StaticOutput << " /* Third derivatives for endogenous and exogenous variables */" << endl + << " if (v3 == NULL)" << endl + << " return;" << endl + << " else" << endl + << " {" << endl + << third_derivatives_output.str() + << " }" << endl; } } diff --git a/StaticModel.hh b/StaticModel.hh index f193c4c4..e76a5f0f 100644 --- a/StaticModel.hh +++ b/StaticModel.hh @@ -161,7 +161,7 @@ public: \param hessian whether 2nd derivatives w.r. to exo, exo_det and endo should be computed \param paramsDerivatives whether 2nd derivatives w.r. to a pair (endo/exo/exo_det, parameter) should be computed */ - void computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian,bool paramsDerivatives, bool block, bool bytecode); + void computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian, bool thirdDerivatices, bool paramsDerivatives, bool block, bool bytecode); //! 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, diff --git a/SteadyStateModel.cc b/SteadyStateModel.cc index f85aee07..d19a7f38 100644 --- a/SteadyStateModel.cc +++ b/SteadyStateModel.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 Dynare Team + * Copyright (C) 2010-2014 Dynare Team * * This file is part of Dynare. * @@ -39,8 +39,7 @@ SteadyStateModel::addDefinition(int symb_id, expr_t expr) // Add the variable vector v; v.push_back(symb_id); - recursive_order.push_back(v); - def_table[v] = expr; + def_table.push_back(make_pair(v, expr)); } void @@ -53,41 +52,40 @@ SteadyStateModel::addMultipleDefinitions(const vector &symb_ids, expr_t exp || symbol_table.getType(symb_ids[i]) == eModFileLocalVariable || symbol_table.getType(symb_ids[i]) == eParameter); } - recursive_order.push_back(symb_ids); - def_table[symb_ids] = expr; + def_table.push_back(make_pair(symb_ids, expr)); } void -SteadyStateModel::checkPass(bool ramsey_policy) const +SteadyStateModel::checkPass(bool ramsey_model, WarningConsolidation &warnings) const { + if (def_table.size() == 0) + return; + vector so_far_defined; - for (size_t i = 0; i < recursive_order.size(); i++) + for (size_t i = 0; i < def_table.size(); i++) { - const vector &symb_ids = recursive_order[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()) - { - cerr << "ERROR: in the 'steady_state' block, variable '" << symbol_table.getName(symb_ids[j]) << "' is declared twice" << endl; - exit(EXIT_FAILURE); - } - + 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 (!ramsey_policy) + if (!ramsey_model) { - set > used_symbols; - expr_t expr = def_table.find(symb_ids)->second; + 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(); + for (set::const_iterator it = used_symbols.begin(); it != used_symbols.end(); ++it) - if (find(so_far_defined.begin(), so_far_defined.end(), it->first) + if (find(so_far_defined.begin(), so_far_defined.end(), *it) == so_far_defined.end()) { - cerr << "ERROR: in the 'steady_state' block, variable '" << symbol_table.getName(it->first) + 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); } @@ -95,12 +93,21 @@ SteadyStateModel::checkPass(bool ramsey_policy) const 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::writeSteadyStateFile(const string &basename, bool ramsey_policy) const +SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_model) const { - if (recursive_order.size() == 0) + if (def_table.size() == 0) return; string filename = basename + "_steadystate2.m"; @@ -118,9 +125,9 @@ SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_polic << "% Steady state generated by Dynare preprocessor" << endl << " info = 0;" << endl; - for (size_t i = 0; i < recursive_order.size(); i++) + for (size_t i = 0; i < def_table.size(); i++) { - const vector &symb_ids = recursive_order[i]; + const vector &symb_ids = def_table[i].first; output << " "; if (symb_ids.size() > 1) output << "["; @@ -136,7 +143,7 @@ SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_polic output << "]"; output << "="; - def_table.find(symb_ids)->second->writeOutput(output, oSteadyStateFile); + def_table[i].second->writeOutput(output, oSteadyStateFile); output << ";" << endl; } output << " % Auxiliary equations" << endl; diff --git a/SteadyStateModel.hh b/SteadyStateModel.hh index cbb206af..64b78573 100644 --- a/SteadyStateModel.hh +++ b/SteadyStateModel.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 Dynare Team + * Copyright (C) 2010-2014 Dynare Team * * This file is part of Dynare. * @@ -22,13 +22,13 @@ #include "DataTree.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) - map, expr_t> def_table; - vector > recursive_order; + vector, expr_t> > def_table; //! Reference to static model (for writing auxiliary equations) const StaticModel &static_model; @@ -41,14 +41,16 @@ public: 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_policy Is there a ramsey_policy statement in the MOD file? If yes, then disable the check on the recursivity of the declarations + \param[in] ramsey_model Is there a Ramsey model in the MOD file? If yes, then disable the check on the recursivity of the declarations */ - void checkPass(bool ramsey_policy) const; + void checkPass(bool ramsey_model, WarningConsolidation &warnings) const; //! Write the steady state file /*! - \param[in] ramsey_policy Is there a ramsey_policy statement in the MOD file? If yes, then use the "ys" in argument of the steady state file as initial values + \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_policy) const; + void writeSteadyStateFile(const string &basename, bool ramsey_model) const; + // in ExternalFiles.cc + void writeSteadyStateFileC(const string &basename, bool ramsey_model) const; }; #endif diff --git a/SymbolList.cc b/SymbolList.cc index af4c1911..dca1410e 100644 --- a/SymbolList.cc +++ b/SymbolList.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2010 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -28,13 +28,15 @@ SymbolList::addSymbol(const string &symbol) void SymbolList::writeOutput(const string &varname, ostream &output) const { - output << varname << "=[];" << endl; + output << varname << " = char("; for (vector::const_iterator it = symbols.begin(); - it != symbols.end(); it++) - if (it == symbols.begin()) - output << varname << " = '" << *it << "';" << endl; - else - output << varname << " = char(" << varname << ", '" << *it << "');" << endl; + it != symbols.end(); ++it) + { + if (it != symbols.begin()) + output << ","; + output << "'" << *it << "'"; + } + output << ");" << endl; } void diff --git a/SymbolList.hh b/SymbolList.hh index dafa965b..82f0b794 100644 --- a/SymbolList.hh +++ b/SymbolList.hh @@ -20,12 +20,12 @@ #ifndef _SYMBOL_LIST_HH #define _SYMBOL_LIST_HH -using namespace std; - #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 @@ -43,6 +43,8 @@ public: 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/SymbolTable.cc b/SymbolTable.cc index 4141e941..aa636b97 100644 --- a/SymbolTable.cc +++ b/SymbolTable.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -39,7 +39,7 @@ SymbolTable::SymbolTable() : frozen(false), size(0) } int -SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_name) throw (AlreadyDeclaredException, FrozenException) +SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_name, const string &long_name) throw (AlreadyDeclaredException, FrozenException) { if (frozen) throw FrozenException(); @@ -52,12 +52,29 @@ SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_na 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 = long_name; + if (final_long_name.empty()) + final_long_name = name; + int id = size++; symbol_table[name] = id; type_table.push_back(type); name_table.push_back(name); - tex_name_table.push_back(tex_name); + tex_name_table.push_back(final_tex_name); + long_name_table.push_back(final_long_name); return id; } @@ -65,15 +82,7 @@ SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_na int SymbolTable::addSymbol(const string &name, SymbolType type) throw (AlreadyDeclaredException, FrozenException) { - // Construct "tex_name" by prepending an antislash to all underscores in "name" - string tex_name = name; - size_t pos = 0; - while ((pos = tex_name.find('_', pos)) != string::npos) - { - tex_name.insert(pos, "\\"); - pos += 2; - } - return addSymbol(name, type, tex_name); + return addSymbol(name, type, "", ""); } void @@ -168,40 +177,48 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException) { output << "M_.exo_names = '" << getName(exo_ids[0]) << "';" << endl; output << "M_.exo_names_tex = '" << getTeXName(exo_ids[0]) << "';" << endl; + output << "M_.exo_names_long = '" << getLongName(exo_ids[0]) << "';" << endl; for (int id = 1; id < exo_nbr(); id++) { output << "M_.exo_names = char(M_.exo_names, '" << getName(exo_ids[id]) << "');" << endl - << "M_.exo_names_tex = char(M_.exo_names_tex, '" << getTeXName(exo_ids[id]) << "');" << endl; + << "M_.exo_names_tex = char(M_.exo_names_tex, '" << getTeXName(exo_ids[id]) << "');" << endl + << "M_.exo_names_long = char(M_.exo_names_long, '" << getLongName(exo_ids[id]) << "');" << endl; } } if (exo_det_nbr() > 0) { output << "M_.exo_det_names = '" << getName(exo_det_ids[0]) << "';" << endl; output << "M_.exo_det_names_tex = '" << getTeXName(exo_det_ids[0]) << "';" << endl; + output << "M_.exo_det_names_long = '" << getLongName(exo_det_ids[0]) << "';" << endl; for (int id = 1; id < exo_det_nbr(); id++) { output << "M_.exo_det_names = char(M_.exo_det_names, '" << getName(exo_det_ids[id]) << "');" << endl - << "M_.exo_det_names_tex = char(M_.exo_det_names_tex, '" << getTeXName(exo_det_ids[id]) << "');" << endl; + << "M_.exo_det_names_tex = char(M_.exo_det_names_tex, '" << getTeXName(exo_det_ids[id]) << "');" << endl + << "M_.exo_det_names_long = char(M_.exo_det_names_long, '" << getLongName(exo_det_ids[id]) << "');" << endl; } } if (endo_nbr() > 0) { output << "M_.endo_names = '" << getName(endo_ids[0]) << "';" << endl; output << "M_.endo_names_tex = '" << getTeXName(endo_ids[0]) << "';" << endl; + output << "M_.endo_names_long = '" << getLongName(endo_ids[0]) << "';" << endl; for (int id = 1; id < endo_nbr(); id++) { output << "M_.endo_names = char(M_.endo_names, '" << getName(endo_ids[id]) << "');" << endl - << "M_.endo_names_tex = char(M_.endo_names_tex, '" << getTeXName(endo_ids[id]) << "');" << endl; + << "M_.endo_names_tex = char(M_.endo_names_tex, '" << getTeXName(endo_ids[id]) << "');" << endl + << "M_.endo_names_long = char(M_.endo_names_long, '" << getLongName(endo_ids[id]) << "');" << endl; } } if (param_nbr() > 0) { output << "M_.param_names = '" << getName(param_ids[0]) << "';" << endl; output << "M_.param_names_tex = '" << getTeXName(param_ids[0]) << "';" << endl; + output << "M_.param_names_long = '" << getLongName(param_ids[0]) << "';" << endl; for (int id = 1; id < param_nbr(); id++) { output << "M_.param_names = char(M_.param_names, '" << getName(param_ids[id]) << "');" << endl - << "M_.param_names_tex = char(M_.param_names_tex, '" << getTeXName(param_ids[id]) << "');" << endl; + << "M_.param_names_tex = char(M_.param_names_tex, '" << getTeXName(param_ids[id]) << "');" << endl + << "M_.param_names_long = char(M_.param_names_long, '" << getLongName(param_ids[id]) << "');" << endl; if (getName(param_ids[id]) == "dsge_prior_weight") output << "options_.dsge_var = 1;" << endl; @@ -269,6 +286,168 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException) } } +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; + if (exo_nbr() > 0) + 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; + if (exo_det_nbr() > 0) + 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; + if (endo_nbr() > 0) + for (int id = 0; id < endo_nbr(); id++) + output << "endo_names[\"" << getName(endo_ids[id]) << "\"] = " << id << ";" << endl; + + output << endl + << "int param_nbr = " << param_nbr() << ";" << endl; + if (param_nbr() > 0) + for (int id = 0; id < param_nbr(); id++) + output << "param_names[\"" << getName(param_ids[id]) << "\"] = " << id << ";" << endl; + + // Write the auxiliary variable table + if (aux_vars.size() > 0) + 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; + } + + if (predeterminedNbr() > 0) + for (set::const_iterator it = predetermined_variables.begin(); + it != predetermined_variables.end(); it++) + output << "predetermined_variables.push_back(" << getTypeSpecificID(*it) << ");" << endl; + + if (observedVariablesNbr() > 0) + 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) throw (FrozenException) { @@ -510,3 +689,23 @@ SymbolTable::getEndogenous() const 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; +} + +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; +} diff --git a/SymbolTable.hh b/SymbolTable.hh index a8a032f5..3e4c47e1 100644 --- a/SymbolTable.hh +++ b/SymbolTable.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 Dynare Team + * Copyright (C) 2003-2014 Dynare Team * * This file is part of Dynare. * @@ -87,6 +87,8 @@ private: 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 types vector type_table; @@ -182,7 +184,7 @@ private: public: //! Add a symbol /*! Returns the symbol ID */ - int addSymbol(const string &name, SymbolType type, const string &tex_name) throw (AlreadyDeclaredException, FrozenException); + int addSymbol(const string &name, SymbolType type, const string &tex_name, const string &long_name) 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); @@ -242,6 +244,8 @@ public: 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); //! Get type (by ID) inline SymbolType getType(int id) const throw (UnknownSymbolIDException); //! Get type (by name) @@ -272,6 +276,10 @@ public: inline int orig_endo_nbr() const throw (NotYetFrozenException); //! Write output of this class void writeOutput(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 @@ -291,6 +299,10 @@ public: set getExogenous() const; //! Get list of endogenous variables set getEndogenous() const; + //! Is a given symbol an auxiliary variable + bool isAuxiliaryVariable(int symb_id) const; + //! Get list of endogenous variables without aux vars + set getOrigEndogenous() const; }; inline bool @@ -318,6 +330,15 @@ SymbolTable::getTeXName(int id) const throw (UnknownSymbolIDException) return tex_name_table[id]; } +inline string +SymbolTable::getLongName(int id) const throw (UnknownSymbolIDException) +{ + if (id < 0 || id >= size) + throw UnknownSymbolIDException(id); + else + return long_name_table[id]; +} + inline SymbolType SymbolTable::getType(int id) const throw (UnknownSymbolIDException) { diff --git a/WarningConsolidation.cc b/WarningConsolidation.cc index beaf061d..653d4730 100644 --- a/WarningConsolidation.cc +++ b/WarningConsolidation.cc @@ -17,8 +17,6 @@ * along with Dynare. If not, see . */ -using namespace std; - #include "WarningConsolidation.hh" #include diff --git a/WarningConsolidation.hh b/WarningConsolidation.hh index ba633014..135a54a3 100644 --- a/WarningConsolidation.hh +++ b/WarningConsolidation.hh @@ -20,12 +20,12 @@ #ifndef _WARNINGCONSOLIDATION_HH #define _WARNINGCONSOLIDATION_HH -using namespace std; - #include #include #include "location.hh" +using namespace std; + //! Stores Warnings issued by the Preprocessor class WarningConsolidation { diff --git a/macro/MacroBison.yy b/macro/MacroBison.yy index a7a6456e..2bd8072a 100644 --- a/macro/MacroBison.yy +++ b/macro/MacroBison.yy @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2013 Dynare Team + * Copyright (C) 2008-2014 Dynare Team * * This file is part of Dynare. * @@ -18,24 +18,14 @@ */ %skeleton "lalr1.cc" -%require "2.3" +%require "2.5" %defines -/* Prologue: - In Bison <= 2.3, it is inserted in both the .cc and .hh files. - In Bison >= 2.3a, it is inserted only in the .cc file. - Since Bison 2.4, the new %code directives provide a cleaner way of dealing - with the prologue. -*/ -%{ -using namespace std; - -#include "MacroValue.hh" - +%code top { class MacroDriver; -%} +} -%name-prefix="Macro" +%name-prefix "Macro" %parse-param { MacroDriver &driver } %parse-param { ostream &out } @@ -51,6 +41,10 @@ class MacroDriver; %debug %error-verbose +%code requires { +#include "MacroValue.hh" +} + %union { string *string_val; @@ -58,7 +52,7 @@ class MacroDriver; const MacroValue *mv; }; -%{ +%code { #include // Pour atoi() #include "MacroDriver.hh" @@ -77,7 +71,7 @@ class MacroDriver; 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 diff --git a/macro/MacroValue.hh b/macro/MacroValue.hh index d79c024c..25016478 100644 --- a/macro/MacroValue.hh +++ b/macro/MacroValue.hh @@ -20,12 +20,12 @@ #ifndef _MACRO_VALUE_HH #define _MACRO_VALUE_HH -using namespace std; - #include #include #include +using namespace std; + class MacroDriver; //! Base class for representing values in macro language