// Copyright (C) 2005, Ondra Kamenik // $Id: fine_atoms.cpp 1759 2008-03-31 14:25:20Z kamenik $ #include "utils/cc/exception.h" #include "parser_exception.h" #include "fine_atoms.h" using namespace ogp; AllvarOuterOrdering::AllvarOuterOrdering(const vector& allvar_outer, const FineAtoms& a) : atoms(a), allvar(), endo2all(a.get_endovars().size(), -1), exo2all(a.get_exovars().size(), -1) { // fill in the allvar from allvar_outer for (unsigned int i = 0; i < allvar_outer.size(); i++) { const char* s = atoms.varnames.query(allvar_outer[i]); if (s) allvar.push_back(s); else throw ogu::Exception(__FILE__, __LINE__, string("Variable ") + allvar_outer[i] + " is not a declared symbol in AllvarOuterOrdering constructor"); } // fill in endo2all and exo2all for (unsigned int i = 0; i < allvar.size(); i++) { Tvarintmap::const_iterator it = atoms.endo_outer_map.find(allvar[i]); if (it != atoms.endo_outer_map.end()) endo2all[(*it).second] = i; else { it = atoms.exo_outer_map.find(allvar[i]); if (it != atoms.exo_outer_map.end()) exo2all[(*it).second] = i; else throw ogu::Exception(__FILE__, __LINE__, string("Name ") + allvar[i] + " is neither endogenous nor exogenous variable in AllvarOuterOrdering constructor"); } } // check whether everything has been filled unsigned int iendo = 0; while (iendo < endo2all.size() && endo2all[iendo] != -1) iendo++; unsigned int iexo = 0; while (iexo < exo2all.size() && exo2all[iexo] != -1) iexo++; if (iendo < endo2all.size()) throw ogu::Exception(__FILE__, __LINE__, string("Endogenous variable ") + atoms.get_endovars()[iendo] + " not found in outer all ordering in AllvarOuterOrdering constructor"); if (iexo < exo2all.size()) throw ogu::Exception(__FILE__, __LINE__, string("Exogenous variable ") + atoms.get_exovars()[iexo] + " not found in outer all ordering in AllvarOuterOrdering constructor"); } AllvarOuterOrdering::AllvarOuterOrdering(const AllvarOuterOrdering& avo, const FineAtoms& a) : atoms(a), allvar(), endo2all(avo.endo2all), exo2all(avo.exo2all) { // fill in the allvar from avo.allvar for (unsigned int i = 0; i < avo.allvar.size(); i++) { const char* s = atoms.varnames.query(avo.allvar[i]); allvar.push_back(s); } } FineAtoms::FineAtoms(const FineAtoms& fa) : DynamicAtoms(fa), params(), endovars(), exovars(), endo_order(NULL), exo_order(NULL), allvar_order(NULL), der_atoms(fa.der_atoms), endo_atoms_map(fa.endo_atoms_map), exo_atoms_map(fa.exo_atoms_map) { // fill in params for (unsigned int i = 0; i < fa.params.size(); i++) { const char* s = varnames.query(fa.params[i]); if (! s) throw ogu::Exception(__FILE__, __LINE__, string("Parameter ") + fa.params[i] + " does not exist in FineAtoms copy cosntructor"); params.push_back(s); param_outer_map.insert(Tvarintmap::value_type(s, params.size()-1)); } // fill in endovars for (unsigned int i = 0; i < fa.endovars.size(); i++) { const char* s = varnames.query(fa.endovars[i]); if (! s) throw ogu::Exception(__FILE__, __LINE__, string("Endo variable ") + fa.endovars[i] + " does not exist in FineAtoms copy constructor"); endovars.push_back(s); endo_outer_map.insert(Tvarintmap::value_type(s, endovars.size()-1)); } // fill in exovars for (unsigned int i = 0; i < fa.exovars.size(); i++) { const char* s = varnames.query(fa.exovars[i]); if (! s) throw ogu::Exception(__FILE__, __LINE__, string("Exo variable ") + fa.exovars[i] + " does not exist in FineAtoms copy cosntructor"); exovars.push_back(s); exo_outer_map.insert(Tvarintmap::value_type(s, exovars.size()-1)); } if (fa.endo_order) endo_order = fa.endo_order->clone(endovars, *this); if (fa.exo_order) exo_order = fa.exo_order->clone(exovars, *this); if (fa.allvar_order) allvar_order = new AllvarOuterOrdering(*(fa.allvar_order), *this); } int FineAtoms::check_variable(const char* name) const { string str; int ll; parse_variable(name, str, ll); if (varnames.query(str.c_str())) return DynamicAtoms::check_variable(name); else { throw ParserException(string("Variable <")+str+"> not declared.",0); return -1; } } int FineAtoms::num_exo_periods() const { int mlead, mlag; exovarspan(mlead, mlag); return mlead-mlag+1; } void FineAtoms::parsing_finished(VarOrdering::ord_type ot) { make_internal_orderings(ot); // by default, concatenate outer endo and outer exo and make it as // allvar outer: vector allvar_tmp; allvar_tmp.insert(allvar_tmp.end(), endovars.begin(), endovars.end()); allvar_tmp.insert(allvar_tmp.end(), exovars.begin(), exovars.end()); if (allvar_order) delete allvar_order; allvar_order = new AllvarOuterOrdering(allvar_tmp, *this); } void FineAtoms::parsing_finished(VarOrdering::ord_type ot, const vector allvar) { make_internal_orderings(ot); if (allvar_order) delete allvar_order; allvar_order = new AllvarOuterOrdering(allvar, *this); } const vector& FineAtoms::get_allvar() const { if (! allvar_order) throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::get_allvars called before parsing_finished"); return allvar_order->get_allvar(); } const vector& FineAtoms::outer_endo2all() const { if (! allvar_order) throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::outer_endo2all called before parsing_finished"); return allvar_order->get_endo2all(); } const vector& FineAtoms::outer_exo2all() const { if (! allvar_order) throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::outer_exo2all called before parsing_finished"); return allvar_order->get_exo2all(); } vector FineAtoms::variables() const { if (endo_order) { return der_atoms; } else { throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::variables called before parsing_finished"); return vector(); } } int FineAtoms::nstat() const { if (endo_order) { return endo_order->nstat(); } else { throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::nstat called before parsing_finished"); return -1; } } int FineAtoms::npred() const { if (endo_order) { return endo_order->npred(); } else { throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::npred called before parsing_finished"); return -1; } } int FineAtoms::nboth() const { if (endo_order) { return endo_order->nboth(); } else { throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::nboth called before parsing_finished"); return -1; } } int FineAtoms::nforw() const { if (endo_order) { return endo_order->nforw(); } else { throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::nforw called before parsing_finished"); return -1; } } int FineAtoms::get_pos_of_endo(int t) const { if (endo_order) { return endo_order->get_pos_of(t); } else { throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::get_pos_of_endo called before parsing_finished"); return -1; } } int FineAtoms::get_pos_of_exo(int t) const { if (exo_order) { return exo_order->get_pos_of(t); } else { throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::get_pos_of_exo called before parsing_finished"); return -1; } } int FineAtoms::get_pos_of_all(int t) const { if (endo_order && exo_order) { if (endo_order->check(t)) return endo_order->get_pos_of(t); else if (exo_order->check(t)) return endo_order->length() + exo_order->get_pos_of(t); else { throw ogu::Exception(__FILE__,__LINE__, "Atom is not endo nor exo in FineAtoms::get_pos_of_all"); return -1; } } else { throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::get_pos_of_exo called before parsing_finished"); return -1; } } const vector& FineAtoms::y2outer_endo() const { if (! endo_order) throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::y2outer_endo called before parsing_finished"); return endo_order->get_y2outer(); } const vector& FineAtoms::outer2y_endo() const { if (! endo_order) throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::outer2y_endo called before parsing_finished"); return endo_order->get_outer2y(); } const vector& FineAtoms::y2outer_exo() const { if (! exo_order) throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::y2outer_endo called before parsing_finished"); return exo_order->get_y2outer(); } const vector& FineAtoms::outer2y_exo() const { if (! exo_order) throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::outer2y_exo called before parsing_finished"); return exo_order->get_outer2y(); } const vector& FineAtoms::get_endo_atoms_map() const { if (! endo_order) throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::get_endo_atoms_map called before parsing_finished"); return endo_atoms_map; } const vector& FineAtoms::get_exo_atoms_map() const { if (! exo_order) throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::get_exo_atoms_map called before parsing_finished"); return exo_atoms_map; } int FineAtoms::name2outer_param(const char* name) const { Tvarintmap::const_iterator it = param_outer_map.find(name); if (it == param_outer_map.end()) throw ogu::Exception(__FILE__,__LINE__, "Name is not a parameter in FineAtoms::name2outer_param"); return (*it).second; } int FineAtoms::name2outer_endo(const char* name) const { Tvarintmap::const_iterator it = endo_outer_map.find(name); if (it == endo_outer_map.end()) throw ogu::Exception(__FILE__,__LINE__, "Name is not an endogenous variable in FineAtoms::name2outer_endo"); return (*it).second; } int FineAtoms::name2outer_exo(const char* name) const { Tvarintmap::const_iterator it = exo_outer_map.find(name); if (it == exo_outer_map.end()) throw ogu::Exception(__FILE__,__LINE__, "Name is not an exogenous variable in FineAtoms::name2outer_exo"); return (*it).second; } int FineAtoms::name2outer_allvar(const char* name) const { if (! allvar_order) throw ogu::Exception(__FILE__,__LINE__, "FineAtoms::name2outer_allvar called beore parsing_finished"); Tvarintmap::const_iterator it = endo_outer_map.find(name); if (it != endo_outer_map.end()) return allvar_order->get_endo2all()[(*it).second]; else { it = exo_outer_map.find(name); if (it != exo_outer_map.end()) return allvar_order->get_exo2all()[(*it).second]; } throw ogu::Exception(__FILE__,__LINE__, string("Name ") + name + " is neither endo nor exo variable in FineAtoms::name2outer_allvar"); return -1; } void FineAtoms::register_uniq_endo(const char* name) { if (varnames.query(name)) throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.",0); const char* ss = varnames.insert(name); endovars.push_back(ss); endo_outer_map.insert(Tvarintmap::value_type(ss, endovars.size()-1)); } void FineAtoms::register_uniq_exo(const char* name) { if (varnames.query(name)) throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.",0); const char* ss = varnames.insert(name); exovars.push_back(ss); exo_outer_map.insert(Tvarintmap::value_type(ss, exovars.size()-1)); } void FineAtoms::register_uniq_param(const char* name) { if (varnames.query(name)) throw ogp::ParserException(string("Parameter <")+name+"> is not unique.",0); const char* ss = varnames.insert(name); params.push_back(ss); param_outer_map.insert(Tvarintmap::value_type(ss, params.size()-1)); } void FineAtoms::make_internal_orderings(VarOrdering::ord_type ot) { bool endo_ordering_done = false; bool exo_ordering_done = false; order_type = ot; int mlead, mlag; endovarspan(mlead, mlag); if (mlag >= -1 && mlead <= 1) { // make endo ordering if (endo_order) delete endo_order; if (ot == VarOrdering::pbspbfbf) endo_order = new EndoVarOrdering1(endovars, *this); else endo_order = new EndoVarOrdering2(endovars, *this); endo_order->do_ordering(); endo_ordering_done = true; } exovarspan(mlead, mlag); if (mlag == 0 && mlead == 0) { // make exo ordering if (exo_order) delete exo_order; exo_order = new ExoVarOrdering(exovars, *this); exo_order->do_ordering(); exo_ordering_done = true; } if (endo_ordering_done && exo_ordering_done) { // concatenate der atoms from endo_order and exo_order der_atoms.clear(); der_atoms.insert(der_atoms.end(), endo_order->get_der_atoms().begin(), endo_order->get_der_atoms().end()); der_atoms.insert(der_atoms.end(), exo_order->get_der_atoms().begin(), exo_order->get_der_atoms().end()); // create endo_atoms_map; der_atoms is a concatenation, so it is easy int endo_atoms = endo_order->get_der_atoms().size(); endo_atoms_map.clear(); for (int i = 0; i < endo_atoms; i++) endo_atoms_map.push_back(i); // create exo_atoms_map int exo_atoms = exo_order->get_der_atoms().size(); exo_atoms_map.clear(); for (int i = 0; i < exo_atoms; i++) exo_atoms_map.push_back(endo_atoms + i); } } void FineAtoms::print() const { DynamicAtoms::print(); if (endo_order) { printf("Endo ordering:\n"); endo_order->print(); } else { printf("Endo ordering not created.\n"); } if (exo_order) { printf("Exo ordering:\n"); exo_order->print(); } else { printf("Exo ordering not created.\n"); } printf("endo atoms map:\n"); for (unsigned int i = 0; i < endo_atoms_map.size(); i++) printf("%d --> %d\n", i, endo_atoms_map[i]); printf("exo atoms map:\n"); for (unsigned int i = 0; i < exo_atoms_map.size(); i++) printf("%d --> %d\n", i, exo_atoms_map[i]); }