/* * Copyright © 2004-2011 Ondra Kamenik * Copyright © 2019-2020 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 "dynare3.hh" #include "dynare_exception.hh" #include "dynare_params.hh" #include "utils/cc/exception.hh" #include "parser/cc/parser_exception.hh" #include "../sylv/cc/SylvException.hh" #include "../kord/seed_generator.hh" #include "../kord/global_check.hh" #include "../kord/approximation.hh" #include #include #include int main(int argc, char **argv) { DynareParams params(argc, argv); if (params.help) { params.printHelp(); return EXIT_SUCCESS; } if (params.version) { std::cout << "Dynare++ v. " << VERSION << '\n' << '\n' << u8"Copyright © 2004-2011 Ondra Kamenik\n" << u8"Copyright © 2019-2020 Dynare Team\n" << "Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under the GNU GPL,\n" << "version 3 or later (see https://www.gnu.org/licenses/gpl.html)\n"; return EXIT_SUCCESS; } sthread::detach_thread_group::max_parallel_threads = params.num_threads; try { // make journal Journal journal(params.basename + ".jnl"); // make dynare object Dynare dynare(params.modname, params.order, params.ss_tol, journal); // make list of shocks for which we will do IRFs std::vector irf_list_ind; if (params.do_irfs_all) for (int i = 0; i < dynare.nexog(); i++) irf_list_ind.push_back(i); else irf_list_ind = static_cast(dynare.getExogNames()).selectIndices(params.irf_list); // write matlab files std::string mfile1(params.basename + "_f.m"); std::ofstream mfd{mfile1, std::ios::out | std::ios::trunc}; if (mfd.fail()) { std::cerr << "Couldn't open " << mfile1 << " for writing.\n"; std::exit(EXIT_FAILURE); } ogdyn::MatlabSSWriter writer0(dynare.getModel(), params.basename); writer0.write_der0(mfd); mfd.close(); std::string mfile2(params.basename + "_ff.m"); mfd.open(mfile2, std::ios::out | std::ios::trunc); if (mfd.fail()) { std::cerr << "Couldn't open " << mfile2 << " for writing.\n"; std::exit(EXIT_FAILURE); } ogdyn::MatlabSSWriter writer1(dynare.getModel(), params.basename); writer1.write_der1(mfd); mfd.close(); // open mat file std::string matfile(params.basename + ".mat"); mat_t *matfd = Mat_Create(matfile.c_str(), nullptr); if (!matfd) { std::cerr << "Couldn't open " << matfile << " for writing.\n"; std::exit(EXIT_FAILURE); } // write info about the model (dimensions and variables) dynare.writeMat(matfd, params.prefix); // write the dump file corresponding to the input dynare.writeDump(params.basename); seed_generator::set_meta_seed(static_cast(params.seed)); TLStatic::init(dynare.order(), dynare.nstat()+2*dynare.npred()+3*dynare.nboth() +2*dynare.nforw()+dynare.nexog()); Approximation app(dynare, journal, params.num_steps, params.do_centralize, params.qz_criterium); try { app.walkStochSteady(); } catch (const KordException &e) { // tell about the exception and continue std::cout << "Caught (not yet fatal) Kord exception: "; e.print(); JournalRecord rec(journal); rec << "Solution routine not finished (" << e.get_message() << "), see what happens" << endrec; } std::string ss_matrix_name(params.prefix + "_steady_states"); ConstTwoDMatrix(app.getSS()).writeMat(matfd, ss_matrix_name); // check the approximation if (params.check_along_path || params.check_along_shocks || params.check_on_ellipse) { GlobalChecker gcheck(app, sthread::detach_thread_group::max_parallel_threads, journal); if (params.check_along_shocks) gcheck.checkAlongShocksAndSave(matfd, params.prefix, params.getCheckShockPoints(), params.getCheckShockScale(), params.check_evals); if (params.check_on_ellipse) gcheck.checkOnEllipseAndSave(matfd, params.prefix, params.getCheckEllipsePoints(), params.getCheckEllipseScale(), params.check_evals); if (params.check_along_path) gcheck.checkAlongSimulationAndSave(matfd, params.prefix, params.getCheckPathPoints(), params.check_evals); } // write the folded decision rule to the Mat-4 file app.getFoldDecisionRule().writeMat(matfd, params.prefix); // simulate conditional if (params.num_condper > 0 && params.num_condsim > 0) { SimResultsDynamicStats rescond(dynare.numeq(), params.num_condper, 0); Vector det_ss{app.getSS().getCol(0)}; rescond.simulate(params.num_condsim, app.getFoldDecisionRule(), det_ss, dynare.getVcov(), journal); rescond.writeMat(matfd, params.prefix); } // simulate unconditional //const DecisionRule& dr = app.getUnfoldDecisionRule(); const DecisionRule &dr = app.getFoldDecisionRule(); if (params.num_per > 0 && params.num_sim > 0) { SimResultsStats res(dynare.numeq(), params.num_per, params.num_burn); res.simulate(params.num_sim, dr, dynare.getSteady(), dynare.getVcov(), journal); res.writeMat(matfd, params.prefix); // impulse response functions if (!irf_list_ind.empty()) { IRFResults irf(dynare, dr, res, irf_list_ind, journal); irf.writeMat(matfd, params.prefix); } } // simulate with real-time statistics if (params.num_rtper > 0 && params.num_rtsim > 0) { RTSimResultsStats rtres(dynare.numeq(), params.num_rtper, params.num_burn); rtres.simulate(params.num_rtsim, dr, dynare.getSteady(), dynare.getVcov(), journal); rtres.writeMat(matfd, params.prefix); } Mat_Close(matfd); } catch (const KordException &e) { std::cout << "Caught Kord exception: "; e.print(); return e.code(); } catch (const TLException &e) { std::cout << "Caught TL exception: "; e.print(); return 255; } catch (SylvException &e) { std::cout << "Caught Sylv exception: "; e.printMessage(); return 255; } catch (const DynareException &e) { std::cout << "Caught Dynare exception: " << e.message() << '\n'; return 255; } catch (const ogu::Exception &e) { std::cout << "Caught ogu::Exception: "; e.print(); return 255; } catch (const ogp::ParserException &e) { std::cout << "Caught parser exception: " << e.message() << '\n'; return 255; } return EXIT_SUCCESS; }