// Copyright (C) 2005, Ondra Kamenik // $Id: fine_atoms.h 1759 2008-03-31 14:25:20Z kamenik $ #ifndef OGP_FINE_ATOMS_H #define OGP_FINE_ATOMS_H #include "dynamic_atoms.h" #include #include namespace ogp { using std::vector; using std::string; /** This is just ordering used for endogenous variables. It * assumes that we have only time t-1, t, and t+1, orders them as * pred(t-1), both(t-1), stat(t), pred(t), both(t), forw(t), * both(t+1), forw(t+1). */ class EndoVarOrdering1 : public VarOrdering { public: EndoVarOrdering1(const vector& vnames, const DynamicAtoms& a) : VarOrdering(vnames, a) {} EndoVarOrdering1(const EndoVarOrdering1& vo, const vector& vnames, const DynamicAtoms& a) : VarOrdering(vo, vnames, a) {} VarOrdering* clone(const vector& vnames, const DynamicAtoms& a) const {return new EndoVarOrdering1(*this, vnames, a);} void do_ordering() {do_pbspbfbf();} }; /** This is just another ordering used for endogenous * variables. It assumes that we have only time t-1, t, and t+1, * orders them as both(t+1), forw(t+1), pred(t-1), both(t-1), * stat(t), pred(t), both(t), forw(t). */ class EndoVarOrdering2 : public VarOrdering { public: EndoVarOrdering2(const vector& vnames, const DynamicAtoms& a) : VarOrdering(vnames, a) {} EndoVarOrdering2(const EndoVarOrdering2& vo, const vector& vnames, const DynamicAtoms& a) : VarOrdering(vo, vnames, a) {} VarOrdering* clone(const vector& vnames, const DynamicAtoms& a) const {return new EndoVarOrdering2(*this, vnames, a);} void do_ordering() {do_bfspbfpb();} }; /** This is just ordering used for exogenous variables. It makes * no assumptions about their timing. It orders them from the * least time to the latest time. */ class ExoVarOrdering : public VarOrdering { public: ExoVarOrdering(const vector& vnames, const DynamicAtoms& a) : VarOrdering(vnames, a) {} ExoVarOrdering(const ExoVarOrdering& vo, const vector& vnames, const DynamicAtoms& a) : VarOrdering(vo, vnames, a) {} VarOrdering* clone(const vector& vnames, const DynamicAtoms& a) const {return new ExoVarOrdering(*this, vnames, a);} void do_ordering() {do_increasing_time();} }; class FineAtoms; /** This class provides an outer ordering of all variables (endo * and exo). It maps the ordering to the particular outer * orderings of endo and exo. It works tightly with the FineAtoms * class. */ class AllvarOuterOrdering { protected: /** Type for a map mapping a variable name to an integer. */ typedef map Tvarintmap; /** Reference to atoms. */ const FineAtoms& atoms; /** The vector of all endo and exo variables in outer * ordering. The pointers point to storage in atoms. */ vector allvar; /** The mapping from outer endogenous to outer all. For * example endo2all[0] is the order of the first outer * endogenous variable in the allvar ordering. */ vector endo2all; /** The mapping from outer exogenous to outer all. For example * exo2all[0] is the order of the first outer exogenous * variables in the allvar ordering. */ vector exo2all; public: /** Construct the allvar outer ordering from the provided * sequence of endo and exo names. The names can have an * arbitrary storage, the storage is transformed to the atoms * storage. An exception is thrown if either the list is not * exhaustive, or some string is not a variable. */ AllvarOuterOrdering(const vector& allvar_outer, const FineAtoms& a); /** Copy constructor using the storage of provided atoms. */ AllvarOuterOrdering(const AllvarOuterOrdering& allvar_outer, const FineAtoms& a); /** Return endo2all mapping. */ const vector& get_endo2all() const {return endo2all;} /** Return exo2all mapping. */ const vector& get_exo2all() const {return exo2all;} /** Return the allvar ordering. */ const vector& get_allvar() const {return allvar;} }; /** This class refines the DynamicAtoms by distinguishing among * parameters (no lag and leads) and endogenous and exogenous * variables (with lags and leads). For parameters, endogenous and * exogenous, it defines outer orderings and internal * orderings. The internal orderings are created by * parsing_finished() method when it is sure that no new variables * would be registered. The outer orderings are given by the order * of calls of registering methods. * * In addition, the class also defines outer ordering of * endogenous and exogenous variables. This is input as a * parameter to parsing_finished(). By default, this whole outer * ordering is just a concatenation of outer ordering of * endogenous and exogenous variables. * * The internal ordering of all endo and exo variables is just a * concatenation of endo and exo variables in their internal * orderings. This is the ordering with respect to which all * derivatives are taken. */ class FineAtoms : public DynamicAtoms { friend class AllvarOuterOrdering; protected: typedef map Tvarintmap; private: /** The vector of parameters names. The order gives the order * the data is communicated with outside world. */ vector params; /** A map mapping a name of a parameter to an index in the outer * ordering. */ Tvarintmap param_outer_map; /** The vector of endogenous variables. This defines the order * like parameters. */ vector endovars; /** A map mapping a name of an endogenous variable to an index * in the outer ordering. */ Tvarintmap endo_outer_map; /** The vector of exogenous variables. Also defines the order * like parameters and endovars. */ vector exovars; /** A map mapping a name of an exogenous variable to an index * in the outer ordering. */ Tvarintmap exo_outer_map; protected: /** This is the internal ordering of all atoms corresponding * to endogenous variables. It is constructed by * parsing_finished() method, which should be called after all * parsing jobs have been finished. */ VarOrdering* endo_order; /** This is the internal ordering of all atoms corresponding * to exogenous variables. It has the same handling as * endo_order. */ VarOrdering* exo_order; /** This is the all variables outer ordering. It is * constructed by parsing finished. */ AllvarOuterOrdering* allvar_order; /** This vector defines a set of atoms as tree indices used * for differentiation. The order of the atoms in this vector * defines ordering of the derivative tensors. The ordering is * a concatenation of atoms from endo_order and then * exo_order. This vector is setup by parsing_finished() and * is returned by variables(). */ vector der_atoms; /** This is a mapping from endogenous atoms to all atoms in * der_atoms member. The mapping maps index in endogenous atom * ordering to index (not value) in der_atoms. It is useful if * one wants to evaluate derivatives wrt only endogenous * variables. It is set by parsing_finished(). By definition, * it is monotone. */ vector endo_atoms_map; /** This is a mapping from exogenous atoms to all atoms in * der_atoms member. It is the same as endo_atoms_map for * atoms of exogenous variables. */ vector exo_atoms_map; public: FineAtoms() : endo_order(NULL), exo_order(NULL), allvar_order(NULL) {} FineAtoms(const FineAtoms& fa); /** Deletes endo_order and exo_order. */ virtual ~FineAtoms() { if (endo_order) delete endo_order; if (exo_order) delete exo_order; if (allvar_order) delete allvar_order; } /** Overrides DynamicAtoms::check_variable so that the error * would be raised if the variable name is not declared. A * variable is declared by inserting it to * DynamicAtoms::varnames. This is a responsibility of a * subclass. */ int check_variable(const char* name) const; /** This calculates min lag and max lead of endogenous variables. */ void endovarspan(int& mlead, int& mlag) const {varspan(endovars, mlead, mlag);} /** This calculates mim lag and max lead of exogenous variables. */ void exovarspan(int& mlead, int& mlag) const {varspan(exovars, mlead, mlag);} /** This calculates the number of periods in which at least * one exogenous variable occurs. */ int num_exo_periods() const; /** Return an (external) ordering of parameters. */ const vector& get_params() const {return params;} /** Return an external ordering of endogenous variables. */ const vector& get_endovars() const {return endovars;} /** Return an external ordering of exogenous variables. */ const vector& get_exovars() const {return exovars;} /** This constructs internal orderings and makes the indices * returned by variables method available. Further it * constructs outer ordering of all variables by a simple * concatenation of outer endogenous and outer exogenous. In * addition, it makes nstat, npred, nboth, nforw available. */ void parsing_finished(VarOrdering::ord_type ot); /** This does the same thing as * parsing_finished(VarOrdering::ord_type) plus it allows for * inputing a different outer ordering of all variables. The * ordering is input as a list of strings, their storage can * be arbitrary. */ void parsing_finished(VarOrdering::ord_type ot, const vector avo); /** Return the external ordering of all variables (endo and * exo). This is either the second argument to * parsing_finished or the default external ordering. This * must be called only after parsing_finished. */ const vector& get_allvar() const; /** Return the map from outer ordering of endo variables to * the allvar ordering. This must be called only after * parsing_finished. */ const vector& outer_endo2all() const; /** Return the map from outer ordering of exo variables to * the allvar ordering. This must be called only after * parsing_finished. */ const vector& outer_exo2all() const; /** Return the atoms with respect to which we are going to * differentiate. This must be called after * parsing_finished. */ vector variables() const; /** Return the number of static. */ int nstat() const; /** Return the number of predetermined. */ int npred() const; /** Return the number of both. */ int nboth() const; /** Return the number of forward looking. */ int nforw() const; /** Return the index of an endogenous atom given by tree index in * the endo ordering. This must be also called only after * parsing_finished(). */ int get_pos_of_endo(int t) const; /** Return the index of an exogenous atom given by tree index in * the exo ordering. This must be also called only after * parsing_finished(). */ int get_pos_of_exo(int t) const; /** Return the index of either endogenous or exogenous atom * given by tree index in the concatenated ordering of * endogenous and exogenous atoms. This must be also called * only after parsing_finished(). */ int get_pos_of_all(int t) const; /** Return the mapping from endogenous at time t to outer * ordering of endogenous. */ const vector& y2outer_endo() const; /** Return the mapping from the outer ordering of endogenous to endogenous * at time t. */ const vector& outer2y_endo() const; /** Return the mapping from exogenous at time t to outer * ordering of exogenous. */ const vector& y2outer_exo() const; /** Return the mapping from the outer ordering of exogenous to exogenous * at time t. */ const vector& outer2y_exo() const; /** Return the endo_atoms_map. */ const vector& get_endo_atoms_map() const; /** Return the exo_atoms_map. */ const vector& get_exo_atoms_map() const; /** Return an index in the outer ordering of a given * parameter. An exception is thrown if the name is not a * parameter. */ int name2outer_param(const char* name) const; /** Return an index in the outer ordering of a given * endogenous variable. An exception is thrown if the name is not a * and endogenous variable. */ int name2outer_endo(const char* name) const; /** Return an index in the outer ordering of a given * exogenous variable. An exception is thrown if the name is not a * and exogenous variable. */ int name2outer_exo(const char* name) const; /** Return an index in the outer ordering of all variables * (endo and exo) for a given name. An exception is thrown if * the name is not a variable. This must be called only after * parsing_finished(). */ int name2outer_allvar(const char* name) const; /** Return the number of endogenous variables at time t-1, these are state * variables. */ int nys() const {return npred()+nboth();} /** Return the number of endogenous variables at time t+1. */ int nyss() const {return nboth()+nforw();} /** Return the number of endogenous variables. */ int ny() const {return endovars.size();} /** Return the number of exogenous variables. */ int nexo() const {return (int)exovars.size();} /** Return the number of parameters. */ int np() const {return (int)(params.size());} /** Register unique endogenous variable name. The order of * calls defines the endo outer ordering. The method is * virtual, since a superclass may want to do some additional * action. */ virtual void register_uniq_endo(const char* name); /** Register unique exogenous variable name. The order of * calls defines the exo outer ordering. The method is * virtual, since a superclass may want to do somem additional * action. */ virtual void register_uniq_exo(const char* name); /** Register unique parameter name. The order of calls defines * the param outer ordering. The method is * virtual, since a superclass may want to do somem additional * action. */ virtual void register_uniq_param(const char* name); /** Debug print. */ void print() const; private: /** This performs the common part of parsing_finished(), which * is a construction of internal orderings. */ void make_internal_orderings(VarOrdering::ord_type ot); protected: /** This remembers the ordering type of the last call make_internal_ordering. */ VarOrdering::ord_type order_type; }; }; #endif // Local Variables: // mode:C++ // End: