Merge branch 'prepare-4.5'
commit
24a2fc340a
|
@ -12,114 +12,126 @@
|
|||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace ogp {
|
||||
namespace ogp
|
||||
{
|
||||
|
||||
class AtomAsgnEvaluator;
|
||||
class AtomAsgnEvaluator;
|
||||
|
||||
/** This class represents atom assignments used in parameters
|
||||
* settings and initval initialization. It maintains atoms of the
|
||||
* all expressions on the right hand side, the parsed formulas of
|
||||
* the right hand sides, and the information about the left hand
|
||||
* sides. See documentation to the order member below. */
|
||||
class AtomAssignings {
|
||||
friend class AtomAsgnEvaluator;
|
||||
protected:
|
||||
typedef std::map<const char*, int, ltstr> Tvarintmap;
|
||||
/** All atoms which should be sufficient for formulas at the
|
||||
* right hand sides. The atoms should be filled with names
|
||||
* (preregistered). This is a responsibility of the caller. */
|
||||
StaticAtoms& atoms;
|
||||
/** The formulas of right hand sides. */
|
||||
FormulaParser expr;
|
||||
/** Name storage of the names from left hand sides. */
|
||||
NameStorage left_names;
|
||||
/** Information on left hand sides. This maps a name to the
|
||||
* index of its assigned expression in expr. More than one
|
||||
* name may reference to the same expression. */
|
||||
Tvarintmap lname2expr;
|
||||
/** Information on left hand sides. If order[i] >= 0, then it
|
||||
* says that i-th expression in expr is assigned to atom with
|
||||
* order[i] tree index. */
|
||||
std::vector<int> order;
|
||||
public:
|
||||
/** Construct the object using the provided static atoms. */
|
||||
AtomAssignings(StaticAtoms& a) : atoms(a), expr(atoms)
|
||||
{}
|
||||
/** Make a copy with provided reference to (posibly different)
|
||||
* static atoms. */
|
||||
AtomAssignings(const AtomAssignings& aa, StaticAtoms& a);
|
||||
virtual ~AtomAssignings()
|
||||
{}
|
||||
/** Parse the assignments from the given string. */
|
||||
void parse(int length, const char* stream);
|
||||
/** Process a syntax error from bison. */
|
||||
void error(const char* mes);
|
||||
/** Add an assignment of the given name to the given
|
||||
* double. Can be called by a user, anytime. */
|
||||
void add_assignment_to_double(const char* name, double val);
|
||||
/** Add an assignment. Called from assign.y. */
|
||||
void add_assignment(int asgn_off, const char* str, int name_len,
|
||||
int right_off, int right_len);
|
||||
/** This applies old2new map (possibly from atom
|
||||
* substitutions) to this object. It registers new variables
|
||||
* in the atoms, and adds the expressions to expr, and left
|
||||
* names to lname2expr. The information about dynamical part
|
||||
* of substitutions is ignored, since we are now in the static
|
||||
* world. */
|
||||
void apply_subst(const AtomSubstitutions::Toldnamemap& mm);
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
};
|
||||
/** This class represents atom assignments used in parameters
|
||||
* settings and initval initialization. It maintains atoms of the
|
||||
* all expressions on the right hand side, the parsed formulas of
|
||||
* the right hand sides, and the information about the left hand
|
||||
* sides. See documentation to the order member below. */
|
||||
class AtomAssignings
|
||||
{
|
||||
friend class AtomAsgnEvaluator;
|
||||
protected:
|
||||
typedef std::map<const char *, int, ltstr> Tvarintmap;
|
||||
/** All atoms which should be sufficient for formulas at the
|
||||
* right hand sides. The atoms should be filled with names
|
||||
* (preregistered). This is a responsibility of the caller. */
|
||||
StaticAtoms &atoms;
|
||||
/** The formulas of right hand sides. */
|
||||
FormulaParser expr;
|
||||
/** Name storage of the names from left hand sides. */
|
||||
NameStorage left_names;
|
||||
/** Information on left hand sides. This maps a name to the
|
||||
* index of its assigned expression in expr. More than one
|
||||
* name may reference to the same expression. */
|
||||
Tvarintmap lname2expr;
|
||||
/** Information on left hand sides. If order[i] >= 0, then it
|
||||
* says that i-th expression in expr is assigned to atom with
|
||||
* order[i] tree index. */
|
||||
std::vector<int> order;
|
||||
public:
|
||||
/** Construct the object using the provided static atoms. */
|
||||
AtomAssignings(StaticAtoms &a) : atoms(a), expr(atoms)
|
||||
{
|
||||
}
|
||||
/** Make a copy with provided reference to (posibly different)
|
||||
* static atoms. */
|
||||
AtomAssignings(const AtomAssignings &aa, StaticAtoms &a);
|
||||
virtual ~AtomAssignings()
|
||||
{
|
||||
}
|
||||
/** Parse the assignments from the given string. */
|
||||
void parse(int length, const char *stream);
|
||||
/** Process a syntax error from bison. */
|
||||
void error(const char *mes);
|
||||
/** Add an assignment of the given name to the given
|
||||
* double. Can be called by a user, anytime. */
|
||||
void add_assignment_to_double(const char *name, double val);
|
||||
/** Add an assignment. Called from assign.y. */
|
||||
void add_assignment(int asgn_off, const char *str, int name_len,
|
||||
int right_off, int right_len);
|
||||
/** This applies old2new map (possibly from atom
|
||||
* substitutions) to this object. It registers new variables
|
||||
* in the atoms, and adds the expressions to expr, and left
|
||||
* names to lname2expr. The information about dynamical part
|
||||
* of substitutions is ignored, since we are now in the static
|
||||
* world. */
|
||||
void apply_subst(const AtomSubstitutions::Toldnamemap &mm);
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
};
|
||||
|
||||
/** This class basically evaluates the atom assignments
|
||||
* AtomAssignings, so it inherits from ogp::FormulaEvaluator. It
|
||||
* is also a storage for the results of the evaluation stored as a
|
||||
* vector, so the class inherits from std::vector<double> and
|
||||
* ogp::FormulaEvalLoader. As the expressions for atoms are
|
||||
* evaluated, the results are values for atoms which will be
|
||||
* used in subsequent evaluations. For this reason, the class
|
||||
* inherits also from AtomValues. */
|
||||
class AtomAsgnEvaluator : public FormulaEvalLoader,
|
||||
public AtomValues,
|
||||
protected FormulaEvaluator,
|
||||
public std::vector<double> {
|
||||
protected:
|
||||
typedef std::map<int, double> Tusrvalmap;
|
||||
Tusrvalmap user_values;
|
||||
const AtomAssignings& aa;
|
||||
public:
|
||||
AtomAsgnEvaluator(const AtomAssignings& a)
|
||||
: FormulaEvaluator(a.expr),
|
||||
std::vector<double>(a.expr.nformulas()), aa(a) {}
|
||||
virtual ~AtomAsgnEvaluator() {}
|
||||
/** This sets all initial values to NaNs, all constants and
|
||||
* all values set by user by call set_value. This is called by
|
||||
* FormulaEvaluator::eval() method, which is called by eval()
|
||||
* method passing this argument as AtomValues. So the
|
||||
* ogp::EvalTree will be always this->etree. */
|
||||
void setValues(EvalTree& et) const;
|
||||
/** User setting of the values. For example in initval,
|
||||
* parameters are known and should be set to their values. In
|
||||
* constrast endogenous variables are set initially to NaNs by
|
||||
* AtomValues::setValues. */
|
||||
void set_user_value(const char* name, double val);
|
||||
/** This sets the result of i-th expression in aa to res, and
|
||||
* also checks whether the i-th expression is an atom. If so,
|
||||
* it sets the value of the atom in ogp::EvalTree
|
||||
* this->etree. */
|
||||
void load(int i, double res);
|
||||
/** After the user values have been set, the assignments can
|
||||
* be evaluated. For this purpose we have eval() method. The
|
||||
* result is that this object as std::vector<double> will
|
||||
* contain the values. It is ordered given by formulas in
|
||||
* expr. */
|
||||
void eval()
|
||||
{FormulaEvaluator::eval(*this, *this);}
|
||||
/** This returns a value for a given name. If the name is not
|
||||
* found among atoms, or there is no assignment for the atom,
|
||||
* NaN is returned. */
|
||||
double get_value(const char* name) const;
|
||||
};
|
||||
/** This class basically evaluates the atom assignments
|
||||
* AtomAssignings, so it inherits from ogp::FormulaEvaluator. It
|
||||
* is also a storage for the results of the evaluation stored as a
|
||||
* vector, so the class inherits from std::vector<double> and
|
||||
* ogp::FormulaEvalLoader. As the expressions for atoms are
|
||||
* evaluated, the results are values for atoms which will be
|
||||
* used in subsequent evaluations. For this reason, the class
|
||||
* inherits also from AtomValues. */
|
||||
class AtomAsgnEvaluator : public FormulaEvalLoader,
|
||||
public AtomValues,
|
||||
protected FormulaEvaluator,
|
||||
public std::vector<double>
|
||||
{
|
||||
protected:
|
||||
typedef std::map<int, double> Tusrvalmap;
|
||||
Tusrvalmap user_values;
|
||||
const AtomAssignings &aa;
|
||||
public:
|
||||
AtomAsgnEvaluator(const AtomAssignings &a)
|
||||
: FormulaEvaluator(a.expr),
|
||||
std::vector<double>(a.expr.nformulas()), aa(a)
|
||||
{
|
||||
}
|
||||
virtual ~AtomAsgnEvaluator()
|
||||
{
|
||||
}
|
||||
/** This sets all initial values to NaNs, all constants and
|
||||
* all values set by user by call set_value. This is called by
|
||||
* FormulaEvaluator::eval() method, which is called by eval()
|
||||
* method passing this argument as AtomValues. So the
|
||||
* ogp::EvalTree will be always this->etree. */
|
||||
void setValues(EvalTree &et) const;
|
||||
/** User setting of the values. For example in initval,
|
||||
* parameters are known and should be set to their values. In
|
||||
* constrast endogenous variables are set initially to NaNs by
|
||||
* AtomValues::setValues. */
|
||||
void set_user_value(const char *name, double val);
|
||||
/** This sets the result of i-th expression in aa to res, and
|
||||
* also checks whether the i-th expression is an atom. If so,
|
||||
* it sets the value of the atom in ogp::EvalTree
|
||||
* this->etree. */
|
||||
void load(int i, double res);
|
||||
/** After the user values have been set, the assignments can
|
||||
* be evaluated. For this purpose we have eval() method. The
|
||||
* result is that this object as std::vector<double> will
|
||||
* contain the values. It is ordered given by formulas in
|
||||
* expr. */
|
||||
void
|
||||
eval()
|
||||
{
|
||||
FormulaEvaluator::eval(*this, *this);
|
||||
}
|
||||
/** This returns a value for a given name. If the name is not
|
||||
* found among atoms, or there is no assignment for the atom,
|
||||
* NaN is returned. */
|
||||
double get_value(const char *name) const;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -9,148 +9,185 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
namespace ogp {
|
||||
namespace ogp
|
||||
{
|
||||
|
||||
using std::string;
|
||||
using std::map;
|
||||
using std::pair;
|
||||
using std::string;
|
||||
using std::map;
|
||||
using std::pair;
|
||||
|
||||
/** This class tracts an information about the performed
|
||||
* substitutions. In fact, there is only one number to keep track
|
||||
* about, this is a number of substitutions. */
|
||||
struct SubstInfo {
|
||||
int num_substs;
|
||||
SubstInfo() : num_substs(0) {}
|
||||
};
|
||||
/** This class tracts an information about the performed
|
||||
* substitutions. In fact, there is only one number to keep track
|
||||
* about, this is a number of substitutions. */
|
||||
struct SubstInfo
|
||||
{
|
||||
int num_substs;
|
||||
SubstInfo() : num_substs(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/** This class tracks all atom substitutions during the job and
|
||||
* then builds structures when all substitutions are finished. */
|
||||
class AtomSubstitutions {
|
||||
public:
|
||||
typedef pair<const char*, int> Tshiftname;
|
||||
typedef map<const char*, Tshiftname, ltstr> Tshiftmap;
|
||||
typedef set<Tshiftname> Tshiftnameset;
|
||||
typedef map<const char*, Tshiftnameset, ltstr> Toldnamemap;
|
||||
protected:
|
||||
/** This maps a new name to a shifted old name. This is, one
|
||||
* entry looks as "a_m3 ==> a(-3)", saying that a variable
|
||||
* "a_m3" corresponds to a variable "a" lagged by 3. */
|
||||
Tshiftmap new2old;
|
||||
/** This is inverse to new2old, which is not unique. For old
|
||||
* name, say "a", it says what new names are derived with what
|
||||
* shifts from the "a". For example, it can map "a" to a two
|
||||
* element set {["a_m3", +3], ["a_p2", -2]}. This says that
|
||||
* leading "a_m3" by 3 one gets old "a" and lagging "a_p2" by
|
||||
* 2 one gets also old "a". */
|
||||
Toldnamemap old2new;
|
||||
/** This is a reference to old atoms with multiple leads and
|
||||
* lags. They are supposed to be used with parsing finished
|
||||
* being had called, so that the external ordering is
|
||||
* available. */
|
||||
const FineAtoms& old_atoms;
|
||||
/** This is a reference to new atoms. All name pointers point
|
||||
* to storage of these atoms. */
|
||||
FineAtoms& new_atoms;
|
||||
/** Substitutions information. */
|
||||
SubstInfo info;
|
||||
public:
|
||||
/** Create the object with reference to the old and new
|
||||
* atoms. In the beginning, old atoms are supposed to be with
|
||||
* parsing_finished() called, and new atoms a simple copy of
|
||||
* old atoms. The new atoms will be an instance of SAtoms. All
|
||||
* substitution job is done by a substitution method of the
|
||||
* new atoms. */
|
||||
AtomSubstitutions(const FineAtoms& oa, FineAtoms& na)
|
||||
: old_atoms(oa), new_atoms(na) {}
|
||||
/** Construct a copy of the object using a different instances
|
||||
* of old atoms and new atoms, which are supposed to be
|
||||
* semantically same as the atoms from as. */
|
||||
AtomSubstitutions(const AtomSubstitutions& as, const FineAtoms& oa, FineAtoms& na);
|
||||
virtual ~AtomSubstitutions() {}
|
||||
/** This is called during the substitution job from the
|
||||
* substitution method of the new atoms. This says that the
|
||||
* new name, say "a_m3" is a substitution of old name "a"
|
||||
* shifted by -3. */
|
||||
void add_substitution(const char* newname, const char* oldname, int tshift);
|
||||
/** This is called when all substitutions are finished. This
|
||||
* forms the new external ordering of the new atoms and calls
|
||||
* parsing_finished() for the new atoms with the given ordering type. */
|
||||
void substitutions_finished(VarOrdering::ord_type ot);
|
||||
/** Returns a new name for old name and given tshift. For "a"
|
||||
* and tshift=-3, it returns "a_m3". If there is no such
|
||||
* substitution, it returns NULL. */
|
||||
const char* get_new4old(const char* oldname, int tshift) const;
|
||||
/** Return new2old. */
|
||||
const Tshiftmap& get_new2old() const
|
||||
{return new2old;}
|
||||
/** Return old2new. */
|
||||
const Toldnamemap& get_old2new() const
|
||||
{return old2new;}
|
||||
/** Return substitution info. */
|
||||
const SubstInfo& get_info() const
|
||||
{return info;}
|
||||
/** Return old atoms. */
|
||||
const FineAtoms& get_old_atoms() const
|
||||
{return old_atoms;}
|
||||
/** Return new atoms. */
|
||||
const FineAtoms& get_new_atoms() const
|
||||
{return new_atoms;}
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
};
|
||||
/** This class tracks all atom substitutions during the job and
|
||||
* then builds structures when all substitutions are finished. */
|
||||
class AtomSubstitutions
|
||||
{
|
||||
public:
|
||||
typedef pair<const char *, int> Tshiftname;
|
||||
typedef map<const char *, Tshiftname, ltstr> Tshiftmap;
|
||||
typedef set<Tshiftname> Tshiftnameset;
|
||||
typedef map<const char *, Tshiftnameset, ltstr> Toldnamemap;
|
||||
protected:
|
||||
/** This maps a new name to a shifted old name. This is, one
|
||||
* entry looks as "a_m3 ==> a(-3)", saying that a variable
|
||||
* "a_m3" corresponds to a variable "a" lagged by 3. */
|
||||
Tshiftmap new2old;
|
||||
/** This is inverse to new2old, which is not unique. For old
|
||||
* name, say "a", it says what new names are derived with what
|
||||
* shifts from the "a". For example, it can map "a" to a two
|
||||
* element set {["a_m3", +3], ["a_p2", -2]}. This says that
|
||||
* leading "a_m3" by 3 one gets old "a" and lagging "a_p2" by
|
||||
* 2 one gets also old "a". */
|
||||
Toldnamemap old2new;
|
||||
/** This is a reference to old atoms with multiple leads and
|
||||
* lags. They are supposed to be used with parsing finished
|
||||
* being had called, so that the external ordering is
|
||||
* available. */
|
||||
const FineAtoms &old_atoms;
|
||||
/** This is a reference to new atoms. All name pointers point
|
||||
* to storage of these atoms. */
|
||||
FineAtoms &new_atoms;
|
||||
/** Substitutions information. */
|
||||
SubstInfo info;
|
||||
public:
|
||||
/** Create the object with reference to the old and new
|
||||
* atoms. In the beginning, old atoms are supposed to be with
|
||||
* parsing_finished() called, and new atoms a simple copy of
|
||||
* old atoms. The new atoms will be an instance of SAtoms. All
|
||||
* substitution job is done by a substitution method of the
|
||||
* new atoms. */
|
||||
AtomSubstitutions(const FineAtoms &oa, FineAtoms &na)
|
||||
: old_atoms(oa), new_atoms(na)
|
||||
{
|
||||
}
|
||||
/** Construct a copy of the object using a different instances
|
||||
* of old atoms and new atoms, which are supposed to be
|
||||
* semantically same as the atoms from as. */
|
||||
AtomSubstitutions(const AtomSubstitutions &as, const FineAtoms &oa, FineAtoms &na);
|
||||
virtual ~AtomSubstitutions()
|
||||
{
|
||||
}
|
||||
/** This is called during the substitution job from the
|
||||
* substitution method of the new atoms. This says that the
|
||||
* new name, say "a_m3" is a substitution of old name "a"
|
||||
* shifted by -3. */
|
||||
void add_substitution(const char *newname, const char *oldname, int tshift);
|
||||
/** This is called when all substitutions are finished. This
|
||||
* forms the new external ordering of the new atoms and calls
|
||||
* parsing_finished() for the new atoms with the given ordering type. */
|
||||
void substitutions_finished(VarOrdering::ord_type ot);
|
||||
/** Returns a new name for old name and given tshift. For "a"
|
||||
* and tshift=-3, it returns "a_m3". If there is no such
|
||||
* substitution, it returns NULL. */
|
||||
const char *get_new4old(const char *oldname, int tshift) const;
|
||||
/** Return new2old. */
|
||||
const Tshiftmap &
|
||||
get_new2old() const
|
||||
{
|
||||
return new2old;
|
||||
}
|
||||
/** Return old2new. */
|
||||
const Toldnamemap &
|
||||
get_old2new() const
|
||||
{
|
||||
return old2new;
|
||||
}
|
||||
/** Return substitution info. */
|
||||
const SubstInfo &
|
||||
get_info() const
|
||||
{
|
||||
return info;
|
||||
}
|
||||
/** Return old atoms. */
|
||||
const FineAtoms &
|
||||
get_old_atoms() const
|
||||
{
|
||||
return old_atoms;
|
||||
}
|
||||
/** Return new atoms. */
|
||||
const FineAtoms &
|
||||
get_new_atoms() const
|
||||
{
|
||||
return new_atoms;
|
||||
}
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
};
|
||||
|
||||
class SAtoms : public FineAtoms {
|
||||
public:
|
||||
SAtoms()
|
||||
: FineAtoms() {}
|
||||
SAtoms(const SAtoms& sa)
|
||||
: FineAtoms(sa) {}
|
||||
virtual ~SAtoms() {}
|
||||
/** This substitutes all lags and leads for all exogenous and
|
||||
* all lags and leads greater than 1 for all endogenous
|
||||
* variables. This is useful for perfect foresight problems
|
||||
* where we can do that. */
|
||||
void substituteAllLagsAndLeads(FormulaParser& fp, AtomSubstitutions& as);
|
||||
/** This substitutes all lags of all endo and exo and one step
|
||||
* leads of all exo variables. This is useful for stochastic
|
||||
* models where we cannot solve leads more than 1. */
|
||||
void substituteAllLagsAndExo1Leads(FormulaParser& fp, AtomSubstitutions& as);
|
||||
protected:
|
||||
/** This finds an endogenous variable name which occurs between
|
||||
* ll1 and ll2 included. */
|
||||
const char* findEndoWithLeadInInterval(int ll1, int ll2) const
|
||||
{return findNameWithLeadInInterval(get_endovars(), ll1, ll2);}
|
||||
/** This finds an exogenous variable name which occurs between
|
||||
* ll1 and ll2 included. */
|
||||
const char* findExoWithLeadInInterval(int ll1, int ll2) const
|
||||
{return findNameWithLeadInInterval(get_exovars(), ll1, ll2);}
|
||||
class SAtoms : public FineAtoms
|
||||
{
|
||||
public:
|
||||
SAtoms()
|
||||
: FineAtoms()
|
||||
{
|
||||
}
|
||||
SAtoms(const SAtoms &sa)
|
||||
: FineAtoms(sa)
|
||||
{
|
||||
}
|
||||
virtual ~SAtoms()
|
||||
{
|
||||
}
|
||||
/** This substitutes all lags and leads for all exogenous and
|
||||
* all lags and leads greater than 1 for all endogenous
|
||||
* variables. This is useful for perfect foresight problems
|
||||
* where we can do that. */
|
||||
void substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as);
|
||||
/** This substitutes all lags of all endo and exo and one step
|
||||
* leads of all exo variables. This is useful for stochastic
|
||||
* models where we cannot solve leads more than 1. */
|
||||
void substituteAllLagsAndExo1Leads(FormulaParser &fp, AtomSubstitutions &as);
|
||||
protected:
|
||||
/** This finds an endogenous variable name which occurs between
|
||||
* ll1 and ll2 included. */
|
||||
const char *
|
||||
findEndoWithLeadInInterval(int ll1, int ll2) const
|
||||
{
|
||||
return findNameWithLeadInInterval(get_endovars(), ll1, ll2);
|
||||
}
|
||||
/** This finds an exogenous variable name which occurs between
|
||||
* ll1 and ll2 included. */
|
||||
const char *
|
||||
findExoWithLeadInInterval(int ll1, int ll2) const
|
||||
{
|
||||
return findNameWithLeadInInterval(get_exovars(), ll1, ll2);
|
||||
}
|
||||
|
||||
/** This attempts to find a non registered name of the form
|
||||
* <str>_m<abs(ll)> or <str>_p<abs(ll)>. A letter 'p' is
|
||||
* chosen if ll is positive, 'm' if negative. If a name of
|
||||
* such form is already registered, one more character (either
|
||||
* 'p' or 'm') is added and the test is performed again. The
|
||||
* resulting name is returned in a string out. */
|
||||
void attemptAuxName(const char* str, int ll, string& out) const;
|
||||
/** This attempts to find a non registered name of the form
|
||||
* <str>_m<abs(ll)> or <str>_p<abs(ll)>. A letter 'p' is
|
||||
* chosen if ll is positive, 'm' if negative. If a name of
|
||||
* such form is already registered, one more character (either
|
||||
* 'p' or 'm') is added and the test is performed again. The
|
||||
* resulting name is returned in a string out. */
|
||||
void attemptAuxName(const char *str, int ll, string &out) const;
|
||||
|
||||
/** This makes auxiliary variables to eliminate all leads/lags
|
||||
* greater/less than or equal to start up to the limit_lead
|
||||
* for a variable with the given name. If the limit_lead is
|
||||
* greater/less than the maxlead/minlag of the variable, than
|
||||
* maxlead/minlag is used. This process is recorded in
|
||||
* AtomSubstitutions. The new auxiliary variables and their
|
||||
* atoms are created in this object. The auxiliary equations
|
||||
* are created in the given FormulaParser. The value of step
|
||||
* is allowed to be either -1 (lags) or +1 (leads). */
|
||||
void makeAuxVariables(const char* name, int step, int start, int limit_lead,
|
||||
FormulaParser& fp, AtomSubstitutions& as);
|
||||
private:
|
||||
/** This is a worker routine for findEndoWithLeadInInterval
|
||||
* and findExoWithLeadInInterval. */
|
||||
const char* findNameWithLeadInInterval(const vector<const char*>& names,
|
||||
int ll1, int ll2) const;
|
||||
/** This makes auxiliary variables to eliminate all leads/lags
|
||||
* greater/less than or equal to start up to the limit_lead
|
||||
* for a variable with the given name. If the limit_lead is
|
||||
* greater/less than the maxlead/minlag of the variable, than
|
||||
* maxlead/minlag is used. This process is recorded in
|
||||
* AtomSubstitutions. The new auxiliary variables and their
|
||||
* atoms are created in this object. The auxiliary equations
|
||||
* are created in the given FormulaParser. The value of step
|
||||
* is allowed to be either -1 (lags) or +1 (leads). */
|
||||
void makeAuxVariables(const char *name, int step, int start, int limit_lead,
|
||||
FormulaParser &fp, AtomSubstitutions &as);
|
||||
private:
|
||||
/** This is a worker routine for findEndoWithLeadInInterval
|
||||
* and findExoWithLeadInInterval. */
|
||||
const char *findNameWithLeadInInterval(const vector<const char *> &names,
|
||||
int ll1, int ll2) const;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -5,38 +5,58 @@
|
|||
#ifndef OGP_CSV_PARSER
|
||||
#define OGP_CSV_PARSER
|
||||
|
||||
namespace ogp {
|
||||
namespace ogp
|
||||
{
|
||||
|
||||
class CSVParserPeer {
|
||||
public:
|
||||
virtual ~CSVParserPeer() {}
|
||||
virtual void item(int irow, int icol, const char* str, int length) = 0;
|
||||
};
|
||||
class CSVParserPeer
|
||||
{
|
||||
public:
|
||||
virtual ~CSVParserPeer()
|
||||
{
|
||||
}
|
||||
virtual void item(int irow, int icol, const char *str, int length) = 0;
|
||||
};
|
||||
|
||||
class CSVParser {
|
||||
private:
|
||||
CSVParserPeer& peer;
|
||||
int row;
|
||||
int col;
|
||||
const char* parsed_string;
|
||||
public:
|
||||
CSVParser(CSVParserPeer& p)
|
||||
: peer(p), row(0), col(0), parsed_string(0) {}
|
||||
CSVParser(const CSVParser& csvp)
|
||||
: peer(csvp.peer), row(csvp.row),
|
||||
col(csvp.col), parsed_string(csvp.parsed_string) {}
|
||||
virtual ~CSVParser() {}
|
||||
class CSVParser
|
||||
{
|
||||
private:
|
||||
CSVParserPeer &peer;
|
||||
int row;
|
||||
int col;
|
||||
const char *parsed_string;
|
||||
public:
|
||||
CSVParser(CSVParserPeer &p)
|
||||
: peer(p), row(0), col(0), parsed_string(0)
|
||||
{
|
||||
}
|
||||
CSVParser(const CSVParser &csvp)
|
||||
: peer(csvp.peer), row(csvp.row),
|
||||
col(csvp.col), parsed_string(csvp.parsed_string)
|
||||
{
|
||||
}
|
||||
virtual ~CSVParser()
|
||||
{
|
||||
}
|
||||
|
||||
void csv_error(const char* mes);
|
||||
void csv_parse(int length, const char* str);
|
||||
void csv_error(const char *mes);
|
||||
void csv_parse(int length, const char *str);
|
||||
|
||||
void nextrow()
|
||||
{row++; col = 0;}
|
||||
void nextcol()
|
||||
{col++;}
|
||||
void item(int off, int length)
|
||||
{peer.item(row, col, parsed_string+off, length);}
|
||||
};
|
||||
void
|
||||
nextrow()
|
||||
{
|
||||
row++; col = 0;
|
||||
}
|
||||
void
|
||||
nextcol()
|
||||
{
|
||||
col++;
|
||||
}
|
||||
void
|
||||
item(int off, int length)
|
||||
{
|
||||
peer.item(row, col, parsed_string+off, length);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,389 +13,462 @@
|
|||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
namespace ogp {
|
||||
using std::vector;
|
||||
using std::map;
|
||||
using std::set;
|
||||
using std::string;
|
||||
namespace ogp
|
||||
{
|
||||
using std::vector;
|
||||
using std::map;
|
||||
using std::set;
|
||||
using std::string;
|
||||
|
||||
struct ltstr {
|
||||
bool operator()(const char* a1, const char* a2) const
|
||||
{ return strcmp(a1, a2) < 0; }
|
||||
};
|
||||
struct ltstr
|
||||
{
|
||||
bool
|
||||
operator()(const char *a1, const char *a2) const
|
||||
{
|
||||
return strcmp(a1, a2) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
/** Class storing names. We will keep names of variables in
|
||||
* various places, and all these pointers will point to one
|
||||
* storage, which will be responsible for allocation and
|
||||
* deallocation. The main function of the class is to allocate
|
||||
* space for names, and return a pointer of the stored name if
|
||||
* required. */
|
||||
class NameStorage {
|
||||
protected:
|
||||
/** Vector of names allocated, this is the storage. */
|
||||
vector<char*> name_store;
|
||||
/** Map useful to quickly decide if the name is already
|
||||
* allocated or not. */
|
||||
set<const char*, ltstr> name_set;
|
||||
public:
|
||||
NameStorage() {}
|
||||
NameStorage(const NameStorage& stor);
|
||||
virtual ~NameStorage();
|
||||
/** Query for the name. If the name has been stored, it
|
||||
* returns its address, otherwise 0. */
|
||||
const char* query(const char* name) const;
|
||||
/** Insert the name if it has not been inserted yet, and
|
||||
* return its new or old allocation. */
|
||||
const char* insert(const char* name);
|
||||
int num() const
|
||||
{return (int)name_store.size();}
|
||||
const char* get_name(int i) const
|
||||
{return name_store[i];}
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
};
|
||||
/** Class storing names. We will keep names of variables in
|
||||
* various places, and all these pointers will point to one
|
||||
* storage, which will be responsible for allocation and
|
||||
* deallocation. The main function of the class is to allocate
|
||||
* space for names, and return a pointer of the stored name if
|
||||
* required. */
|
||||
class NameStorage
|
||||
{
|
||||
protected:
|
||||
/** Vector of names allocated, this is the storage. */
|
||||
vector<char *> name_store;
|
||||
/** Map useful to quickly decide if the name is already
|
||||
* allocated or not. */
|
||||
set<const char *, ltstr> name_set;
|
||||
public:
|
||||
NameStorage()
|
||||
{
|
||||
}
|
||||
NameStorage(const NameStorage &stor);
|
||||
virtual
|
||||
~NameStorage();
|
||||
/** Query for the name. If the name has been stored, it
|
||||
* returns its address, otherwise 0. */
|
||||
const char *query(const char *name) const;
|
||||
/** Insert the name if it has not been inserted yet, and
|
||||
* return its new or old allocation. */
|
||||
const char *insert(const char *name);
|
||||
int
|
||||
num() const
|
||||
{
|
||||
return (int) name_store.size();
|
||||
}
|
||||
const char *
|
||||
get_name(int i) const
|
||||
{
|
||||
return name_store[i];
|
||||
}
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
};
|
||||
|
||||
class Constants : public AtomValues {
|
||||
public:
|
||||
/** Type for a map mapping tree indices to double values. */
|
||||
typedef map<int,double> Tconstantmap;
|
||||
typedef map<int,int> Tintintmap;
|
||||
protected:
|
||||
/** Map mapping a tree index of a constant to its double value. */
|
||||
Tconstantmap cmap;
|
||||
public:
|
||||
Constants() {}
|
||||
/** Copy constructor. */
|
||||
Constants(const Constants& c)
|
||||
: cmap(c.cmap), cinvmap(c.cinvmap) {}
|
||||
/** Copy constructor registering the constants in the given
|
||||
* tree. The mapping from old tree indices to new ones is
|
||||
* traced in tmap. */
|
||||
Constants(const Constants& c, OperationTree& otree, Tintintmap& tmap)
|
||||
{import_constants(c, otree, tmap);}
|
||||
/** Import constants registering their tree indices in the
|
||||
* given tree. The mapping form old tree indices to new ones
|
||||
* is traced in tmap. */
|
||||
void import_constants(const Constants& c, OperationTree& otree, Tintintmap& tmap);
|
||||
/** Implements AtomValues interface. This sets the values to
|
||||
* the evaluation tree EvalTree. */
|
||||
void setValues(EvalTree& et) const;
|
||||
/** This adds a constant with the given tree index. The
|
||||
* constant must be checked previously and asserted that it
|
||||
* does not exist. */
|
||||
void add_constant(int t, double val);
|
||||
/** Returns true if the tree index is either an hardwired
|
||||
* constant (initial number OperationTree:num_constants in
|
||||
* OperationTree) or the tree index is a registered constant
|
||||
* by add_constant method. */
|
||||
bool is_constant(int t) const;
|
||||
double get_constant_value(int t) const;
|
||||
/** Return -1 if the given string representation of a constant
|
||||
* is not among the constants (double represenations). If it
|
||||
* is, its tree index is returned. */
|
||||
int check(const char* str) const;
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
const Tconstantmap& get_constantmap() const
|
||||
{return cmap;}
|
||||
private:
|
||||
/** Inverse map to Tconstantmap. */
|
||||
typedef map<double,int> Tconstantinvmap;
|
||||
/** This is an inverse map to cmap. This is only used for fast
|
||||
* queries for the existing double constants in check
|
||||
* method and add_constant. */
|
||||
Tconstantinvmap cinvmap;
|
||||
};
|
||||
class Constants : public AtomValues
|
||||
{
|
||||
public:
|
||||
/** Type for a map mapping tree indices to double values. */
|
||||
typedef map<int, double> Tconstantmap;
|
||||
typedef map<int, int> Tintintmap;
|
||||
protected:
|
||||
/** Map mapping a tree index of a constant to its double value. */
|
||||
Tconstantmap cmap;
|
||||
public:
|
||||
Constants()
|
||||
{
|
||||
}
|
||||
/** Copy constructor. */
|
||||
Constants(const Constants &c)
|
||||
: cmap(c.cmap), cinvmap(c.cinvmap)
|
||||
{
|
||||
}
|
||||
/** Copy constructor registering the constants in the given
|
||||
* tree. The mapping from old tree indices to new ones is
|
||||
* traced in tmap. */
|
||||
Constants(const Constants &c, OperationTree &otree, Tintintmap &tmap)
|
||||
{
|
||||
import_constants(c, otree, tmap);
|
||||
}
|
||||
/** Import constants registering their tree indices in the
|
||||
* given tree. The mapping form old tree indices to new ones
|
||||
* is traced in tmap. */
|
||||
void import_constants(const Constants &c, OperationTree &otree, Tintintmap &tmap);
|
||||
/** Implements AtomValues interface. This sets the values to
|
||||
* the evaluation tree EvalTree. */
|
||||
void setValues(EvalTree &et) const;
|
||||
/** This adds a constant with the given tree index. The
|
||||
* constant must be checked previously and asserted that it
|
||||
* does not exist. */
|
||||
void add_constant(int t, double val);
|
||||
/** Returns true if the tree index is either an hardwired
|
||||
* constant (initial number OperationTree:num_constants in
|
||||
* OperationTree) or the tree index is a registered constant
|
||||
* by add_constant method. */
|
||||
bool is_constant(int t) const;
|
||||
double get_constant_value(int t) const;
|
||||
/** Return -1 if the given string representation of a constant
|
||||
* is not among the constants (double represenations). If it
|
||||
* is, its tree index is returned. */
|
||||
int check(const char *str) const;
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
const Tconstantmap &
|
||||
get_constantmap() const
|
||||
{
|
||||
return cmap;
|
||||
}
|
||||
private:
|
||||
/** Inverse map to Tconstantmap. */
|
||||
typedef map<double, int> Tconstantinvmap;
|
||||
/** This is an inverse map to cmap. This is only used for fast
|
||||
* queries for the existing double constants in check
|
||||
* method and add_constant. */
|
||||
Tconstantinvmap cinvmap;
|
||||
};
|
||||
|
||||
/** This class is a parent to Atoms classes which distinguish between
|
||||
* constants (numerical literals), and variables with lags and
|
||||
* leads. This abstraction does not distinguish between a parameter
|
||||
* and a variable without lag or lead. In this sense, everything is a
|
||||
* variable.*/
|
||||
class DynamicAtoms : public Atoms, public Constants {
|
||||
public:
|
||||
/** Definition of a type mapping lags to the indices of the variables. */
|
||||
typedef map<int,int> Tlagmap;
|
||||
protected:
|
||||
/** Definition of a type mapping names of the atoms to Tlagmap. */
|
||||
typedef map<const char*, Tlagmap, ltstr> Tvarmap;
|
||||
/** Definition of a type mapping indices of variables to the variable names. */
|
||||
typedef map<int, const char*> Tindexmap;
|
||||
/** This is just a storage for variable names, since all other
|
||||
* instances of a variable name just point to the memory
|
||||
* allocated by this object. */
|
||||
NameStorage varnames;
|
||||
/** This is the map for variables. Each variable name is
|
||||
* mapped to the Tlagmap, which maps lags/leads to the nulary
|
||||
* term indices in the tree. */
|
||||
Tvarmap vars;
|
||||
/** This is almost inverse map to the vars. It maps variable
|
||||
* indices to the names. A returned name can be in turn used
|
||||
* as a key in vars. */
|
||||
Tindexmap indices;
|
||||
/** This class is a parent to Atoms classes which distinguish between
|
||||
* constants (numerical literals), and variables with lags and
|
||||
* leads. This abstraction does not distinguish between a parameter
|
||||
* and a variable without lag or lead. In this sense, everything is a
|
||||
* variable.*/
|
||||
class DynamicAtoms : public Atoms, public Constants
|
||||
{
|
||||
public:
|
||||
/** Definition of a type mapping lags to the indices of the variables. */
|
||||
typedef map<int, int> Tlagmap;
|
||||
protected:
|
||||
/** Definition of a type mapping names of the atoms to Tlagmap. */
|
||||
typedef map<const char *, Tlagmap, ltstr> Tvarmap;
|
||||
/** Definition of a type mapping indices of variables to the variable names. */
|
||||
typedef map<int, const char *> Tindexmap;
|
||||
/** This is just a storage for variable names, since all other
|
||||
* instances of a variable name just point to the memory
|
||||
* allocated by this object. */
|
||||
NameStorage varnames;
|
||||
/** This is the map for variables. Each variable name is
|
||||
* mapped to the Tlagmap, which maps lags/leads to the nulary
|
||||
* term indices in the tree. */
|
||||
Tvarmap vars;
|
||||
/** This is almost inverse map to the vars. It maps variable
|
||||
* indices to the names. A returned name can be in turn used
|
||||
* as a key in vars. */
|
||||
Tindexmap indices;
|
||||
|
||||
/** Number of variables. */
|
||||
int nv;
|
||||
/** Minimum lag, if there is at least one lag, than this is a negative number. */
|
||||
int minlag;
|
||||
/** Maximum lead, if there is at least one lead, than this is a positive number. */
|
||||
int maxlead;
|
||||
public:
|
||||
/** Construct empty DynamicAtoms. */
|
||||
DynamicAtoms();
|
||||
DynamicAtoms(const DynamicAtoms& da);
|
||||
virtual ~DynamicAtoms() {}
|
||||
/** Check the nulary term identified by its string
|
||||
* representation. The nulary term can be either a constant or
|
||||
* a variable. If constant, -1 is returned so that it could be
|
||||
* assigned regardless if the same constant has already
|
||||
* appeared or not. If variable, then -1 is returned only if
|
||||
* the variable has not been assigned an index, otherwise the
|
||||
* assigned index is returned. */
|
||||
int check(const char* name) const;
|
||||
/** Assign the nulary term identified by its string
|
||||
* representation. This method should be called when check()
|
||||
* returns -1. */
|
||||
void assign(const char* name, int t);
|
||||
/** Return a number of all variables. */
|
||||
int nvar() const
|
||||
{ return nv; }
|
||||
/** Return the vector of variable indices. */
|
||||
vector<int> variables() const;
|
||||
/** Return max lead and min lag for a variable given by the
|
||||
* index. If a variable cannot be found, the method retursn
|
||||
* the smallest integer as maxlead and the largest integer as
|
||||
* minlag. */
|
||||
void varspan(int t, int& mlead, int& mlag) const;
|
||||
/** Return max lead and min lag for a variable given by the
|
||||
* name (without lead, lag). The same is valid if the variable
|
||||
* name cannot be found. */
|
||||
void varspan(const char* name, int& mlead, int& mlag) const;
|
||||
/** Return max lead and min lag for a vector of variables given by the names. */
|
||||
void varspan(const vector<const char*>& names, int& mlead, int& mlag) const;
|
||||
/** Return true for all tree indices corresponding to a
|
||||
* variable in the sense of this class. (This is parameters,
|
||||
* exo and endo). Since the semantics of 'variable' will be
|
||||
* changed in subclasses, we use name 'named atom'. These are
|
||||
* all atoms but constants. */
|
||||
bool is_named_atom(int t) const;
|
||||
/** Return index of the variable described by the variable
|
||||
* name and lag/lead. If it doesn't exist, return -1. */
|
||||
int index(const char* name, int ll) const;
|
||||
/** Return true if a variable is referenced, i.e. it has lag
|
||||
* map. */
|
||||
bool is_referenced(const char* name) const;
|
||||
/** Return the lag map for the variable name. */
|
||||
const Tlagmap& lagmap(const char* name) const;
|
||||
/** Return the variable name for the tree index. It throws an
|
||||
* exception if the tree index t is not a named atom. */
|
||||
const char* name(int t) const;
|
||||
/** Return the lead/lag for the tree index. It throws an
|
||||
* exception if the tree index t is not a named atom. */
|
||||
int lead(int t) const;
|
||||
/** Return maximum lead. */
|
||||
int get_maxlead() const
|
||||
{return maxlead;}
|
||||
/** Return minimum lag. */
|
||||
int get_minlag() const
|
||||
{return minlag;}
|
||||
/** Return the name storage to allow querying to other
|
||||
* classes. */
|
||||
const NameStorage& get_name_storage() const
|
||||
{return varnames;}
|
||||
/** Assign the variable with a given lead. The varname must be
|
||||
* from the varnames storage. The method checks if the
|
||||
* variable iwht the given lead/lag is not assigned. If so, an
|
||||
* exception is thrown. */
|
||||
void assign_variable(const char* varname, int ll, int t);
|
||||
/** Unassign the variable with a given lead and given tree
|
||||
* index. The tree index is only provided as a check. An
|
||||
* exception is thrown if the name, ll, and the tree index t
|
||||
* are not consistent. The method also updates nv, indices,
|
||||
* maxlead and minlag. The varname must be from the varnames
|
||||
* storage. */
|
||||
void unassign_variable(const char* varname, int ll, int t);
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
protected:
|
||||
/** Do the check for the variable. A subclass may need to
|
||||
* reimplement this so that it could raise an error if the
|
||||
* variable is not among a given list. */
|
||||
virtual int check_variable(const char* name) const;
|
||||
/** Assign the constant. */
|
||||
void assign_constant(const char* name, int t);
|
||||
/** Assign the variable. */
|
||||
void assign_variable(const char* name, int t);
|
||||
/** The method just updates minlag or/and maxlead. Note that
|
||||
* when assigning variables, the update is done when inserting
|
||||
* to the maps, however, if removing a variable, we need to
|
||||
* call this method. */
|
||||
void update_minmaxll();
|
||||
/** The method parses the string to recover a variable name
|
||||
* and lag/lead ll. The variable name doesn't contain a lead/lag. */
|
||||
virtual void parse_variable(const char* in, string& out, int& ll) const = 0;
|
||||
public:
|
||||
/** Return true if the str represents a double.*/
|
||||
static bool is_string_constant(const char* str);
|
||||
};
|
||||
/** Number of variables. */
|
||||
int nv;
|
||||
/** Minimum lag, if there is at least one lag, than this is a negative number. */
|
||||
int minlag;
|
||||
/** Maximum lead, if there is at least one lead, than this is a positive number. */
|
||||
int maxlead;
|
||||
public:
|
||||
/** Construct empty DynamicAtoms. */
|
||||
DynamicAtoms();
|
||||
DynamicAtoms(const DynamicAtoms &da);
|
||||
virtual ~DynamicAtoms()
|
||||
{
|
||||
}
|
||||
/** Check the nulary term identified by its string
|
||||
* representation. The nulary term can be either a constant or
|
||||
* a variable. If constant, -1 is returned so that it could be
|
||||
* assigned regardless if the same constant has already
|
||||
* appeared or not. If variable, then -1 is returned only if
|
||||
* the variable has not been assigned an index, otherwise the
|
||||
* assigned index is returned. */
|
||||
int check(const char *name) const;
|
||||
/** Assign the nulary term identified by its string
|
||||
* representation. This method should be called when check()
|
||||
* returns -1. */
|
||||
void assign(const char *name, int t);
|
||||
/** Return a number of all variables. */
|
||||
int
|
||||
nvar() const
|
||||
{
|
||||
return nv;
|
||||
}
|
||||
/** Return the vector of variable indices. */
|
||||
vector<int> variables() const;
|
||||
/** Return max lead and min lag for a variable given by the
|
||||
* index. If a variable cannot be found, the method retursn
|
||||
* the smallest integer as maxlead and the largest integer as
|
||||
* minlag. */
|
||||
void varspan(int t, int &mlead, int &mlag) const;
|
||||
/** Return max lead and min lag for a variable given by the
|
||||
* name (without lead, lag). The same is valid if the variable
|
||||
* name cannot be found. */
|
||||
void varspan(const char *name, int &mlead, int &mlag) const;
|
||||
/** Return max lead and min lag for a vector of variables given by the names. */
|
||||
void varspan(const vector<const char *> &names, int &mlead, int &mlag) const;
|
||||
/** Return true for all tree indices corresponding to a
|
||||
* variable in the sense of this class. (This is parameters,
|
||||
* exo and endo). Since the semantics of 'variable' will be
|
||||
* changed in subclasses, we use name 'named atom'. These are
|
||||
* all atoms but constants. */
|
||||
bool is_named_atom(int t) const;
|
||||
/** Return index of the variable described by the variable
|
||||
* name and lag/lead. If it doesn't exist, return -1. */
|
||||
int index(const char *name, int ll) const;
|
||||
/** Return true if a variable is referenced, i.e. it has lag
|
||||
* map. */
|
||||
bool is_referenced(const char *name) const;
|
||||
/** Return the lag map for the variable name. */
|
||||
const Tlagmap&lagmap(const char *name) const;
|
||||
/** Return the variable name for the tree index. It throws an
|
||||
* exception if the tree index t is not a named atom. */
|
||||
const char *name(int t) const;
|
||||
/** Return the lead/lag for the tree index. It throws an
|
||||
* exception if the tree index t is not a named atom. */
|
||||
int lead(int t) const;
|
||||
/** Return maximum lead. */
|
||||
int
|
||||
get_maxlead() const
|
||||
{
|
||||
return maxlead;
|
||||
}
|
||||
/** Return minimum lag. */
|
||||
int
|
||||
get_minlag() const
|
||||
{
|
||||
return minlag;
|
||||
}
|
||||
/** Return the name storage to allow querying to other
|
||||
* classes. */
|
||||
const NameStorage &
|
||||
get_name_storage() const
|
||||
{
|
||||
return varnames;
|
||||
}
|
||||
/** Assign the variable with a given lead. The varname must be
|
||||
* from the varnames storage. The method checks if the
|
||||
* variable iwht the given lead/lag is not assigned. If so, an
|
||||
* exception is thrown. */
|
||||
void assign_variable(const char *varname, int ll, int t);
|
||||
/** Unassign the variable with a given lead and given tree
|
||||
* index. The tree index is only provided as a check. An
|
||||
* exception is thrown if the name, ll, and the tree index t
|
||||
* are not consistent. The method also updates nv, indices,
|
||||
* maxlead and minlag. The varname must be from the varnames
|
||||
* storage. */
|
||||
void unassign_variable(const char *varname, int ll, int t);
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
protected:
|
||||
/** Do the check for the variable. A subclass may need to
|
||||
* reimplement this so that it could raise an error if the
|
||||
* variable is not among a given list. */
|
||||
virtual int check_variable(const char *name) const;
|
||||
/** Assign the constant. */
|
||||
void assign_constant(const char *name, int t);
|
||||
/** Assign the variable. */
|
||||
void assign_variable(const char *name, int t);
|
||||
/** The method just updates minlag or/and maxlead. Note that
|
||||
* when assigning variables, the update is done when inserting
|
||||
* to the maps, however, if removing a variable, we need to
|
||||
* call this method. */
|
||||
void update_minmaxll();
|
||||
/** The method parses the string to recover a variable name
|
||||
* and lag/lead ll. The variable name doesn't contain a lead/lag. */
|
||||
virtual void parse_variable(const char *in, string &out, int &ll) const = 0;
|
||||
public:
|
||||
/** Return true if the str represents a double.*/
|
||||
static bool is_string_constant(const char *str);
|
||||
};
|
||||
|
||||
|
||||
/** This class is a parent of all orderings of the dynamic atoms
|
||||
* of variables which can appear before t, at t, or after t. It
|
||||
* encapsulates the ordering, and the information about the number
|
||||
* of static (appearing only at time t) predetermined (appearing
|
||||
* before t and possibly at t), both (appearing before t and after
|
||||
* t and possibly at t) and forward looking (appearing after t and
|
||||
* possibly at t).
|
||||
*
|
||||
* The constructor takes a list of variable names. The class also
|
||||
* provides mapping from the ordering of the variables in the list
|
||||
* (outer) to the new ordering (at time t) and back.
|
||||
*
|
||||
* The user of the subclass must call do_ordering() after
|
||||
* initialization.
|
||||
*
|
||||
* The class contains a few preimplemented methods for
|
||||
* ordering. The class is used in this way: Make a subclass, and
|
||||
* implement pure virtual do_ordering() by just plugging a
|
||||
* preimplemented method, or plugging your own implementation. The
|
||||
* method do_ordering() is called by the user after the constructor.
|
||||
*/
|
||||
class VarOrdering {
|
||||
protected:
|
||||
/** Number of static variables. */
|
||||
int n_stat;
|
||||
/** Number of predetermined variables. */
|
||||
int n_pred;
|
||||
/** Number of both variables. */
|
||||
int n_both;
|
||||
/** Number of forward looking variables. */
|
||||
int n_forw;
|
||||
/** This is a set of tree indices corresponding to the
|
||||
* variables at all times as they occur in the formulas. In
|
||||
* fact, since this is used only for derivatives, the ordering
|
||||
* of this vector is only important for ordering of the
|
||||
* derivatives, in other contexts the ordering is not
|
||||
* important, so it is rather a set of indices.*/
|
||||
vector<int> der_atoms;
|
||||
/** This maps tree index of the variable to the position in
|
||||
* the row of the ordering. One should be careful with making
|
||||
* space in the positions for variables not appearing at time
|
||||
* t. For instance in the pred(t-1), both(t-1), stat(t),
|
||||
* pred(t), both(t), forw(t), both(t+1), forw(t+1) ordering,
|
||||
* the variables x(t-1), y(t-1), x(t+1), z(t-1), z(t), and
|
||||
* z(t+1) having tree indices 6,5,4,3,2,1 will be ordered as
|
||||
* follows: y(t-1), x(t-1), z(t-1), [y(t)], [x(t)], z(t),
|
||||
* x(t+1), where a bracketed expresion means non-existent by
|
||||
* occupying a space. The map thus will look as follows:
|
||||
* {5->0, 6->1, 3->2, 2->5, 3->6}. Note that nothing is mapped
|
||||
* to positions 3 and 4. */
|
||||
map<int,int> positions;
|
||||
/** This maps an ordering of the list of variables in
|
||||
* constructor to the new ordering (at time t). The length is
|
||||
* the number of variables. */
|
||||
vector<int> outer2y;
|
||||
/** This maps a new ordering to the ordering of the list of
|
||||
* variables in constructor (at time t). The length is the
|
||||
* number of variables. */
|
||||
vector<int> y2outer;
|
||||
/** This is just a reference for variable names to keep it
|
||||
* from constructor to do_ordering() implementations. */
|
||||
const vector<const char*>& varnames;
|
||||
/** This is just a reference to atoms to keep it from
|
||||
* constructor to do_ordering() implementations. */
|
||||
const DynamicAtoms& atoms;
|
||||
public:
|
||||
/** This is an enum type for an ordering type implemented by
|
||||
* do_general. */
|
||||
enum ord_type {pbspbfbf, bfspbfpb};
|
||||
/** Construct the ordering of the variables given by the names
|
||||
* with their dynamic occurrences defined by the atoms. It
|
||||
* calls the virtual method do_ordering which can be
|
||||
* reimplemented. */
|
||||
VarOrdering(const vector<const char*>& vnames, const DynamicAtoms& a)
|
||||
: n_stat(0), n_pred(0), n_both(0), n_forw(0), varnames(vnames), atoms(a)
|
||||
{}
|
||||
VarOrdering(const VarOrdering& vo, const vector<const char*>& vnames,
|
||||
const DynamicAtoms& a);
|
||||
virtual VarOrdering* clone(const vector<const char*>& vnames,
|
||||
const DynamicAtoms& a) const = 0;
|
||||
/** Destructor does nothing here. */
|
||||
virtual ~VarOrdering() {}
|
||||
/** This is the method setting the ordering and the map. A
|
||||
* subclass must reimplement it, possibly using a
|
||||
* preimplemented ordering. This method must be called by the
|
||||
* user after the class has been created. */
|
||||
virtual void do_ordering() = 0;
|
||||
/** Return number of static. */
|
||||
int nstat() const
|
||||
{return n_stat;}
|
||||
/** Return number of predetermined. */
|
||||
int npred() const
|
||||
{return n_pred;}
|
||||
/** Return number of both. */
|
||||
int nboth() const
|
||||
{return n_both;}
|
||||
/** Return number of forward looking. */
|
||||
int nforw() const
|
||||
{return n_forw;}
|
||||
/** Return the set of tree indices for derivatives. */
|
||||
const vector<int>& get_der_atoms() const
|
||||
{return der_atoms;}
|
||||
/** Return the y2outer. */
|
||||
const vector<int>& get_y2outer() const
|
||||
{return y2outer;}
|
||||
/** Return the outer2y. */
|
||||
const vector<int>& get_outer2y() const
|
||||
{return outer2y;}
|
||||
/** Query the atom given by the tree index. True is returned
|
||||
* if the atom is one of the variables in the object. */
|
||||
bool check(int t) const;
|
||||
/** Return the position of the atom (nulary term) given by a
|
||||
* tree index. It is a lookup to the map. If the atom cannot
|
||||
* be found, the exception is raised. */
|
||||
int get_pos_of(int t) const;
|
||||
/** This returns a length of ordered row of atoms. In all
|
||||
* cases so far, it does not depend on the ordering and it is
|
||||
* as follows. */
|
||||
int length() const
|
||||
{return n_stat+2*n_pred+3*n_both+2*n_forw;}
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
protected:
|
||||
/** This is a general ordering method which orders the
|
||||
* variables by the given ordering ord_type. See documentation
|
||||
* for respective do_ methods. */
|
||||
void do_general(ord_type ordering);
|
||||
/** This is a preimplemented ordering for do_ordering()
|
||||
* method. It assumes that the variables appear only at time
|
||||
* t-1, t, t+1. It orders the atoms as pred(t-1), both(t-1),
|
||||
* stat(t), pred(t), both(t), forw(t), both(t+1),
|
||||
* forw(t+1). It builds the der_atoms, the map of positions,
|
||||
* as well as y2outer and outer2y. */
|
||||
void do_pbspbfbf()
|
||||
{do_general(pbspbfbf);}
|
||||
/** This is a preimplemented ordering for do_ordering()
|
||||
* method. It assumes that the variables appear only at time
|
||||
* t-1, t, t+1. It orders the atoms as both(t+1), forw(t+1),
|
||||
* stat(t), pred(t), both(t), forw(t), pred(t-1),
|
||||
* both(t-1). It builds the der_atoms, the map of positions,
|
||||
* as well as y2outer and outer2y. */
|
||||
void do_bfspbfpb()
|
||||
{do_general(bfspbfpb);}
|
||||
/** This is a preimplemented ordering for do_ordering()
|
||||
* method. It makes no assumptions about occurences of
|
||||
* variables at different times. It orders the atoms with
|
||||
* increasing time keeping the given ordering within one
|
||||
* time. This implies that y2outer and outer2y will be
|
||||
* identities. The der_atoms will be just a sequence of atoms
|
||||
* from the least to the most time preserving the order of atoms
|
||||
* within one time. */
|
||||
void do_increasing_time();
|
||||
private:
|
||||
/** Declare this copy constructor as private to hide it. */
|
||||
VarOrdering(const VarOrdering& vo);
|
||||
};
|
||||
/** This class is a parent of all orderings of the dynamic atoms
|
||||
* of variables which can appear before t, at t, or after t. It
|
||||
* encapsulates the ordering, and the information about the number
|
||||
* of static (appearing only at time t) predetermined (appearing
|
||||
* before t and possibly at t), both (appearing before t and after
|
||||
* t and possibly at t) and forward looking (appearing after t and
|
||||
* possibly at t).
|
||||
*
|
||||
* The constructor takes a list of variable names. The class also
|
||||
* provides mapping from the ordering of the variables in the list
|
||||
* (outer) to the new ordering (at time t) and back.
|
||||
*
|
||||
* The user of the subclass must call do_ordering() after
|
||||
* initialization.
|
||||
*
|
||||
* The class contains a few preimplemented methods for
|
||||
* ordering. The class is used in this way: Make a subclass, and
|
||||
* implement pure virtual do_ordering() by just plugging a
|
||||
* preimplemented method, or plugging your own implementation. The
|
||||
* method do_ordering() is called by the user after the constructor.
|
||||
*/
|
||||
class VarOrdering
|
||||
{
|
||||
protected:
|
||||
/** Number of static variables. */
|
||||
int n_stat;
|
||||
/** Number of predetermined variables. */
|
||||
int n_pred;
|
||||
/** Number of both variables. */
|
||||
int n_both;
|
||||
/** Number of forward looking variables. */
|
||||
int n_forw;
|
||||
/** This is a set of tree indices corresponding to the
|
||||
* variables at all times as they occur in the formulas. In
|
||||
* fact, since this is used only for derivatives, the ordering
|
||||
* of this vector is only important for ordering of the
|
||||
* derivatives, in other contexts the ordering is not
|
||||
* important, so it is rather a set of indices.*/
|
||||
vector<int> der_atoms;
|
||||
/** This maps tree index of the variable to the position in
|
||||
* the row of the ordering. One should be careful with making
|
||||
* space in the positions for variables not appearing at time
|
||||
* t. For instance in the pred(t-1), both(t-1), stat(t),
|
||||
* pred(t), both(t), forw(t), both(t+1), forw(t+1) ordering,
|
||||
* the variables x(t-1), y(t-1), x(t+1), z(t-1), z(t), and
|
||||
* z(t+1) having tree indices 6,5,4,3,2,1 will be ordered as
|
||||
* follows: y(t-1), x(t-1), z(t-1), [y(t)], [x(t)], z(t),
|
||||
* x(t+1), where a bracketed expresion means non-existent by
|
||||
* occupying a space. The map thus will look as follows:
|
||||
* {5->0, 6->1, 3->2, 2->5, 3->6}. Note that nothing is mapped
|
||||
* to positions 3 and 4. */
|
||||
map<int, int> positions;
|
||||
/** This maps an ordering of the list of variables in
|
||||
* constructor to the new ordering (at time t). The length is
|
||||
* the number of variables. */
|
||||
vector<int> outer2y;
|
||||
/** This maps a new ordering to the ordering of the list of
|
||||
* variables in constructor (at time t). The length is the
|
||||
* number of variables. */
|
||||
vector<int> y2outer;
|
||||
/** This is just a reference for variable names to keep it
|
||||
* from constructor to do_ordering() implementations. */
|
||||
const vector<const char *> &varnames;
|
||||
/** This is just a reference to atoms to keep it from
|
||||
* constructor to do_ordering() implementations. */
|
||||
const DynamicAtoms &atoms;
|
||||
public:
|
||||
/** This is an enum type for an ordering type implemented by
|
||||
* do_general. */
|
||||
enum ord_type {pbspbfbf, bfspbfpb};
|
||||
/** Construct the ordering of the variables given by the names
|
||||
* with their dynamic occurrences defined by the atoms. It
|
||||
* calls the virtual method do_ordering which can be
|
||||
* reimplemented. */
|
||||
VarOrdering(const vector<const char *> &vnames, const DynamicAtoms &a)
|
||||
: n_stat(0), n_pred(0), n_both(0), n_forw(0), varnames(vnames), atoms(a)
|
||||
{
|
||||
}
|
||||
VarOrdering(const VarOrdering &vo, const vector<const char *> &vnames,
|
||||
const DynamicAtoms &a);
|
||||
virtual VarOrdering *clone(const vector<const char *> &vnames,
|
||||
const DynamicAtoms &a) const = 0;
|
||||
/** Destructor does nothing here. */
|
||||
virtual ~VarOrdering()
|
||||
{
|
||||
}
|
||||
/** This is the method setting the ordering and the map. A
|
||||
* subclass must reimplement it, possibly using a
|
||||
* preimplemented ordering. This method must be called by the
|
||||
* user after the class has been created. */
|
||||
virtual void do_ordering() = 0;
|
||||
/** Return number of static. */
|
||||
int
|
||||
nstat() const
|
||||
{
|
||||
return n_stat;
|
||||
}
|
||||
/** Return number of predetermined. */
|
||||
int
|
||||
npred() const
|
||||
{
|
||||
return n_pred;
|
||||
}
|
||||
/** Return number of both. */
|
||||
int
|
||||
nboth() const
|
||||
{
|
||||
return n_both;
|
||||
}
|
||||
/** Return number of forward looking. */
|
||||
int
|
||||
nforw() const
|
||||
{
|
||||
return n_forw;
|
||||
}
|
||||
/** Return the set of tree indices for derivatives. */
|
||||
const vector<int> &
|
||||
get_der_atoms() const
|
||||
{
|
||||
return der_atoms;
|
||||
}
|
||||
/** Return the y2outer. */
|
||||
const vector<int> &
|
||||
get_y2outer() const
|
||||
{
|
||||
return y2outer;
|
||||
}
|
||||
/** Return the outer2y. */
|
||||
const vector<int> &
|
||||
get_outer2y() const
|
||||
{
|
||||
return outer2y;
|
||||
}
|
||||
/** Query the atom given by the tree index. True is returned
|
||||
* if the atom is one of the variables in the object. */
|
||||
bool check(int t) const;
|
||||
/** Return the position of the atom (nulary term) given by a
|
||||
* tree index. It is a lookup to the map. If the atom cannot
|
||||
* be found, the exception is raised. */
|
||||
int get_pos_of(int t) const;
|
||||
/** This returns a length of ordered row of atoms. In all
|
||||
* cases so far, it does not depend on the ordering and it is
|
||||
* as follows. */
|
||||
int
|
||||
length() const
|
||||
{
|
||||
return n_stat+2*n_pred+3*n_both+2*n_forw;
|
||||
}
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
protected:
|
||||
/** This is a general ordering method which orders the
|
||||
* variables by the given ordering ord_type. See documentation
|
||||
* for respective do_ methods. */
|
||||
void do_general(ord_type ordering);
|
||||
/** This is a preimplemented ordering for do_ordering()
|
||||
* method. It assumes that the variables appear only at time
|
||||
* t-1, t, t+1. It orders the atoms as pred(t-1), both(t-1),
|
||||
* stat(t), pred(t), both(t), forw(t), both(t+1),
|
||||
* forw(t+1). It builds the der_atoms, the map of positions,
|
||||
* as well as y2outer and outer2y. */
|
||||
void
|
||||
do_pbspbfbf()
|
||||
{
|
||||
do_general(pbspbfbf);
|
||||
}
|
||||
/** This is a preimplemented ordering for do_ordering()
|
||||
* method. It assumes that the variables appear only at time
|
||||
* t-1, t, t+1. It orders the atoms as both(t+1), forw(t+1),
|
||||
* stat(t), pred(t), both(t), forw(t), pred(t-1),
|
||||
* both(t-1). It builds the der_atoms, the map of positions,
|
||||
* as well as y2outer and outer2y. */
|
||||
void
|
||||
do_bfspbfpb()
|
||||
{
|
||||
do_general(bfspbfpb);
|
||||
}
|
||||
/** This is a preimplemented ordering for do_ordering()
|
||||
* method. It makes no assumptions about occurences of
|
||||
* variables at different times. It orders the atoms with
|
||||
* increasing time keeping the given ordering within one
|
||||
* time. This implies that y2outer and outer2y will be
|
||||
* identities. The der_atoms will be just a sequence of atoms
|
||||
* from the least to the most time preserving the order of atoms
|
||||
* within one time. */
|
||||
void do_increasing_time();
|
||||
private:
|
||||
/** Declare this copy constructor as private to hide it. */
|
||||
VarOrdering(const VarOrdering &vo);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -10,337 +10,417 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace ogp {
|
||||
namespace ogp
|
||||
{
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
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<const char*>& vnames, const DynamicAtoms& a)
|
||||
: VarOrdering(vnames, a) {}
|
||||
EndoVarOrdering1(const EndoVarOrdering1& vo, const vector<const char*>& vnames,
|
||||
const DynamicAtoms& a)
|
||||
: VarOrdering(vo, vnames, a) {}
|
||||
VarOrdering* clone(const vector<const char*>& vnames, const DynamicAtoms& a) const
|
||||
{return new EndoVarOrdering1(*this, vnames, a);}
|
||||
void do_ordering()
|
||||
{do_pbspbfbf();}
|
||||
};
|
||||
/** 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<const char *> &vnames, const DynamicAtoms &a)
|
||||
: VarOrdering(vnames, a)
|
||||
{
|
||||
}
|
||||
EndoVarOrdering1(const EndoVarOrdering1 &vo, const vector<const char *> &vnames,
|
||||
const DynamicAtoms &a)
|
||||
: VarOrdering(vo, vnames, a)
|
||||
{
|
||||
}
|
||||
VarOrdering *
|
||||
clone(const vector<const char *> &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<const char*>& vnames, const DynamicAtoms& a)
|
||||
: VarOrdering(vnames, a) {}
|
||||
EndoVarOrdering2(const EndoVarOrdering2& vo, const vector<const char*>& vnames,
|
||||
const DynamicAtoms& a)
|
||||
: VarOrdering(vo, vnames, a) {}
|
||||
VarOrdering* clone(const vector<const char*>& vnames, const DynamicAtoms& a) const
|
||||
{return new EndoVarOrdering2(*this, vnames, a);}
|
||||
void do_ordering()
|
||||
{do_bfspbfpb();}
|
||||
};
|
||||
/** 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<const char *> &vnames, const DynamicAtoms &a)
|
||||
: VarOrdering(vnames, a)
|
||||
{
|
||||
}
|
||||
EndoVarOrdering2(const EndoVarOrdering2 &vo, const vector<const char *> &vnames,
|
||||
const DynamicAtoms &a)
|
||||
: VarOrdering(vo, vnames, a)
|
||||
{
|
||||
}
|
||||
VarOrdering *
|
||||
clone(const vector<const char *> &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<const char*>& vnames, const DynamicAtoms& a)
|
||||
: VarOrdering(vnames, a) {}
|
||||
ExoVarOrdering(const ExoVarOrdering& vo, const vector<const char*>& vnames,
|
||||
const DynamicAtoms& a)
|
||||
: VarOrdering(vo, vnames, a) {}
|
||||
VarOrdering* clone(const vector<const char*>& vnames, const DynamicAtoms& a) const
|
||||
{return new ExoVarOrdering(*this, vnames, a);}
|
||||
void do_ordering()
|
||||
{do_increasing_time();}
|
||||
};
|
||||
/** 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<const char *> &vnames, const DynamicAtoms &a)
|
||||
: VarOrdering(vnames, a)
|
||||
{
|
||||
}
|
||||
ExoVarOrdering(const ExoVarOrdering &vo, const vector<const char *> &vnames,
|
||||
const DynamicAtoms &a)
|
||||
: VarOrdering(vo, vnames, a)
|
||||
{
|
||||
}
|
||||
VarOrdering *
|
||||
clone(const vector<const char *> &vnames, const DynamicAtoms &a) const
|
||||
{
|
||||
return new ExoVarOrdering(*this, vnames, a);
|
||||
}
|
||||
void
|
||||
do_ordering()
|
||||
{
|
||||
do_increasing_time();
|
||||
}
|
||||
};
|
||||
|
||||
class FineAtoms;
|
||||
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<const char*, int, ltstr> 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<const char*> 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<int> 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<int> 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<const char*>& 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<int>& get_endo2all() const
|
||||
{return endo2all;}
|
||||
/** Return exo2all mapping. */
|
||||
const vector<int>& get_exo2all() const
|
||||
{return exo2all;}
|
||||
/** Return the allvar ordering. */
|
||||
const vector<const char*>& get_allvar() const
|
||||
{return allvar;}
|
||||
};
|
||||
/** 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<const char *, int, ltstr> 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<const char *> 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<int> 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<int> 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<const char *> &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<int> &
|
||||
get_endo2all() const
|
||||
{
|
||||
return endo2all;
|
||||
}
|
||||
/** Return exo2all mapping. */
|
||||
const vector<int> &
|
||||
get_exo2all() const
|
||||
{
|
||||
return exo2all;
|
||||
}
|
||||
/** Return the allvar ordering. */
|
||||
const vector<const char *> &
|
||||
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<const char*, int, ltstr> Tvarintmap;
|
||||
private:
|
||||
/** The vector of parameters names. The order gives the order
|
||||
* the data is communicated with outside world. */
|
||||
vector<const char*> 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<const char*> 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<const char*> exovars;
|
||||
/** A map mapping a name of an exogenous variable to an index
|
||||
* in the outer ordering. */
|
||||
Tvarintmap exo_outer_map;
|
||||
/** 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<const char *, int, ltstr> Tvarintmap;
|
||||
private:
|
||||
/** The vector of parameters names. The order gives the order
|
||||
* the data is communicated with outside world. */
|
||||
vector<const char *> 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<const char *> 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<const char *> 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<int> 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<int> 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<int> 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<const char*>& get_params() const
|
||||
{return params;}
|
||||
/** Return an external ordering of endogenous variables. */
|
||||
const vector<const char*>& get_endovars() const
|
||||
{return endovars;}
|
||||
/** Return an external ordering of exogenous variables. */
|
||||
const vector<const char*>& 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<const char*> 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<const char*>& 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<int>& 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<int>& outer_exo2all() const;
|
||||
/** Return the atoms with respect to which we are going to
|
||||
* differentiate. This must be called after
|
||||
* parsing_finished. */
|
||||
vector<int> 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<int>& y2outer_endo() const;
|
||||
/** Return the mapping from the outer ordering of endogenous to endogenous
|
||||
* at time t. */
|
||||
const vector<int>& outer2y_endo() const;
|
||||
/** Return the mapping from exogenous at time t to outer
|
||||
* ordering of exogenous. */
|
||||
const vector<int>& y2outer_exo() const;
|
||||
/** Return the mapping from the outer ordering of exogenous to exogenous
|
||||
* at time t. */
|
||||
const vector<int>& outer2y_exo() const;
|
||||
/** Return the endo_atoms_map. */
|
||||
const vector<int>& get_endo_atoms_map() const;
|
||||
/** Return the exo_atoms_map. */
|
||||
const vector<int>& 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;
|
||||
};
|
||||
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<int> 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<int> 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<int> 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<const char *> &
|
||||
get_params() const
|
||||
{
|
||||
return params;
|
||||
}
|
||||
/** Return an external ordering of endogenous variables. */
|
||||
const vector<const char *> &
|
||||
get_endovars() const
|
||||
{
|
||||
return endovars;
|
||||
}
|
||||
/** Return an external ordering of exogenous variables. */
|
||||
const vector<const char *> &
|
||||
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<const char *> 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<const char *>&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<int>&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<int>&outer_exo2all() const;
|
||||
/** Return the atoms with respect to which we are going to
|
||||
* differentiate. This must be called after
|
||||
* parsing_finished. */
|
||||
vector<int> 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<int>&y2outer_endo() const;
|
||||
/** Return the mapping from the outer ordering of endogenous to endogenous
|
||||
* at time t. */
|
||||
const vector<int>&outer2y_endo() const;
|
||||
/** Return the mapping from exogenous at time t to outer
|
||||
* ordering of exogenous. */
|
||||
const vector<int>&y2outer_exo() const;
|
||||
/** Return the mapping from the outer ordering of exogenous to exogenous
|
||||
* at time t. */
|
||||
const vector<int>&outer2y_exo() const;
|
||||
/** Return the endo_atoms_map. */
|
||||
const vector<int>&get_endo_atoms_map() const;
|
||||
/** Return the exo_atoms_map. */
|
||||
const vector<int>&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
|
||||
|
|
|
@ -5,408 +5,492 @@
|
|||
|
||||
#include "tree.h"
|
||||
|
||||
namespace ogp {
|
||||
using std::vector;
|
||||
namespace ogp
|
||||
{
|
||||
using std::vector;
|
||||
|
||||
/** Pure virtual class defining a minimal interface for
|
||||
* representation of nulary terms within FormulaParser. */
|
||||
class Atoms {
|
||||
public:
|
||||
Atoms() {}
|
||||
virtual ~Atoms() {}
|
||||
/** This returns previously assigned internal index to the
|
||||
* given atom, or returns -1 if the atom has not been assigned
|
||||
* yet. The method can raise an exception, if the Atoms
|
||||
* implementation is strict and the name is not among
|
||||
* prescribed possible values. */
|
||||
virtual int check(const char* name) const = 0;
|
||||
/** This method assigns an internal index to the nulary term
|
||||
* described by the name. The internal index is allocated by
|
||||
* OperationTree class. */
|
||||
virtual void assign(const char* name, int t) = 0;
|
||||
/** Returns a number of variables which will be used for
|
||||
* differentiations. */
|
||||
virtual int nvar() const = 0;
|
||||
/** Returns a vector of variable's internal indices which will
|
||||
* be used for differentiations. */
|
||||
virtual vector<int> variables() const = 0;
|
||||
/** Debug print. */
|
||||
virtual void print() const = 0;
|
||||
};
|
||||
/** Pure virtual class defining a minimal interface for
|
||||
* representation of nulary terms within FormulaParser. */
|
||||
class Atoms
|
||||
{
|
||||
public:
|
||||
Atoms()
|
||||
{
|
||||
}
|
||||
virtual ~Atoms()
|
||||
{
|
||||
}
|
||||
/** This returns previously assigned internal index to the
|
||||
* given atom, or returns -1 if the atom has not been assigned
|
||||
* yet. The method can raise an exception, if the Atoms
|
||||
* implementation is strict and the name is not among
|
||||
* prescribed possible values. */
|
||||
virtual int check(const char *name) const = 0;
|
||||
/** This method assigns an internal index to the nulary term
|
||||
* described by the name. The internal index is allocated by
|
||||
* OperationTree class. */
|
||||
virtual void assign(const char *name, int t) = 0;
|
||||
/** Returns a number of variables which will be used for
|
||||
* differentiations. */
|
||||
virtual int nvar() const = 0;
|
||||
/** Returns a vector of variable's internal indices which will
|
||||
* be used for differentiations. */
|
||||
virtual vector<int> variables() const = 0;
|
||||
/** Debug print. */
|
||||
virtual void print() const = 0;
|
||||
};
|
||||
|
||||
/** Pure virtual class defining interface for all classes able to
|
||||
* set nulary terms to evaluation tree EvalTree. The
|
||||
* implementations of this class will have to be connected with
|
||||
* Atoms to have knowledge about the atoms and their indices in
|
||||
* the tree, and will call EvalTree::set_nulary. */
|
||||
class AtomValues {
|
||||
public:
|
||||
virtual ~AtomValues() {}
|
||||
virtual void setValues(EvalTree& et) const = 0;
|
||||
};
|
||||
/** Pure virtual class defining interface for all classes able to
|
||||
* set nulary terms to evaluation tree EvalTree. The
|
||||
* implementations of this class will have to be connected with
|
||||
* Atoms to have knowledge about the atoms and their indices in
|
||||
* the tree, and will call EvalTree::set_nulary. */
|
||||
class AtomValues
|
||||
{
|
||||
public:
|
||||
virtual ~AtomValues()
|
||||
{
|
||||
}
|
||||
virtual void setValues(EvalTree &et) const = 0;
|
||||
};
|
||||
|
||||
class FormulaDerEvaluator;
|
||||
class FoldMultiIndex;
|
||||
/** For ordering FoldMultiIndex in the std::map. */
|
||||
struct ltfmi {
|
||||
bool operator()(const FoldMultiIndex& i1, const FoldMultiIndex& i2) const;
|
||||
};
|
||||
class FormulaDerEvaluator;
|
||||
class FoldMultiIndex;
|
||||
/** For ordering FoldMultiIndex in the std::map. */
|
||||
struct ltfmi
|
||||
{
|
||||
bool operator()(const FoldMultiIndex &i1, const FoldMultiIndex &i2) const;
|
||||
};
|
||||
|
||||
/** This class stores derivatives (tree indices) of one formula
|
||||
* for all orders upto a given one. It stores the derivatives as a
|
||||
* sequence (vector) of these tree indices and sequence of the
|
||||
* multidimensional indices of variables wrt which the derivatives
|
||||
* were taken. In order to speed up querying for a derivative
|
||||
* given the variables, we have a map mapping the multidimensional
|
||||
* index to the order of the derivative in the sequence.
|
||||
*
|
||||
* The only reason we do not have only this map is that the
|
||||
* iterators of the map do not survive the insertions to the map,
|
||||
* and implementation of the constructor has to be very difficult.
|
||||
*/
|
||||
class FormulaDerivatives {
|
||||
friend class FormulaDerEvaluator;
|
||||
protected:
|
||||
/** Vector of derivatives. This is a list of derivatives (tree
|
||||
* indices), the ordering is given by the algorithm used to
|
||||
* create it. Currently, it starts with zero-th derivative,
|
||||
* the formula itself and carries with first order, second,
|
||||
* etc. */
|
||||
vector<int> tder;
|
||||
/** Vector of multiindices corresponding to the vector of
|
||||
* derivatives. */
|
||||
vector<FoldMultiIndex> indices;
|
||||
/** For retrieving derivatives via a multiindex, we have a map
|
||||
* mapping a multiindex to a derivative in the tder
|
||||
* ordering. This means that indices[ind2der[index]] == index. */
|
||||
typedef map<FoldMultiIndex, int, ltfmi> Tfmiintmap;
|
||||
Tfmiintmap ind2der;
|
||||
/** The number of variables. */
|
||||
int nvar;
|
||||
/** The maximum order of derivatives. */
|
||||
int order;
|
||||
public:
|
||||
/** The constructor allocates and fills the sequence of the
|
||||
* indices of derivatives for a formula.
|
||||
* @param otree the OperationTree for which all work is done
|
||||
* and to which the derivatives are added.
|
||||
* @param vars the vector of nulary terms in the tree; the
|
||||
* derivatives are taken with respect to these variables in
|
||||
* the ordering given by the vector.
|
||||
* @param f the index of the formula being differentiated. The
|
||||
* zero derivative is set to f.
|
||||
* @param max_order the maximum order of differentiation.
|
||||
*/
|
||||
FormulaDerivatives(OperationTree& otree, const vector<int>& vars, int f, int max_order);
|
||||
/** Copy constructor. */
|
||||
FormulaDerivatives(const FormulaDerivatives& fd);
|
||||
virtual ~FormulaDerivatives(){}
|
||||
/** Random access to the derivatives via multiindex. */
|
||||
int derivative(const FoldMultiIndex& mi) const;
|
||||
/** Return the order. */
|
||||
int get_order() const
|
||||
{return order;}
|
||||
/** Debug print. */
|
||||
void print(const OperationTree& otree) const;
|
||||
};
|
||||
/** This class stores derivatives (tree indices) of one formula
|
||||
* for all orders upto a given one. It stores the derivatives as a
|
||||
* sequence (vector) of these tree indices and sequence of the
|
||||
* multidimensional indices of variables wrt which the derivatives
|
||||
* were taken. In order to speed up querying for a derivative
|
||||
* given the variables, we have a map mapping the multidimensional
|
||||
* index to the order of the derivative in the sequence.
|
||||
*
|
||||
* The only reason we do not have only this map is that the
|
||||
* iterators of the map do not survive the insertions to the map,
|
||||
* and implementation of the constructor has to be very difficult.
|
||||
*/
|
||||
class FormulaDerivatives
|
||||
{
|
||||
friend class FormulaDerEvaluator;
|
||||
protected:
|
||||
/** Vector of derivatives. This is a list of derivatives (tree
|
||||
* indices), the ordering is given by the algorithm used to
|
||||
* create it. Currently, it starts with zero-th derivative,
|
||||
* the formula itself and carries with first order, second,
|
||||
* etc. */
|
||||
vector<int> tder;
|
||||
/** Vector of multiindices corresponding to the vector of
|
||||
* derivatives. */
|
||||
vector<FoldMultiIndex> indices;
|
||||
/** For retrieving derivatives via a multiindex, we have a map
|
||||
* mapping a multiindex to a derivative in the tder
|
||||
* ordering. This means that indices[ind2der[index]] == index. */
|
||||
typedef map<FoldMultiIndex, int, ltfmi> Tfmiintmap;
|
||||
Tfmiintmap ind2der;
|
||||
/** The number of variables. */
|
||||
int nvar;
|
||||
/** The maximum order of derivatives. */
|
||||
int order;
|
||||
public:
|
||||
/** The constructor allocates and fills the sequence of the
|
||||
* indices of derivatives for a formula.
|
||||
* @param otree the OperationTree for which all work is done
|
||||
* and to which the derivatives are added.
|
||||
* @param vars the vector of nulary terms in the tree; the
|
||||
* derivatives are taken with respect to these variables in
|
||||
* the ordering given by the vector.
|
||||
* @param f the index of the formula being differentiated. The
|
||||
* zero derivative is set to f.
|
||||
* @param max_order the maximum order of differentiation.
|
||||
*/
|
||||
FormulaDerivatives(OperationTree &otree, const vector<int> &vars, int f, int max_order);
|
||||
/** Copy constructor. */
|
||||
FormulaDerivatives(const FormulaDerivatives &fd);
|
||||
virtual ~FormulaDerivatives()
|
||||
{
|
||||
}
|
||||
/** Random access to the derivatives via multiindex. */
|
||||
int derivative(const FoldMultiIndex &mi) const;
|
||||
/** Return the order. */
|
||||
int
|
||||
get_order() const
|
||||
{
|
||||
return order;
|
||||
}
|
||||
/** Debug print. */
|
||||
void print(const OperationTree &otree) const;
|
||||
};
|
||||
|
||||
class FormulaEvaluator;
|
||||
class FormulaEvaluator;
|
||||
|
||||
/** This class is able to parse a number of formulas and
|
||||
* differentiate them. The life cycle of the object is as follows:
|
||||
* After it is created, a few calls to parse will add formulas
|
||||
* (zero derivatives) to the object. Then a method differentiate()
|
||||
* can be called and a vector of pointers to derivatives for each
|
||||
* formula is created. After this, no one should call other
|
||||
* parse() or differentiate(). A const reference of the object can
|
||||
* be used in constructors of FormulaEvaluator and
|
||||
* FormulaDerEvaluator in order to evaluate formulas (zero
|
||||
* derivatives) and higher derivatives resp. */
|
||||
class FormulaParser {
|
||||
friend class FormulaCustomEvaluator;
|
||||
friend class FormulaDerEvaluator;
|
||||
protected:
|
||||
/** The OperationTree of all formulas, including derivatives. */
|
||||
OperationTree otree;
|
||||
/** Reference to Atoms. The Atoms are filled with nulary terms
|
||||
* during execution of parse(). */
|
||||
Atoms& atoms;
|
||||
/** Vector of formulas (zero derivatives) in the order as they
|
||||
* have been parsed. */
|
||||
vector<int> formulas;
|
||||
/** The vector to derivatives, each vector corresponds to a
|
||||
* formula in the vector formulas. */
|
||||
vector<FormulaDerivatives*> ders;
|
||||
public:
|
||||
/** Construct an empty formula parser. */
|
||||
FormulaParser(Atoms& a)
|
||||
: atoms(a) {}
|
||||
/** Copy constructor using a different instance of Atoms. */
|
||||
FormulaParser(const FormulaParser& fp, Atoms& a);
|
||||
virtual ~FormulaParser();
|
||||
/** This class is able to parse a number of formulas and
|
||||
* differentiate them. The life cycle of the object is as follows:
|
||||
* After it is created, a few calls to parse will add formulas
|
||||
* (zero derivatives) to the object. Then a method differentiate()
|
||||
* can be called and a vector of pointers to derivatives for each
|
||||
* formula is created. After this, no one should call other
|
||||
* parse() or differentiate(). A const reference of the object can
|
||||
* be used in constructors of FormulaEvaluator and
|
||||
* FormulaDerEvaluator in order to evaluate formulas (zero
|
||||
* derivatives) and higher derivatives resp. */
|
||||
class FormulaParser
|
||||
{
|
||||
friend class FormulaCustomEvaluator;
|
||||
friend class FormulaDerEvaluator;
|
||||
protected:
|
||||
/** The OperationTree of all formulas, including derivatives. */
|
||||
OperationTree otree;
|
||||
/** Reference to Atoms. The Atoms are filled with nulary terms
|
||||
* during execution of parse(). */
|
||||
Atoms &atoms;
|
||||
/** Vector of formulas (zero derivatives) in the order as they
|
||||
* have been parsed. */
|
||||
vector<int> formulas;
|
||||
/** The vector to derivatives, each vector corresponds to a
|
||||
* formula in the vector formulas. */
|
||||
vector<FormulaDerivatives *> ders;
|
||||
public:
|
||||
/** Construct an empty formula parser. */
|
||||
FormulaParser(Atoms &a)
|
||||
: atoms(a)
|
||||
{
|
||||
}
|
||||
/** Copy constructor using a different instance of Atoms. */
|
||||
FormulaParser(const FormulaParser &fp, Atoms &a);
|
||||
virtual
|
||||
~FormulaParser();
|
||||
|
||||
/** Requires an addition of the formula; called from the
|
||||
* parser. */
|
||||
void add_formula(int t);
|
||||
/** Requires an addition of the binary operation; called from
|
||||
* the parser. */
|
||||
int add_binary(code_t code, int t1, int t2);
|
||||
/** Requires an addition of the unary operation; called from
|
||||
* the parser. */
|
||||
int add_unary(code_t code, int t);
|
||||
/** Requires an addition of the nulary operation given by the
|
||||
* string. The Atoms are consulted for uniquness and are given
|
||||
* an internal index generated by the OperationTree. This is
|
||||
* the channel through which the Atoms are filled. */
|
||||
int add_nulary(const char* str);
|
||||
/** Requires an addition of the formula; called from the
|
||||
* parser. */
|
||||
void add_formula(int t);
|
||||
/** Requires an addition of the binary operation; called from
|
||||
* the parser. */
|
||||
int add_binary(code_t code, int t1, int t2);
|
||||
/** Requires an addition of the unary operation; called from
|
||||
* the parser. */
|
||||
int add_unary(code_t code, int t);
|
||||
/** Requires an addition of the nulary operation given by the
|
||||
* string. The Atoms are consulted for uniquness and are given
|
||||
* an internal index generated by the OperationTree. This is
|
||||
* the channel through which the Atoms are filled. */
|
||||
int add_nulary(const char *str);
|
||||
|
||||
/** Adds a derivative to the tree. This just calls
|
||||
* OperationTree::add_derivative. */
|
||||
int add_derivative(int t, int v)
|
||||
{return otree.add_derivative(t, v);}
|
||||
/** Adds a substitution. This just calls
|
||||
* OperationTree::add_substitution. */
|
||||
int add_substitution(int t, const map<int,int>& subst)
|
||||
{return otree.add_substitution(t, subst);}
|
||||
/** Add the substitution given by the map where left sides of
|
||||
* substitutions come from another parser. The right sides are
|
||||
* from this object. The given t is from the given parser fp. */
|
||||
int add_substitution(int t, const map<int,int>& subst,
|
||||
const FormulaParser& fp)
|
||||
{return otree.add_substitution(t, subst, fp.otree);}
|
||||
/** This adds formulas from the given parser with (possibly)
|
||||
* different atoms applying substitutions from the given map
|
||||
* mapping atoms from fp to atoms of the object. */
|
||||
void add_subst_formulas(const map<int,int>& subst, const FormulaParser& fp);
|
||||
/** Substitute formulas. For each i from 1 through all
|
||||
* formulas, it adds a substitution of the i-th formula and
|
||||
* make it to be i-th formula.*/
|
||||
void substitute_formulas(const std::map<int,int>& subst);
|
||||
/** This method turns the given term to nulary operation. It
|
||||
* should be used with caution, since this method does not
|
||||
* anything do with atoms, but usually some action is also
|
||||
* needed (at leat to assign the tree index t to some
|
||||
* atom). */
|
||||
void nularify(int t)
|
||||
{otree.nularify(t);}
|
||||
/** Returns a set of nulary terms of the given term. Just
|
||||
* calls OperationTree::nulary_of_term. */
|
||||
const unordered_set<int>& nulary_of_term(int t) const
|
||||
{return otree.nulary_of_term(t);}
|
||||
/** Adds a derivative to the tree. This just calls
|
||||
* OperationTree::add_derivative. */
|
||||
int
|
||||
add_derivative(int t, int v)
|
||||
{
|
||||
return otree.add_derivative(t, v);
|
||||
}
|
||||
/** Adds a substitution. This just calls
|
||||
* OperationTree::add_substitution. */
|
||||
int
|
||||
add_substitution(int t, const map<int, int> &subst)
|
||||
{
|
||||
return otree.add_substitution(t, subst);
|
||||
}
|
||||
/** Add the substitution given by the map where left sides of
|
||||
* substitutions come from another parser. The right sides are
|
||||
* from this object. The given t is from the given parser fp. */
|
||||
int
|
||||
add_substitution(int t, const map<int, int> &subst,
|
||||
const FormulaParser &fp)
|
||||
{
|
||||
return otree.add_substitution(t, subst, fp.otree);
|
||||
}
|
||||
/** This adds formulas from the given parser with (possibly)
|
||||
* different atoms applying substitutions from the given map
|
||||
* mapping atoms from fp to atoms of the object. */
|
||||
void add_subst_formulas(const map<int, int> &subst, const FormulaParser &fp);
|
||||
/** Substitute formulas. For each i from 1 through all
|
||||
* formulas, it adds a substitution of the i-th formula and
|
||||
* make it to be i-th formula.*/
|
||||
void substitute_formulas(const std::map<int, int> &subst);
|
||||
/** This method turns the given term to nulary operation. It
|
||||
* should be used with caution, since this method does not
|
||||
* anything do with atoms, but usually some action is also
|
||||
* needed (at leat to assign the tree index t to some
|
||||
* atom). */
|
||||
void
|
||||
nularify(int t)
|
||||
{
|
||||
otree.nularify(t);
|
||||
}
|
||||
/** Returns a set of nulary terms of the given term. Just
|
||||
* calls OperationTree::nulary_of_term. */
|
||||
const unordered_set<int> &
|
||||
nulary_of_term(int t) const
|
||||
{
|
||||
return otree.nulary_of_term(t);
|
||||
}
|
||||
|
||||
/** Parse a given string containing one or more formulas. The
|
||||
* formulas are parsed and added to the OperationTree and to
|
||||
* the formulas vector. */
|
||||
void parse(int length, const char* stream);
|
||||
/** Processes a syntax error from bison. */
|
||||
void error(const char* mes) const;
|
||||
/** Differentiate all the formulas up to the given order. The
|
||||
* variables with respect to which the derivatives are taken
|
||||
* are obtained by Atoms::variables(). If the derivates exist,
|
||||
* they are destroyed and created again (with possibly
|
||||
* different order). */
|
||||
void differentiate(int max_order);
|
||||
/** Return i-th formula derivatives. */
|
||||
const FormulaDerivatives& derivatives(int i) const;
|
||||
/** Parse a given string containing one or more formulas. The
|
||||
* formulas are parsed and added to the OperationTree and to
|
||||
* the formulas vector. */
|
||||
void parse(int length, const char *stream);
|
||||
/** Processes a syntax error from bison. */
|
||||
void error(const char *mes) const;
|
||||
/** Differentiate all the formulas up to the given order. The
|
||||
* variables with respect to which the derivatives are taken
|
||||
* are obtained by Atoms::variables(). If the derivates exist,
|
||||
* they are destroyed and created again (with possibly
|
||||
* different order). */
|
||||
void differentiate(int max_order);
|
||||
/** Return i-th formula derivatives. */
|
||||
const FormulaDerivatives&derivatives(int i) const;
|
||||
|
||||
/** This returns a maximum index of zero derivative formulas
|
||||
* including all nulary terms. This is a mimumum length of the
|
||||
* tree for which it is safe to evaluate zero derivatives of
|
||||
* the formulas. */
|
||||
int last_formula() const;
|
||||
/** This returns a tree index of the i-th formula in the
|
||||
* vector. */
|
||||
int formula(int i) const
|
||||
{return formulas[i];}
|
||||
/** This returns a maximum index of zero derivative formulas
|
||||
* including all nulary terms. This is a mimumum length of the
|
||||
* tree for which it is safe to evaluate zero derivatives of
|
||||
* the formulas. */
|
||||
int last_formula() const;
|
||||
/** This returns a tree index of the i-th formula in the
|
||||
* vector. */
|
||||
int
|
||||
formula(int i) const
|
||||
{
|
||||
return formulas[i];
|
||||
}
|
||||
|
||||
/** This returns a tree index of the last formula and pops its
|
||||
* item from the formulas vector. The number of formulas is
|
||||
* then less by one. Returns -1 if there is no formula. If
|
||||
* there are derivatives of the last formula, they are
|
||||
* destroyed and the vector ders is popped from the back. */
|
||||
int pop_last_formula();
|
||||
|
||||
/** This returns a tree index of the last formula and pops its
|
||||
* item from the formulas vector. The number of formulas is
|
||||
* then less by one. Returns -1 if there is no formula. If
|
||||
* there are derivatives of the last formula, they are
|
||||
* destroyed and the vector ders is popped from the back. */
|
||||
int pop_last_formula();
|
||||
/** This returns a number of formulas. */
|
||||
int
|
||||
nformulas() const
|
||||
{
|
||||
return (int) (formulas.size());
|
||||
}
|
||||
|
||||
/** This returns a number of formulas. */
|
||||
int nformulas() const
|
||||
{return (int)(formulas.size());}
|
||||
/** This returns a reference to atoms. */
|
||||
const Atoms &
|
||||
getAtoms() const
|
||||
{
|
||||
return atoms;
|
||||
}
|
||||
Atoms &
|
||||
getAtoms()
|
||||
{
|
||||
return atoms;
|
||||
}
|
||||
/** This returns the tree. */
|
||||
const OperationTree &
|
||||
getTree() const
|
||||
{
|
||||
return otree;
|
||||
}
|
||||
OperationTree &
|
||||
getTree()
|
||||
{
|
||||
return otree;
|
||||
}
|
||||
|
||||
/** This returns a reference to atoms. */
|
||||
const Atoms& getAtoms() const
|
||||
{return atoms;}
|
||||
Atoms& getAtoms()
|
||||
{return atoms;}
|
||||
/** This returns the tree. */
|
||||
const OperationTree& getTree() const
|
||||
{return otree;}
|
||||
OperationTree& getTree()
|
||||
{return otree;}
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
private:
|
||||
/** Hide this copy constructor declaration by declaring it as
|
||||
* private. */
|
||||
FormulaParser(const FormulaParser &fp);
|
||||
/** Destroy all derivatives. */
|
||||
void destroy_derivatives();
|
||||
};
|
||||
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
private:
|
||||
/** Hide this copy constructor declaration by declaring it as
|
||||
* private. */
|
||||
FormulaParser(const FormulaParser& fp);
|
||||
/** Destroy all derivatives. */
|
||||
void destroy_derivatives();
|
||||
};
|
||||
/** This is a pure virtual class defining an interface for all
|
||||
* classes which will load the results of formula (zero
|
||||
* derivative) evaluations. A primitive implementation of this
|
||||
* class can be a vector of doubles. */
|
||||
class FormulaEvalLoader
|
||||
{
|
||||
public:
|
||||
virtual ~FormulaEvalLoader()
|
||||
{
|
||||
}
|
||||
/** Set the value res for the given formula. The formula is
|
||||
* identified by an index corresponding to the ordering in
|
||||
* which the formulas have been parsed (starting from
|
||||
* zero). */
|
||||
virtual void load(int i, double res) = 0;
|
||||
};
|
||||
|
||||
/** This is a pure virtual class defining an interface for all
|
||||
* classes which will load the results of formula (zero
|
||||
* derivative) evaluations. A primitive implementation of this
|
||||
* class can be a vector of doubles. */
|
||||
class FormulaEvalLoader {
|
||||
public:
|
||||
virtual ~FormulaEvalLoader() {}
|
||||
/** Set the value res for the given formula. The formula is
|
||||
* identified by an index corresponding to the ordering in
|
||||
* which the formulas have been parsed (starting from
|
||||
* zero). */
|
||||
virtual void load(int i, double res) = 0;
|
||||
};
|
||||
/** This class evaluates a selected subset of terms of the
|
||||
* tree. In the protected constructor, one can constraint the
|
||||
* initialization of the evaluation tree to a given number of
|
||||
* terms in the beginning. Using this constructor, one has to make
|
||||
* sure, that the terms in the beginning do not refer to terms
|
||||
* behind the initial part. */
|
||||
class FormulaCustomEvaluator
|
||||
{
|
||||
protected:
|
||||
/** The evaluation tree. */
|
||||
EvalTree etree;
|
||||
/** The custom tree indices to be evaluated. */
|
||||
vector<int> terms;
|
||||
public:
|
||||
/** Construct from FormulaParser and given list of terms. */
|
||||
FormulaCustomEvaluator(const FormulaParser &fp, const vector<int> &ts)
|
||||
: etree(fp.otree), terms(ts)
|
||||
{
|
||||
}
|
||||
/** Construct from OperationTree and given list of terms. */
|
||||
FormulaCustomEvaluator(const OperationTree &ot, const vector<int> &ts)
|
||||
: etree(ot), terms(ts)
|
||||
{
|
||||
}
|
||||
/** Evaluate the terms using the given AtomValues and load the
|
||||
* results using the given loader. The loader is called for
|
||||
* each term in the order of the terms. */
|
||||
void eval(const AtomValues &av, FormulaEvalLoader &loader);
|
||||
protected:
|
||||
FormulaCustomEvaluator(const FormulaParser &fp)
|
||||
: etree(fp.otree, fp.last_formula()), terms(fp.formulas)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/** This class evaluates a selected subset of terms of the
|
||||
* tree. In the protected constructor, one can constraint the
|
||||
* initialization of the evaluation tree to a given number of
|
||||
* terms in the beginning. Using this constructor, one has to make
|
||||
* sure, that the terms in the beginning do not refer to terms
|
||||
* behind the initial part. */
|
||||
class FormulaCustomEvaluator {
|
||||
protected:
|
||||
/** The evaluation tree. */
|
||||
EvalTree etree;
|
||||
/** The custom tree indices to be evaluated. */
|
||||
vector<int> terms;
|
||||
public:
|
||||
/** Construct from FormulaParser and given list of terms. */
|
||||
FormulaCustomEvaluator(const FormulaParser& fp, const vector<int>& ts)
|
||||
: etree(fp.otree), terms(ts)
|
||||
{}
|
||||
/** Construct from OperationTree and given list of terms. */
|
||||
FormulaCustomEvaluator(const OperationTree& ot, const vector<int>& ts)
|
||||
: etree(ot), terms(ts)
|
||||
{}
|
||||
/** Evaluate the terms using the given AtomValues and load the
|
||||
* results using the given loader. The loader is called for
|
||||
* each term in the order of the terms. */
|
||||
void eval(const AtomValues& av, FormulaEvalLoader& loader);
|
||||
protected:
|
||||
FormulaCustomEvaluator(const FormulaParser& fp)
|
||||
: etree(fp.otree, fp.last_formula()), terms(fp.formulas)
|
||||
{}
|
||||
};
|
||||
/** This class evaluates zero derivatives of the FormulaParser. */
|
||||
class FormulaEvaluator : public FormulaCustomEvaluator
|
||||
{
|
||||
public:
|
||||
/** Construct from FormulaParser. */
|
||||
FormulaEvaluator(const FormulaParser &fp)
|
||||
: FormulaCustomEvaluator(fp)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/** This class evaluates zero derivatives of the FormulaParser. */
|
||||
class FormulaEvaluator : public FormulaCustomEvaluator {
|
||||
public:
|
||||
/** Construct from FormulaParser. */
|
||||
FormulaEvaluator(const FormulaParser& fp)
|
||||
: FormulaCustomEvaluator(fp) {}
|
||||
};
|
||||
/** This is a pure virtual class defining an interface for all
|
||||
* classes which will load the results of formula derivative
|
||||
* evaluations. */
|
||||
class FormulaDerEvalLoader
|
||||
{
|
||||
public:
|
||||
virtual ~FormulaDerEvalLoader()
|
||||
{
|
||||
}
|
||||
/** This loads the result of the derivative of the given
|
||||
* order. The semantics of i is the same as in
|
||||
* FormulaEvalLoader::load. The indices of variables with
|
||||
* respect to which the derivative was taken are stored in
|
||||
* memory pointed by vars. These are the tree indices of the
|
||||
* variables. */
|
||||
virtual void load(int i, int order, const int *vars, double res) = 0;
|
||||
};
|
||||
|
||||
/** This is a pure virtual class defining an interface for all
|
||||
* classes which will load the results of formula derivative
|
||||
* evaluations. */
|
||||
class FormulaDerEvalLoader {
|
||||
public:
|
||||
virtual ~FormulaDerEvalLoader() {}
|
||||
/** This loads the result of the derivative of the given
|
||||
* order. The semantics of i is the same as in
|
||||
* FormulaEvalLoader::load. The indices of variables with
|
||||
* respect to which the derivative was taken are stored in
|
||||
* memory pointed by vars. These are the tree indices of the
|
||||
* variables. */
|
||||
virtual void load(int i, int order, const int* vars, double res) = 0;
|
||||
};
|
||||
/** This class is a utility class representing the tensor
|
||||
* multindex. It can basically increment itself, and calculate
|
||||
* its offset in the folded tensor. */
|
||||
class FoldMultiIndex
|
||||
{
|
||||
/** Number of variables. */
|
||||
int nvar;
|
||||
/** Dimension. */
|
||||
int ord;
|
||||
/** The multiindex. */
|
||||
int *data;
|
||||
public:
|
||||
/** Initializes to the zero derivative. Order is 0, data is
|
||||
* empty. */
|
||||
FoldMultiIndex(int nv);
|
||||
/** Initializes the multiindex to zeros or given i. */
|
||||
FoldMultiIndex(int nv, int order, int i = 0);
|
||||
/** Makes a new multiindex of the same order applying a given
|
||||
* mapping to the indices. The mapping is supposed to be monotone. */
|
||||
FoldMultiIndex(int nv, const FoldMultiIndex &mi, const vector<int> &mp);
|
||||
/** Shifting constructor. This adds a given number of orders
|
||||
* to the end, copying the last item to the newly added items,
|
||||
* keeping the index ordered. If the index was empty (zero-th
|
||||
* dimension), then zeros are added. */
|
||||
FoldMultiIndex(const FoldMultiIndex &fmi, int new_orders);
|
||||
/** Copy constructor. */
|
||||
FoldMultiIndex(const FoldMultiIndex &fmi);
|
||||
/** Desctructor. */
|
||||
virtual ~FoldMultiIndex()
|
||||
{
|
||||
delete [] data;
|
||||
}
|
||||
/** Assignment operator. */
|
||||
const FoldMultiIndex &operator=(const FoldMultiIndex &fmi);
|
||||
/** Operator < implementing lexicographic ordering within one
|
||||
* order, increasing order across orders. */
|
||||
bool operator<(const FoldMultiIndex &fmi) const;
|
||||
bool operator==(const FoldMultiIndex &fmi) const;
|
||||
/** Increment the multiindex. */
|
||||
void increment();
|
||||
/** Return offset of the multiindex in the folded tensor. */
|
||||
int offset() const;
|
||||
const int &
|
||||
operator[](int i) const
|
||||
{
|
||||
return data[i];
|
||||
}
|
||||
/** Return order of the multiindex, i.e. dimension of the
|
||||
* tensor. */
|
||||
int
|
||||
order() const
|
||||
{
|
||||
return ord;
|
||||
}
|
||||
/** Return the number of variables. */
|
||||
int
|
||||
nv() const
|
||||
{
|
||||
return nvar;
|
||||
}
|
||||
/** Return the data. */
|
||||
const int *
|
||||
ind() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
/** Return true if the end of the tensor is reached. The
|
||||
* result of a subsequent increment should be considered
|
||||
* unpredictable. */
|
||||
bool
|
||||
past_the_end() const
|
||||
{
|
||||
return (ord == 0) || (data[0] == nvar);
|
||||
}
|
||||
/** Prints the multiindex in the brackets. */
|
||||
void print() const;
|
||||
private:
|
||||
static int offset_recurse(int *data, int len, int nv);
|
||||
};
|
||||
|
||||
/** This class is a utility class representing the tensor
|
||||
* multindex. It can basically increment itself, and calculate
|
||||
* its offset in the folded tensor. */
|
||||
class FoldMultiIndex {
|
||||
/** Number of variables. */
|
||||
int nvar;
|
||||
/** Dimension. */
|
||||
int ord;
|
||||
/** The multiindex. */
|
||||
int* data;
|
||||
public:
|
||||
/** Initializes to the zero derivative. Order is 0, data is
|
||||
* empty. */
|
||||
FoldMultiIndex(int nv);
|
||||
/** Initializes the multiindex to zeros or given i. */
|
||||
FoldMultiIndex(int nv, int order, int i = 0);
|
||||
/** Makes a new multiindex of the same order applying a given
|
||||
* mapping to the indices. The mapping is supposed to be monotone. */
|
||||
FoldMultiIndex(int nv, const FoldMultiIndex& mi, const vector<int>& mp);
|
||||
/** Shifting constructor. This adds a given number of orders
|
||||
* to the end, copying the last item to the newly added items,
|
||||
* keeping the index ordered. If the index was empty (zero-th
|
||||
* dimension), then zeros are added. */
|
||||
FoldMultiIndex(const FoldMultiIndex& fmi, int new_orders);
|
||||
/** Copy constructor. */
|
||||
FoldMultiIndex(const FoldMultiIndex& fmi);
|
||||
/** Desctructor. */
|
||||
virtual ~FoldMultiIndex()
|
||||
{delete [] data;}
|
||||
/** Assignment operator. */
|
||||
const FoldMultiIndex& operator=(const FoldMultiIndex& fmi);
|
||||
/** Operator < implementing lexicographic ordering within one
|
||||
* order, increasing order across orders. */
|
||||
bool operator<(const FoldMultiIndex& fmi) const;
|
||||
bool operator==(const FoldMultiIndex& fmi) const;
|
||||
/** Increment the multiindex. */
|
||||
void increment();
|
||||
/** Return offset of the multiindex in the folded tensor. */
|
||||
int offset() const;
|
||||
const int& operator[](int i) const
|
||||
{return data[i];}
|
||||
/** Return order of the multiindex, i.e. dimension of the
|
||||
* tensor. */
|
||||
int order() const
|
||||
{return ord;}
|
||||
/** Return the number of variables. */
|
||||
int nv() const
|
||||
{return nvar;}
|
||||
/** Return the data. */
|
||||
const int* ind() const
|
||||
{return data;}
|
||||
/** Return true if the end of the tensor is reached. The
|
||||
* result of a subsequent increment should be considered
|
||||
* unpredictable. */
|
||||
bool past_the_end() const
|
||||
{return (ord == 0) || (data[0] == nvar);}
|
||||
/** Prints the multiindex in the brackets. */
|
||||
void print() const;
|
||||
private:
|
||||
static int offset_recurse(int* data, int len, int nv);
|
||||
};
|
||||
|
||||
/** This class evaluates derivatives of the FormulaParser. */
|
||||
class FormulaDerEvaluator {
|
||||
/** Its own instance of EvalTree. */
|
||||
EvalTree etree;
|
||||
/** The indices of derivatives for each formula. This is a
|
||||
* const copy FormulaParser::ders. We do not allocate nor
|
||||
* deallocate anything here. */
|
||||
vector<const FormulaDerivatives*> ders;
|
||||
/** A copy of tree indices corresponding to atoms to with
|
||||
* respect the derivatives were taken. */
|
||||
vector<int> der_atoms;
|
||||
public:
|
||||
/** Construct the object from FormulaParser. */
|
||||
FormulaDerEvaluator(const FormulaParser& fp);
|
||||
/** Evaluate the derivatives from the FormulaParser wrt to all
|
||||
* atoms in variables vector at the given AtomValues. The
|
||||
* given loader is used for output. */
|
||||
void eval(const AtomValues& av, FormulaDerEvalLoader& loader, int order);
|
||||
/** Evaluate the derivatives from the FormulaParser wrt to a
|
||||
* selection of atoms of the atoms in der_atoms vector at the
|
||||
* given AtomValues. The selection is given by a monotone
|
||||
* mapping to the indices (not values) of the der_atoms. */
|
||||
void eval(const vector<int>& mp, const AtomValues& av, FormulaDerEvalLoader& loader,
|
||||
int order);
|
||||
};
|
||||
/** This class evaluates derivatives of the FormulaParser. */
|
||||
class FormulaDerEvaluator
|
||||
{
|
||||
/** Its own instance of EvalTree. */
|
||||
EvalTree etree;
|
||||
/** The indices of derivatives for each formula. This is a
|
||||
* const copy FormulaParser::ders. We do not allocate nor
|
||||
* deallocate anything here. */
|
||||
vector<const FormulaDerivatives *> ders;
|
||||
/** A copy of tree indices corresponding to atoms to with
|
||||
* respect the derivatives were taken. */
|
||||
vector<int> der_atoms;
|
||||
public:
|
||||
/** Construct the object from FormulaParser. */
|
||||
FormulaDerEvaluator(const FormulaParser &fp);
|
||||
/** Evaluate the derivatives from the FormulaParser wrt to all
|
||||
* atoms in variables vector at the given AtomValues. The
|
||||
* given loader is used for output. */
|
||||
void eval(const AtomValues &av, FormulaDerEvalLoader &loader, int order);
|
||||
/** Evaluate the derivatives from the FormulaParser wrt to a
|
||||
* selection of atoms of the atoms in der_atoms vector at the
|
||||
* given AtomValues. The selection is given by a monotone
|
||||
* mapping to the indices (not values) of the der_atoms. */
|
||||
void eval(const vector<int> &mp, const AtomValues &av, FormulaDerEvalLoader &loader,
|
||||
int order);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,29 +15,32 @@
|
|||
// in EVERY action consuming material (this can be done with #define
|
||||
// YY_USER_ACTION) and in bison you must use option %locations.
|
||||
|
||||
|
||||
#ifndef OG_LOCATION_H
|
||||
#define OG_LOCATION_H
|
||||
|
||||
namespace ogp {
|
||||
namespace ogp
|
||||
{
|
||||
|
||||
struct location_type {
|
||||
int off; // offset of the token
|
||||
int ll; // length ot the token
|
||||
location_type() : off(0), ll(0) {}
|
||||
};
|
||||
struct location_type
|
||||
{
|
||||
int off; // offset of the token
|
||||
int ll; // length ot the token
|
||||
location_type() : off(0), ll(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#define YYLTYPE ogp::location_type
|
||||
|
||||
// set current off to the first off and add all lengths
|
||||
#define YYLLOC_DEFAULT(Current, Rhs, N) \
|
||||
{(Current).off = (Rhs)[1].off; \
|
||||
(Current).ll = 0; \
|
||||
for (int i = 1; i <= N; i++) (Current).ll += (Rhs)[i].ll;}
|
||||
#define YYLLOC_DEFAULT(Current, Rhs, N) \
|
||||
{(Current).off = (Rhs)[1].off; \
|
||||
(Current).ll = 0; \
|
||||
for (int i = 1; i <= N; i++) (Current).ll += (Rhs)[i].ll; }
|
||||
|
||||
#define SET_LLOC(prefix) (prefix##lloc.off += prefix##lloc.ll, prefix##lloc.ll = prefix##leng)
|
||||
#define SET_LLOC(prefix) (prefix ## lloc.off += prefix ## lloc.ll, prefix ## lloc.ll = prefix ## leng)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -8,110 +8,143 @@
|
|||
#include <cstdlib> // For NULL
|
||||
#include <vector>
|
||||
|
||||
namespace ogp {
|
||||
using std::vector;
|
||||
namespace ogp
|
||||
{
|
||||
using std::vector;
|
||||
|
||||
/** This class reads the given string and parses it as a
|
||||
* matrix. The matrix is read row by row. The row delimiter is
|
||||
* either a newline character or semicolon (first newline
|
||||
* character after the semicolon is ignored), the column delimiter
|
||||
* is either blank character or comma. A different number of items
|
||||
* in the row is not reconciliated, we do not construct a matrix
|
||||
* here. The class provides only an iterator to go through all
|
||||
* read items, the iterator provides information on row number and
|
||||
* column number of the item. */
|
||||
class MPIterator;
|
||||
class MatrixParser {
|
||||
friend class MPIterator;
|
||||
protected:
|
||||
/** Raw data as they were read. */
|
||||
vector<double> data;
|
||||
/** Number of items in each row. */
|
||||
vector<int> row_lengths;
|
||||
/** Maximum number of row lengths. */
|
||||
int nc;
|
||||
public:
|
||||
MatrixParser()
|
||||
: nc(0) {}
|
||||
MatrixParser(const MatrixParser& mp)
|
||||
: data(mp.data), row_lengths(mp.row_lengths), nc(mp.nc) {}
|
||||
virtual ~MatrixParser() {}
|
||||
/** Return a number of read rows. */
|
||||
int nrows() const
|
||||
{return (int) row_lengths.size();}
|
||||
/** Return a maximum number of items in the rows. */
|
||||
int ncols() const
|
||||
{return nc;}
|
||||
/** Parses a given data. This initializes the object data. */
|
||||
void parse(int length, const char* stream);
|
||||
/** Adds newly read item. This should be called from bison
|
||||
* parser. */
|
||||
void add_item(double v);
|
||||
/** Starts a new row. This should be called from bison
|
||||
* parser. */
|
||||
void start_row();
|
||||
/** Process a parse error from the parser. */
|
||||
void error(const char* mes) const;
|
||||
/** Return begin iterator. */
|
||||
MPIterator begin() const;
|
||||
/** Return end iterator. */
|
||||
MPIterator end() const;
|
||||
protected:
|
||||
/** Returns an index of the first non-empty row starting at
|
||||
* start. If the start row is non-empty, returns the start. If
|
||||
* there is no other non-empty row, returns
|
||||
* row_lengths.size(). */
|
||||
int find_first_non_empty_row(int start = 0) const;
|
||||
};
|
||||
/** This class reads the given string and parses it as a
|
||||
* matrix. The matrix is read row by row. The row delimiter is
|
||||
* either a newline character or semicolon (first newline
|
||||
* character after the semicolon is ignored), the column delimiter
|
||||
* is either blank character or comma. A different number of items
|
||||
* in the row is not reconciliated, we do not construct a matrix
|
||||
* here. The class provides only an iterator to go through all
|
||||
* read items, the iterator provides information on row number and
|
||||
* column number of the item. */
|
||||
class MPIterator;
|
||||
class MatrixParser
|
||||
{
|
||||
friend class MPIterator;
|
||||
protected:
|
||||
/** Raw data as they were read. */
|
||||
vector<double> data;
|
||||
/** Number of items in each row. */
|
||||
vector<int> row_lengths;
|
||||
/** Maximum number of row lengths. */
|
||||
int nc;
|
||||
public:
|
||||
MatrixParser()
|
||||
: nc(0)
|
||||
{
|
||||
}
|
||||
MatrixParser(const MatrixParser &mp)
|
||||
: data(mp.data), row_lengths(mp.row_lengths), nc(mp.nc)
|
||||
{
|
||||
}
|
||||
virtual ~MatrixParser()
|
||||
{
|
||||
}
|
||||
/** Return a number of read rows. */
|
||||
int
|
||||
nrows() const
|
||||
{
|
||||
return (int) row_lengths.size();
|
||||
}
|
||||
/** Return a maximum number of items in the rows. */
|
||||
int
|
||||
ncols() const
|
||||
{
|
||||
return nc;
|
||||
}
|
||||
/** Parses a given data. This initializes the object data. */
|
||||
void parse(int length, const char *stream);
|
||||
/** Adds newly read item. This should be called from bison
|
||||
* parser. */
|
||||
void add_item(double v);
|
||||
/** Starts a new row. This should be called from bison
|
||||
* parser. */
|
||||
void start_row();
|
||||
/** Process a parse error from the parser. */
|
||||
void error(const char *mes) const;
|
||||
/** Return begin iterator. */
|
||||
MPIterator begin() const;
|
||||
/** Return end iterator. */
|
||||
MPIterator end() const;
|
||||
protected:
|
||||
/** Returns an index of the first non-empty row starting at
|
||||
* start. If the start row is non-empty, returns the start. If
|
||||
* there is no other non-empty row, returns
|
||||
* row_lengths.size(). */
|
||||
int find_first_non_empty_row(int start = 0) const;
|
||||
};
|
||||
|
||||
/** This is an iterator intended to iterate through a matrix parsed
|
||||
* by MatrixParser. The iterator provides only read-only access. */
|
||||
class MPIterator {
|
||||
friend class MatrixParser;
|
||||
protected:
|
||||
/** Reference to the matrix parser. */
|
||||
const MatrixParser* p;
|
||||
/** The index of the pointed item in the matrix parser. */
|
||||
unsigned int i;
|
||||
/** The column number of the pointed item starting from zero. */
|
||||
int c;
|
||||
/** The row number of the pointed item starting from zero. */
|
||||
int r;
|
||||
/** This is an iterator intended to iterate through a matrix parsed
|
||||
* by MatrixParser. The iterator provides only read-only access. */
|
||||
class MPIterator
|
||||
{
|
||||
friend class MatrixParser;
|
||||
protected:
|
||||
/** Reference to the matrix parser. */
|
||||
const MatrixParser *p;
|
||||
/** The index of the pointed item in the matrix parser. */
|
||||
unsigned int i;
|
||||
/** The column number of the pointed item starting from zero. */
|
||||
int c;
|
||||
/** The row number of the pointed item starting from zero. */
|
||||
int r;
|
||||
|
||||
public:
|
||||
MPIterator() : p(NULL), i(0), c(0), r(0) {}
|
||||
/** Constructs an iterator pointing to the beginning of the
|
||||
* parsed matrix. */
|
||||
MPIterator(const MatrixParser& mp);
|
||||
/** Constructs an iterator pointing to the past-the-end of the
|
||||
* parsed matrix. */
|
||||
MPIterator(const MatrixParser& mp, const char* dummy);
|
||||
/** Return read-only reference to the pointed item. */
|
||||
const double& operator*() const
|
||||
{return p->data[i];}
|
||||
/** Return a row index of the pointed item. */
|
||||
int row() const
|
||||
{return r;}
|
||||
/** Return a column index of the pointed item. */
|
||||
int col() const
|
||||
{return c;}
|
||||
/** Assignment operator. */
|
||||
const MPIterator& operator=(const MPIterator& it)
|
||||
{p = it.p; i = it.i; c = it.c; r = it.r; return *this;}
|
||||
/** Return true if the iterators are the same, this is if they
|
||||
* have the same underlying object and the same item index. */
|
||||
bool operator==(const MPIterator& it) const
|
||||
{return it.p == p && it.i == i;}
|
||||
/** Negative of the operator==. */
|
||||
bool operator!=(const MPIterator& it) const
|
||||
{return ! (it == *this);}
|
||||
/** Increment operator. */
|
||||
MPIterator& operator++();
|
||||
};
|
||||
public:
|
||||
MPIterator() : p(NULL), i(0), c(0), r(0)
|
||||
{
|
||||
}
|
||||
/** Constructs an iterator pointing to the beginning of the
|
||||
* parsed matrix. */
|
||||
MPIterator(const MatrixParser &mp);
|
||||
/** Constructs an iterator pointing to the past-the-end of the
|
||||
* parsed matrix. */
|
||||
MPIterator(const MatrixParser &mp, const char *dummy);
|
||||
/** Return read-only reference to the pointed item. */
|
||||
const double &
|
||||
operator*() const
|
||||
{
|
||||
return p->data[i];
|
||||
}
|
||||
/** Return a row index of the pointed item. */
|
||||
int
|
||||
row() const
|
||||
{
|
||||
return r;
|
||||
}
|
||||
/** Return a column index of the pointed item. */
|
||||
int
|
||||
col() const
|
||||
{
|
||||
return c;
|
||||
}
|
||||
/** Assignment operator. */
|
||||
const MPIterator &
|
||||
operator=(const MPIterator &it)
|
||||
{
|
||||
p = it.p; i = it.i; c = it.c; r = it.r; return *this;
|
||||
}
|
||||
/** Return true if the iterators are the same, this is if they
|
||||
* have the same underlying object and the same item index. */
|
||||
bool
|
||||
operator==(const MPIterator &it) const
|
||||
{
|
||||
return it.p == p && it.i == i;
|
||||
}
|
||||
/** Negative of the operator==. */
|
||||
bool
|
||||
operator!=(const MPIterator &it) const
|
||||
{
|
||||
return !(it == *this);
|
||||
}
|
||||
/** Increment operator. */
|
||||
MPIterator &operator++();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -5,24 +5,28 @@
|
|||
#ifndef OGP_NAMELIST
|
||||
#define OGP_NAMELIST
|
||||
|
||||
namespace ogp {
|
||||
namespace ogp
|
||||
{
|
||||
|
||||
/** Parent class of all parsers parsing a namelist. They must
|
||||
* implement add_name() method and error() method, which is called
|
||||
* when an parse error occurs.
|
||||
*
|
||||
* Parsing a name list is done as follows: implement
|
||||
* NameListParser interface, create the object, and call
|
||||
* NameListParser::namelist_parse(int lengt, const char*
|
||||
* text). When implementing error(), one may consult global
|
||||
* location_type namelist_lloc. */
|
||||
class NameListParser {
|
||||
public:
|
||||
virtual ~NameListParser() {}
|
||||
virtual void add_name(const char* name) = 0;
|
||||
virtual void namelist_error(const char* mes) = 0;
|
||||
void namelist_parse(int length, const char* text);
|
||||
};
|
||||
/** Parent class of all parsers parsing a namelist. They must
|
||||
* implement add_name() method and error() method, which is called
|
||||
* when an parse error occurs.
|
||||
*
|
||||
* Parsing a name list is done as follows: implement
|
||||
* NameListParser interface, create the object, and call
|
||||
* NameListParser::namelist_parse(int lengt, const char*
|
||||
* text). When implementing error(), one may consult global
|
||||
* location_type namelist_lloc. */
|
||||
class NameListParser
|
||||
{
|
||||
public:
|
||||
virtual ~NameListParser()
|
||||
{
|
||||
}
|
||||
virtual void add_name(const char *name) = 0;
|
||||
virtual void namelist_error(const char *mes) = 0;
|
||||
void namelist_parse(int length, const char *text);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,61 +7,88 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
namespace ogp {
|
||||
using std::string;
|
||||
namespace ogp
|
||||
{
|
||||
using std::string;
|
||||
|
||||
/** This is an easy exception, which, besides the message, stores
|
||||
* also an offset of the parse error. Since we might need to track
|
||||
* the argument number and for example the filed in the argument
|
||||
* which caused the error, we add three integers, which have no
|
||||
* semantics here. They should be documented in the function which
|
||||
* throws an exception and sets them. Their default value is -1,
|
||||
* which means they have not been set. */
|
||||
class ParserException {
|
||||
protected:
|
||||
char* mes;
|
||||
int off;
|
||||
int aux_i1;
|
||||
int aux_i2;
|
||||
int aux_i3;
|
||||
public:
|
||||
ParserException(const char* m, int offset);
|
||||
ParserException(const string& m, int offset);
|
||||
ParserException(const string& m, const char* dum, int i1);
|
||||
ParserException(const string& m, const char* dum, int i1, int i2);
|
||||
ParserException(const string& m, const char* dum, int i1, int i2, int i3);
|
||||
ParserException(const ParserException& e, int plus_offset);
|
||||
/** Makes a copy and pushes given integer to aux_i1 shuffling
|
||||
* others and forgetting the last. */
|
||||
ParserException(const ParserException& e, const char* dum, int i);
|
||||
/** Makes a copy and pushes given two integers to aux_i1 and aux_i2 shuffling
|
||||
* others and forgetting the last two. */
|
||||
ParserException(const ParserException& e, const char* dum, int i1, int i2);
|
||||
/** Makes a copy and pushes given three integers to aux_i1, aux_i2, aus_i3 shuffling
|
||||
* others and forgetting the last three. */
|
||||
ParserException(const ParserException& e, const char* dum, int i1, int i2, int i3);
|
||||
ParserException(const ParserException& e);
|
||||
virtual ~ParserException();
|
||||
void print(FILE* fd) const;
|
||||
const char* message() const
|
||||
{return mes;}
|
||||
int offset() const
|
||||
{return off;}
|
||||
const int& i1() const
|
||||
{return aux_i1;}
|
||||
int& i1()
|
||||
{return aux_i1;}
|
||||
const int& i2() const
|
||||
{return aux_i2;}
|
||||
int& i2()
|
||||
{return aux_i2;}
|
||||
const int& i3() const
|
||||
{return aux_i3;}
|
||||
int& i3()
|
||||
{return aux_i3;}
|
||||
protected:
|
||||
void copy(const ParserException& e);
|
||||
};
|
||||
/** This is an easy exception, which, besides the message, stores
|
||||
* also an offset of the parse error. Since we might need to track
|
||||
* the argument number and for example the filed in the argument
|
||||
* which caused the error, we add three integers, which have no
|
||||
* semantics here. They should be documented in the function which
|
||||
* throws an exception and sets them. Their default value is -1,
|
||||
* which means they have not been set. */
|
||||
class ParserException
|
||||
{
|
||||
protected:
|
||||
char *mes;
|
||||
int off;
|
||||
int aux_i1;
|
||||
int aux_i2;
|
||||
int aux_i3;
|
||||
public:
|
||||
ParserException(const char *m, int offset);
|
||||
ParserException(const string &m, int offset);
|
||||
ParserException(const string &m, const char *dum, int i1);
|
||||
ParserException(const string &m, const char *dum, int i1, int i2);
|
||||
ParserException(const string &m, const char *dum, int i1, int i2, int i3);
|
||||
ParserException(const ParserException &e, int plus_offset);
|
||||
/** Makes a copy and pushes given integer to aux_i1 shuffling
|
||||
* others and forgetting the last. */
|
||||
ParserException(const ParserException &e, const char *dum, int i);
|
||||
/** Makes a copy and pushes given two integers to aux_i1 and aux_i2 shuffling
|
||||
* others and forgetting the last two. */
|
||||
ParserException(const ParserException &e, const char *dum, int i1, int i2);
|
||||
/** Makes a copy and pushes given three integers to aux_i1, aux_i2, aus_i3 shuffling
|
||||
* others and forgetting the last three. */
|
||||
ParserException(const ParserException &e, const char *dum, int i1, int i2, int i3);
|
||||
ParserException(const ParserException &e);
|
||||
virtual
|
||||
~ParserException();
|
||||
void print(FILE *fd) const;
|
||||
const char *
|
||||
message() const
|
||||
{
|
||||
return mes;
|
||||
}
|
||||
int
|
||||
offset() const
|
||||
{
|
||||
return off;
|
||||
}
|
||||
const int &
|
||||
i1() const
|
||||
{
|
||||
return aux_i1;
|
||||
}
|
||||
int &
|
||||
i1()
|
||||
{
|
||||
return aux_i1;
|
||||
}
|
||||
const int &
|
||||
i2() const
|
||||
{
|
||||
return aux_i2;
|
||||
}
|
||||
int &
|
||||
i2()
|
||||
{
|
||||
return aux_i2;
|
||||
}
|
||||
const int &
|
||||
i3() const
|
||||
{
|
||||
return aux_i3;
|
||||
}
|
||||
int &
|
||||
i3()
|
||||
{
|
||||
return aux_i3;
|
||||
}
|
||||
protected:
|
||||
void copy(const ParserException &e);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,79 +7,95 @@
|
|||
|
||||
#include "dynamic_atoms.h"
|
||||
|
||||
namespace ogp {
|
||||
namespace ogp
|
||||
{
|
||||
|
||||
class StaticAtoms : public Atoms, public Constants {
|
||||
protected:
|
||||
typedef map<const char*, int, ltstr> Tvarmap;
|
||||
typedef map<int, const char*> Tinvmap;
|
||||
/** Storage for names. */
|
||||
NameStorage varnames;
|
||||
/** Outer order of variables. */
|
||||
vector<const char*> varorder;
|
||||
/** This is the map mapping a variable name to the tree
|
||||
* index. */
|
||||
Tvarmap vars;
|
||||
/** This is the inverse mapping. It maps a tree index to the
|
||||
* variable name. */
|
||||
Tinvmap indices;
|
||||
public:
|
||||
StaticAtoms() : Atoms(), Constants(), varnames(), varorder(), vars()
|
||||
{}
|
||||
/* Copy constructor. */
|
||||
StaticAtoms(const StaticAtoms& a);
|
||||
/** Conversion from DynamicAtoms. This takes all atoms from
|
||||
* the DynamicAtoms and adds its static version. The new tree
|
||||
* indices are allocated in the passed OperationTree. Whole
|
||||
* the process is traced in the map mapping old tree indices
|
||||
* to new tree indices. */
|
||||
StaticAtoms(const DynamicAtoms& da, OperationTree& otree, Tintintmap& tmap)
|
||||
: Atoms(), Constants(), varnames(), varorder(), vars()
|
||||
{import_atoms(da, otree, tmap);}
|
||||
/* Destructor. */
|
||||
virtual ~StaticAtoms() {}
|
||||
/** This imports atoms from dynamic atoms inserting the new
|
||||
* tree indices to the given tree (including constants). The
|
||||
* mapping from old atoms to new atoms is traced in tmap. */
|
||||
void import_atoms(const DynamicAtoms& da, OperationTree& otree,
|
||||
Tintintmap& tmap);
|
||||
/** If the name is constant, it returns its tree index if the
|
||||
* constant is registered in Constants, it returns -1
|
||||
* otherwise. If the name is not constant, it returns result
|
||||
* from check_variable, which is implemented by a subclass. */
|
||||
int check(const char* name) const;
|
||||
/** This assigns a given tree index to the variable name. The
|
||||
* name should have been checked before the call. */
|
||||
void assign(const char* name, int t);
|
||||
int nvar() const
|
||||
{return varnames.num();}
|
||||
/** This returns a vector of all variables. */
|
||||
vector<int> variables() const;
|
||||
/** This returns a tree index of the given variable. */
|
||||
int index(const char* name) const;
|
||||
/** This returns a name from the given tree index. NULL is
|
||||
* returned if the tree index doesn't exist. */
|
||||
const char* inv_index(int t) const;
|
||||
/** This returns a name in a outer ordering. (There is no other ordering.) */
|
||||
const char* name(int i) const
|
||||
{return varorder[i];}
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
/** This registers a variable. A subclass can reimplement
|
||||
* this, for example, to ensure uniqueness of the
|
||||
* name. However, this method should be always called in
|
||||
* overriding methods to do the registering job. */
|
||||
virtual void register_name(const char* name);
|
||||
/** Return the name storage to allow querying to other
|
||||
* classes. */
|
||||
const NameStorage& get_name_storage() const
|
||||
{return varnames;}
|
||||
protected:
|
||||
/** This checks the variable. The implementing subclass might
|
||||
* want to throw an exception if the variable has not been
|
||||
* registered. */
|
||||
virtual int check_variable(const char* name) const = 0;
|
||||
};
|
||||
class StaticAtoms : public Atoms, public Constants
|
||||
{
|
||||
protected:
|
||||
typedef map<const char *, int, ltstr> Tvarmap;
|
||||
typedef map<int, const char *> Tinvmap;
|
||||
/** Storage for names. */
|
||||
NameStorage varnames;
|
||||
/** Outer order of variables. */
|
||||
vector<const char *> varorder;
|
||||
/** This is the map mapping a variable name to the tree
|
||||
* index. */
|
||||
Tvarmap vars;
|
||||
/** This is the inverse mapping. It maps a tree index to the
|
||||
* variable name. */
|
||||
Tinvmap indices;
|
||||
public:
|
||||
StaticAtoms() : Atoms(), Constants(), varnames(), varorder(), vars()
|
||||
{
|
||||
}
|
||||
/* Copy constructor. */
|
||||
StaticAtoms(const StaticAtoms &a);
|
||||
/** Conversion from DynamicAtoms. This takes all atoms from
|
||||
* the DynamicAtoms and adds its static version. The new tree
|
||||
* indices are allocated in the passed OperationTree. Whole
|
||||
* the process is traced in the map mapping old tree indices
|
||||
* to new tree indices. */
|
||||
StaticAtoms(const DynamicAtoms &da, OperationTree &otree, Tintintmap &tmap)
|
||||
: Atoms(), Constants(), varnames(), varorder(), vars()
|
||||
{
|
||||
import_atoms(da, otree, tmap);
|
||||
}
|
||||
/* Destructor. */
|
||||
virtual ~StaticAtoms()
|
||||
{
|
||||
}
|
||||
/** This imports atoms from dynamic atoms inserting the new
|
||||
* tree indices to the given tree (including constants). The
|
||||
* mapping from old atoms to new atoms is traced in tmap. */
|
||||
void import_atoms(const DynamicAtoms &da, OperationTree &otree,
|
||||
Tintintmap &tmap);
|
||||
/** If the name is constant, it returns its tree index if the
|
||||
* constant is registered in Constants, it returns -1
|
||||
* otherwise. If the name is not constant, it returns result
|
||||
* from check_variable, which is implemented by a subclass. */
|
||||
int check(const char *name) const;
|
||||
/** This assigns a given tree index to the variable name. The
|
||||
* name should have been checked before the call. */
|
||||
void assign(const char *name, int t);
|
||||
int
|
||||
nvar() const
|
||||
{
|
||||
return varnames.num();
|
||||
}
|
||||
/** This returns a vector of all variables. */
|
||||
vector<int> variables() const;
|
||||
/** This returns a tree index of the given variable. */
|
||||
int index(const char *name) const;
|
||||
/** This returns a name from the given tree index. NULL is
|
||||
* returned if the tree index doesn't exist. */
|
||||
const char *inv_index(int t) const;
|
||||
/** This returns a name in a outer ordering. (There is no other ordering.) */
|
||||
const char *
|
||||
name(int i) const
|
||||
{
|
||||
return varorder[i];
|
||||
}
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
/** This registers a variable. A subclass can reimplement
|
||||
* this, for example, to ensure uniqueness of the
|
||||
* name. However, this method should be always called in
|
||||
* overriding methods to do the registering job. */
|
||||
virtual void register_name(const char *name);
|
||||
/** Return the name storage to allow querying to other
|
||||
* classes. */
|
||||
const NameStorage &
|
||||
get_name_storage() const
|
||||
{
|
||||
return varnames;
|
||||
}
|
||||
protected:
|
||||
/** This checks the variable. The implementing subclass might
|
||||
* want to throw an exception if the variable has not been
|
||||
* registered. */
|
||||
virtual int check_variable(const char *name) const = 0;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,165 +8,202 @@
|
|||
#include "static_atoms.h"
|
||||
#include "fine_atoms.h"
|
||||
|
||||
namespace ogp {
|
||||
namespace ogp
|
||||
{
|
||||
|
||||
/** This class represents static atoms distinguishing between
|
||||
* parameters, endogenous and exogenous variables. The class
|
||||
* maintains also ordering of all three categories (referenced as
|
||||
* outer or inner, since there is only one ordering). It can be
|
||||
* constructed either from scratch, or from fine dynamic atoms. In
|
||||
* the latter case, one can decide if the ordering of this static
|
||||
* atoms should be internal or external ordering of the original
|
||||
* dynamic fine atoms. */
|
||||
class StaticFineAtoms : public StaticAtoms {
|
||||
public:
|
||||
typedef map<int,int> Tintintmap;
|
||||
protected:
|
||||
typedef map<const char*, int, ltstr> Tvarintmap;
|
||||
private:
|
||||
/** The vector of parameter names, gives the parameter
|
||||
* ordering. */
|
||||
vector<const char*> params;
|
||||
/** A map mappping a parameter name to an index in the ordering. */
|
||||
Tvarintmap param_outer_map;
|
||||
/** The vector of endogenous variables. This defines the order
|
||||
* like parameters. */
|
||||
vector<const char*> endovars;
|
||||
/** A map mapping a name of an endogenous variable to an index
|
||||
* in the ordering. */
|
||||
Tvarintmap endo_outer_map;
|
||||
/** The vector of exogenous variables. Also defines the order
|
||||
* like parameters and endovars. */
|
||||
vector<const char*> exovars;
|
||||
/** A map mapping a name of an exogenous variable to an index
|
||||
* in the outer ordering. */
|
||||
Tvarintmap exo_outer_map;
|
||||
/** This vector defines a set of atoms as tree indices used
|
||||
* for differentiation. The order of the atoms in is the
|
||||
* concatenation of the outer ordering of endogenous and
|
||||
* exogenous. This vector is setup by parsing_finished() and
|
||||
* is returned by variables(). */
|
||||
vector<int> 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<int> 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<int> exo_atoms_map;
|
||||
public:
|
||||
StaticFineAtoms() {}
|
||||
/** Copy constructor making a new storage for atom names. */
|
||||
StaticFineAtoms(const StaticFineAtoms& sfa);
|
||||
/** Conversion from dynamic FineAtoms taking its outer
|
||||
* ordering as ordering of parameters, endogenous and
|
||||
* exogenous. A biproduct is an integer to integer map mapping
|
||||
* tree indices of the dynamic atoms to tree indices of the
|
||||
* static atoms. */
|
||||
StaticFineAtoms(const FineAtoms& fa, OperationTree& otree, Tintintmap& tmap)
|
||||
{StaticFineAtoms::import_atoms(fa, otree, tmap);}
|
||||
/** Conversion from dynamic FineAtoms taking its internal
|
||||
* ordering as ordering of parameters, endogenous and
|
||||
* exogenous. A biproduct is an integer to integer map mapping
|
||||
* tree indices of the dynamic atoms to tree indices of the
|
||||
* static atoms. */
|
||||
StaticFineAtoms(const FineAtoms& fa, OperationTree& otree, Tintintmap& tmap,
|
||||
const char* dummy)
|
||||
{StaticFineAtoms::import_atoms(fa, otree, tmap, dummy);}
|
||||
virtual ~StaticFineAtoms() {}
|
||||
/** This adds atoms from dynamic atoms inserting new tree
|
||||
* indices to the given tree and tracing the mapping from old
|
||||
* atoms to new atoms in tmap. The ordering of the static
|
||||
* atoms is the same as outer ordering of dynamic atoms. */
|
||||
void import_atoms(const FineAtoms& fa, OperationTree& otree, Tintintmap& tmap);
|
||||
/** This adds atoms from dynamic atoms inserting new tree
|
||||
* indices to the given tree and tracing the mapping from old
|
||||
* atoms to new atoms in tmap. The ordering of the static
|
||||
* atoms is the same as internal ordering of dynamic atoms. */
|
||||
void import_atoms(const FineAtoms& fa, OperationTree& otree, Tintintmap& tmap,
|
||||
const char* dummy);
|
||||
/** Overrides StaticAtoms::check_variable so that the error
|
||||
* would be raised if the variable name is not declared. A
|
||||
* variable is declared by inserting it to
|
||||
* StaticAtoms::varnames, which is done with registering
|
||||
* methods. This a responsibility of a subclass. */
|
||||
int check_variable(const char* name) const;
|
||||
/** Return an (external) ordering of parameters. */
|
||||
const vector<const char*>& get_params() const
|
||||
{return params;}
|
||||
/** Return an external ordering of endogenous variables. */
|
||||
const vector<const char*>& get_endovars() const
|
||||
{return endovars;}
|
||||
/** Return an external ordering of exogenous variables. */
|
||||
const vector<const char*>& get_exovars() const
|
||||
{return exovars;}
|
||||
/** This constructs der_atoms, and the endo_endoms_map and
|
||||
* exo_atoms_map, which can be created only after the parsing
|
||||
* is finished. */
|
||||
void parsing_finished();
|
||||
/** Return the atoms with respect to which we are going to
|
||||
* differentiate. */
|
||||
vector<int> variables() const
|
||||
{return der_atoms;}
|
||||
/** Return the endo_atoms_map. */
|
||||
const vector<int>& get_endo_atoms_map() const
|
||||
{return endo_atoms_map;}
|
||||
/** Return the exo_atoms_map. */
|
||||
const vector<int>& get_exo_atoms_map() const
|
||||
{return endo_atoms_map;}
|
||||
/** 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 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:
|
||||
/** Add endogenous variable name, which is already in the name
|
||||
* storage. */
|
||||
void register_endo(const char* name);
|
||||
/** Add exogenous variable name, which is already in the name
|
||||
* storage. */
|
||||
void register_exo(const char* name);
|
||||
/** Add parameter name, which is already in the name
|
||||
* storage. */
|
||||
void register_param(const char* name);
|
||||
};
|
||||
/** This class represents static atoms distinguishing between
|
||||
* parameters, endogenous and exogenous variables. The class
|
||||
* maintains also ordering of all three categories (referenced as
|
||||
* outer or inner, since there is only one ordering). It can be
|
||||
* constructed either from scratch, or from fine dynamic atoms. In
|
||||
* the latter case, one can decide if the ordering of this static
|
||||
* atoms should be internal or external ordering of the original
|
||||
* dynamic fine atoms. */
|
||||
class StaticFineAtoms : public StaticAtoms
|
||||
{
|
||||
public:
|
||||
typedef map<int, int> Tintintmap;
|
||||
protected:
|
||||
typedef map<const char *, int, ltstr> Tvarintmap;
|
||||
private:
|
||||
/** The vector of parameter names, gives the parameter
|
||||
* ordering. */
|
||||
vector<const char *> params;
|
||||
/** A map mappping a parameter name to an index in the ordering. */
|
||||
Tvarintmap param_outer_map;
|
||||
/** The vector of endogenous variables. This defines the order
|
||||
* like parameters. */
|
||||
vector<const char *> endovars;
|
||||
/** A map mapping a name of an endogenous variable to an index
|
||||
* in the ordering. */
|
||||
Tvarintmap endo_outer_map;
|
||||
/** The vector of exogenous variables. Also defines the order
|
||||
* like parameters and endovars. */
|
||||
vector<const char *> exovars;
|
||||
/** A map mapping a name of an exogenous variable to an index
|
||||
* in the outer ordering. */
|
||||
Tvarintmap exo_outer_map;
|
||||
/** This vector defines a set of atoms as tree indices used
|
||||
* for differentiation. The order of the atoms in is the
|
||||
* concatenation of the outer ordering of endogenous and
|
||||
* exogenous. This vector is setup by parsing_finished() and
|
||||
* is returned by variables(). */
|
||||
vector<int> 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<int> 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<int> exo_atoms_map;
|
||||
public:
|
||||
StaticFineAtoms()
|
||||
{
|
||||
}
|
||||
/** Copy constructor making a new storage for atom names. */
|
||||
StaticFineAtoms(const StaticFineAtoms &sfa);
|
||||
/** Conversion from dynamic FineAtoms taking its outer
|
||||
* ordering as ordering of parameters, endogenous and
|
||||
* exogenous. A biproduct is an integer to integer map mapping
|
||||
* tree indices of the dynamic atoms to tree indices of the
|
||||
* static atoms. */
|
||||
StaticFineAtoms(const FineAtoms &fa, OperationTree &otree, Tintintmap &tmap)
|
||||
{
|
||||
StaticFineAtoms::import_atoms(fa, otree, tmap);
|
||||
}
|
||||
/** Conversion from dynamic FineAtoms taking its internal
|
||||
* ordering as ordering of parameters, endogenous and
|
||||
* exogenous. A biproduct is an integer to integer map mapping
|
||||
* tree indices of the dynamic atoms to tree indices of the
|
||||
* static atoms. */
|
||||
StaticFineAtoms(const FineAtoms &fa, OperationTree &otree, Tintintmap &tmap,
|
||||
const char *dummy)
|
||||
{
|
||||
StaticFineAtoms::import_atoms(fa, otree, tmap, dummy);
|
||||
}
|
||||
virtual ~StaticFineAtoms()
|
||||
{
|
||||
}
|
||||
/** This adds atoms from dynamic atoms inserting new tree
|
||||
* indices to the given tree and tracing the mapping from old
|
||||
* atoms to new atoms in tmap. The ordering of the static
|
||||
* atoms is the same as outer ordering of dynamic atoms. */
|
||||
void import_atoms(const FineAtoms &fa, OperationTree &otree, Tintintmap &tmap);
|
||||
/** This adds atoms from dynamic atoms inserting new tree
|
||||
* indices to the given tree and tracing the mapping from old
|
||||
* atoms to new atoms in tmap. The ordering of the static
|
||||
* atoms is the same as internal ordering of dynamic atoms. */
|
||||
void import_atoms(const FineAtoms &fa, OperationTree &otree, Tintintmap &tmap,
|
||||
const char *dummy);
|
||||
/** Overrides StaticAtoms::check_variable so that the error
|
||||
* would be raised if the variable name is not declared. A
|
||||
* variable is declared by inserting it to
|
||||
* StaticAtoms::varnames, which is done with registering
|
||||
* methods. This a responsibility of a subclass. */
|
||||
int check_variable(const char *name) const;
|
||||
/** Return an (external) ordering of parameters. */
|
||||
const vector<const char *> &
|
||||
get_params() const
|
||||
{
|
||||
return params;
|
||||
}
|
||||
/** Return an external ordering of endogenous variables. */
|
||||
const vector<const char *> &
|
||||
get_endovars() const
|
||||
{
|
||||
return endovars;
|
||||
}
|
||||
/** Return an external ordering of exogenous variables. */
|
||||
const vector<const char *> &
|
||||
get_exovars() const
|
||||
{
|
||||
return exovars;
|
||||
}
|
||||
/** This constructs der_atoms, and the endo_endoms_map and
|
||||
* exo_atoms_map, which can be created only after the parsing
|
||||
* is finished. */
|
||||
void parsing_finished();
|
||||
/** Return the atoms with respect to which we are going to
|
||||
* differentiate. */
|
||||
vector<int>
|
||||
variables() const
|
||||
{
|
||||
return der_atoms;
|
||||
}
|
||||
/** Return the endo_atoms_map. */
|
||||
const vector<int> &
|
||||
get_endo_atoms_map() const
|
||||
{
|
||||
return endo_atoms_map;
|
||||
}
|
||||
/** Return the exo_atoms_map. */
|
||||
const vector<int> &
|
||||
get_exo_atoms_map() const
|
||||
{
|
||||
return endo_atoms_map;
|
||||
}
|
||||
/** 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 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:
|
||||
/** Add endogenous variable name, which is already in the name
|
||||
* storage. */
|
||||
void register_endo(const char *name);
|
||||
/** Add exogenous variable name, which is already in the name
|
||||
* storage. */
|
||||
void register_exo(const char *name);
|
||||
/** Add parameter name, which is already in the name
|
||||
* storage. */
|
||||
void register_param(const char *name);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -10,442 +10,511 @@
|
|||
#include <boost/unordered_set.hpp>
|
||||
#include <cstdio>
|
||||
|
||||
namespace ogp {
|
||||
namespace ogp
|
||||
{
|
||||
|
||||
using boost::unordered_set;
|
||||
using boost::unordered_map;
|
||||
using std::vector;
|
||||
using std::set;
|
||||
using std::map;
|
||||
using boost::unordered_set;
|
||||
using boost::unordered_map;
|
||||
using std::vector;
|
||||
using std::set;
|
||||
using std::map;
|
||||
|
||||
/** Enumerator representing nulary, unary and binary operation
|
||||
* codes. For nulary, 'none' is used. When one is adding a new
|
||||
* codes, he should update the code of #OperationTree::add_unary,
|
||||
* #OperationTree::add_binary, and of course
|
||||
* #OperationTree::add_derivative. */
|
||||
enum code_t {NONE, UMINUS, LOG, EXP, SIN, COS, TAN, SQRT, ERF,
|
||||
ERFC, PLUS, MINUS, TIMES, DIVIDE, POWER};
|
||||
/** Enumerator representing nulary, unary and binary operation
|
||||
* codes. For nulary, 'none' is used. When one is adding a new
|
||||
* codes, he should update the code of #OperationTree::add_unary,
|
||||
* #OperationTree::add_binary, and of course
|
||||
* #OperationTree::add_derivative. */
|
||||
enum code_t {NONE, UMINUS, LOG, EXP, SIN, COS, TAN, SQRT, ERF,
|
||||
ERFC, PLUS, MINUS, TIMES, DIVIDE, POWER};
|
||||
|
||||
/** Class representing a nulary, unary, or binary operation. */
|
||||
class Operation {
|
||||
protected:
|
||||
/** Code of the operation. */
|
||||
code_t code;
|
||||
/** First operand. If none, then it is -1. */
|
||||
int op1;
|
||||
/** Second operand. If none, then it is -1. */
|
||||
int op2;
|
||||
/** Class representing a nulary, unary, or binary operation. */
|
||||
class Operation
|
||||
{
|
||||
protected:
|
||||
/** Code of the operation. */
|
||||
code_t code;
|
||||
/** First operand. If none, then it is -1. */
|
||||
int op1;
|
||||
/** Second operand. If none, then it is -1. */
|
||||
int op2;
|
||||
|
||||
public:
|
||||
/** Constructs a binary operation. */
|
||||
Operation(code_t cd, int oper1, int oper2)
|
||||
: code(cd), op1(oper1), op2(oper2) {}
|
||||
/** Constructs a unary operation. */
|
||||
Operation(code_t cd, int oper1)
|
||||
: code(cd), op1(oper1), op2(-1) {}
|
||||
/** Constructs a nulary operation. */
|
||||
Operation()
|
||||
: code(NONE), op1(-1), op2(-1) {}
|
||||
/** A copy constructor. */
|
||||
Operation(const Operation& op)
|
||||
: code(op.code), op1(op.op1), op2(op.op2) {}
|
||||
public:
|
||||
/** Constructs a binary operation. */
|
||||
Operation(code_t cd, int oper1, int oper2)
|
||||
: code(cd), op1(oper1), op2(oper2)
|
||||
{
|
||||
}
|
||||
/** Constructs a unary operation. */
|
||||
Operation(code_t cd, int oper1)
|
||||
: code(cd), op1(oper1), op2(-1)
|
||||
{
|
||||
}
|
||||
/** Constructs a nulary operation. */
|
||||
Operation()
|
||||
: code(NONE), op1(-1), op2(-1)
|
||||
{
|
||||
}
|
||||
/** A copy constructor. */
|
||||
Operation(const Operation &op)
|
||||
: code(op.code), op1(op.op1), op2(op.op2)
|
||||
{
|
||||
}
|
||||
|
||||
/** Operator =. */
|
||||
const Operation& operator=(const Operation& op)
|
||||
{
|
||||
code = op.code;
|
||||
op1 = op.op1;
|
||||
op2 = op.op2;
|
||||
return *this;
|
||||
}
|
||||
/** Operator ==. */
|
||||
bool operator==(const Operation& op) const
|
||||
{
|
||||
return code == op.code && op1 == op.op1 && op2 == op.op2;
|
||||
}
|
||||
/** Operator < implementing lexicographic ordering. */
|
||||
bool operator<(const Operation& op) const
|
||||
{
|
||||
return (code < op.code ||
|
||||
code == op.code &&
|
||||
(op1 < op.op1 || op1 == op.op1 && op2 < op.op2));
|
||||
}
|
||||
/** Returns a number of operands. */
|
||||
int nary() const
|
||||
{
|
||||
return (op2 == -1)? ((op1 == -1) ? 0 : 1) : 2;
|
||||
}
|
||||
/** Returns a hash value of the operation. */
|
||||
size_t hashval() const
|
||||
{
|
||||
return op2+1 + (op1+1)^15 + code^30;
|
||||
}
|
||||
/** Operator =. */
|
||||
const Operation &
|
||||
operator=(const Operation &op)
|
||||
{
|
||||
code = op.code;
|
||||
op1 = op.op1;
|
||||
op2 = op.op2;
|
||||
return *this;
|
||||
}
|
||||
/** Operator ==. */
|
||||
bool
|
||||
operator==(const Operation &op) const
|
||||
{
|
||||
return code == op.code && op1 == op.op1 && op2 == op.op2;
|
||||
}
|
||||
/** Operator < implementing lexicographic ordering. */
|
||||
bool
|
||||
operator<(const Operation &op) const
|
||||
{
|
||||
return (code < op.code
|
||||
|| code == op.code
|
||||
&& (op1 < op.op1 || op1 == op.op1 && op2 < op.op2));
|
||||
}
|
||||
/** Returns a number of operands. */
|
||||
int
|
||||
nary() const
|
||||
{
|
||||
return (op2 == -1) ? ((op1 == -1) ? 0 : 1) : 2;
|
||||
}
|
||||
/** Returns a hash value of the operation. */
|
||||
size_t
|
||||
hashval() const
|
||||
{
|
||||
return op2+1 + (op1+1)^15 + code^30;
|
||||
}
|
||||
|
||||
code_t getCode() const
|
||||
{ return code; }
|
||||
int getOp1() const
|
||||
{ return op1; }
|
||||
int getOp2() const
|
||||
{ return op2; }
|
||||
code_t
|
||||
getCode() const
|
||||
{
|
||||
return code;
|
||||
}
|
||||
int
|
||||
getOp1() const
|
||||
{
|
||||
return op1;
|
||||
}
|
||||
int
|
||||
getOp2() const
|
||||
{
|
||||
return op2;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/** This struct is a predicate for ordering of the operations in
|
||||
* OperationTree class. now obsolete */
|
||||
struct ltoper {
|
||||
bool operator()(const Operation& oper1, const Operation& oper2) const
|
||||
{return oper1 < oper2;}
|
||||
};
|
||||
/** This struct is a predicate for ordering of the operations in
|
||||
* OperationTree class. now obsolete */
|
||||
struct ltoper
|
||||
{
|
||||
bool
|
||||
operator()(const Operation &oper1, const Operation &oper2) const
|
||||
{
|
||||
return oper1 < oper2;
|
||||
}
|
||||
};
|
||||
|
||||
/** Hash function object for Operation. */
|
||||
struct ophash {
|
||||
size_t operator()(const Operation& op) const
|
||||
{ return op.hashval(); }
|
||||
};
|
||||
/** Hash function object for Operation. */
|
||||
struct ophash
|
||||
{
|
||||
size_t
|
||||
operator()(const Operation &op) const
|
||||
{
|
||||
return op.hashval();
|
||||
}
|
||||
};
|
||||
|
||||
/** This struct is a function object selecting some
|
||||
* operations. The operation is given by a tree index. */
|
||||
struct opselector {
|
||||
virtual bool operator()(int t) const = 0;
|
||||
virtual ~opselector() {}
|
||||
};
|
||||
/** This struct is a function object selecting some
|
||||
* operations. The operation is given by a tree index. */
|
||||
struct opselector
|
||||
{
|
||||
virtual bool operator()(int t) const = 0;
|
||||
virtual ~opselector()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/** Forward declaration of OperationFormatter. */
|
||||
class OperationFormatter;
|
||||
class DefaultOperationFormatter;
|
||||
/** Forward declaration of OperationFormatter. */
|
||||
class OperationFormatter;
|
||||
class DefaultOperationFormatter;
|
||||
|
||||
/** Forward declaration of EvalTree to make it friend of OperationTree. */
|
||||
class EvalTree;
|
||||
/** Forward declaration of EvalTree to make it friend of OperationTree. */
|
||||
class EvalTree;
|
||||
|
||||
/** Class representing a set of trees for terms. Each term is
|
||||
* given a unique non-negative integer. The terms are basically
|
||||
* operations whose (integer) operands point to another terms in
|
||||
* the tree. The terms are stored in the vector. Equivalent unary
|
||||
* and binary terms are stored only once. This class guarantees
|
||||
* the uniqueness. The uniqueness of nulary terms is guaranteed by
|
||||
* the caller, since at this level of Operation abstraction, one
|
||||
* cannot discriminate between different nulary operations
|
||||
* (constants, variables). The uniqueness is enforced by the
|
||||
* unordered_map whose keys are operations and values are integers
|
||||
* (indices of the terms).
|
||||
/** Class representing a set of trees for terms. Each term is
|
||||
* given a unique non-negative integer. The terms are basically
|
||||
* operations whose (integer) operands point to another terms in
|
||||
* the tree. The terms are stored in the vector. Equivalent unary
|
||||
* and binary terms are stored only once. This class guarantees
|
||||
* the uniqueness. The uniqueness of nulary terms is guaranteed by
|
||||
* the caller, since at this level of Operation abstraction, one
|
||||
* cannot discriminate between different nulary operations
|
||||
* (constants, variables). The uniqueness is enforced by the
|
||||
* unordered_map whose keys are operations and values are integers
|
||||
* (indices of the terms).
|
||||
|
||||
* This class can also make derivatives of a given term with
|
||||
* respect to a given nulary term. I order to be able to quickly
|
||||
* recognize zero derivativates, we maintain a list of nulary
|
||||
* terms contained in the term. A possible zero derivative is then quickly
|
||||
* recognized by looking at the list. The list is implemented as a
|
||||
* unordered_set of integers.
|
||||
*
|
||||
* In addition, many term can be differentiated multiple times wrt
|
||||
* one variable since they can be referenced multiple times. To
|
||||
* avoid this, for each term we maintain a map mapping variables
|
||||
* to the derivatives of the term. As the caller will
|
||||
* differentiate wrt more and more variables, these maps will
|
||||
* become richer and richer.
|
||||
*/
|
||||
class OperationTree {
|
||||
friend class EvalTree;
|
||||
friend class DefaultOperationFormatter;
|
||||
protected:
|
||||
/** This is the vector of the terms. An index to this vector
|
||||
* uniquelly determines the term. */
|
||||
vector<Operation> terms;
|
||||
* This class can also make derivatives of a given term with
|
||||
* respect to a given nulary term. I order to be able to quickly
|
||||
* recognize zero derivativates, we maintain a list of nulary
|
||||
* terms contained in the term. A possible zero derivative is then quickly
|
||||
* recognized by looking at the list. The list is implemented as a
|
||||
* unordered_set of integers.
|
||||
*
|
||||
* In addition, many term can be differentiated multiple times wrt
|
||||
* one variable since they can be referenced multiple times. To
|
||||
* avoid this, for each term we maintain a map mapping variables
|
||||
* to the derivatives of the term. As the caller will
|
||||
* differentiate wrt more and more variables, these maps will
|
||||
* become richer and richer.
|
||||
*/
|
||||
class OperationTree
|
||||
{
|
||||
friend class EvalTree;
|
||||
friend class DefaultOperationFormatter;
|
||||
protected:
|
||||
/** This is the vector of the terms. An index to this vector
|
||||
* uniquelly determines the term. */
|
||||
vector<Operation> terms;
|
||||
|
||||
/** This defines a type for a map mapping the unary and binary
|
||||
* operations to their indices. */
|
||||
typedef unordered_map<Operation, int, ophash> _Topmap;
|
||||
typedef _Topmap::value_type _Topval;
|
||||
/** This defines a type for a map mapping the unary and binary
|
||||
* operations to their indices. */
|
||||
typedef unordered_map<Operation, int, ophash> _Topmap;
|
||||
typedef _Topmap::value_type _Topval;
|
||||
|
||||
/** This is the map mapping the unary and binary operations to
|
||||
* the indices of the terms.*/
|
||||
_Topmap opmap;
|
||||
/** This is the map mapping the unary and binary operations to
|
||||
* the indices of the terms.*/
|
||||
_Topmap opmap;
|
||||
|
||||
/** This is a type for a set of integers. */
|
||||
typedef unordered_set<int> _Tintset;
|
||||
/** This is a vector of integer sets corresponding to the
|
||||
* nulary terms contained in the term. */
|
||||
vector<_Tintset> nul_incidence;
|
||||
/** This is a type for a set of integers. */
|
||||
typedef unordered_set<int> _Tintset;
|
||||
/** This is a vector of integer sets corresponding to the
|
||||
* nulary terms contained in the term. */
|
||||
vector<_Tintset> nul_incidence;
|
||||
|
||||
/** This is a type of the map from variables (nulary terms) to
|
||||
* the terms. */
|
||||
typedef unordered_map<int, int> _Tderivmap;
|
||||
/** This is a vector of derivative mappings. For each term, it
|
||||
* maps variables to the derivatives of the term with respect
|
||||
* to the variables. */
|
||||
vector<_Tderivmap> derivatives;
|
||||
/** This is a type of the map from variables (nulary terms) to
|
||||
* the terms. */
|
||||
typedef unordered_map<int, int> _Tderivmap;
|
||||
/** This is a vector of derivative mappings. For each term, it
|
||||
* maps variables to the derivatives of the term with respect
|
||||
* to the variables. */
|
||||
vector<_Tderivmap> derivatives;
|
||||
|
||||
/** The tree index of the last nulary term. */
|
||||
int last_nulary;
|
||||
public:
|
||||
/** This is a number of constants set in the following
|
||||
* enum. This number reserves space in a vector of terms for
|
||||
* the constants. */
|
||||
static const int num_constants = 4;
|
||||
/** Enumeration for special terms. We need zero, one, nan and
|
||||
* 2/pi. These will be always first four terms having indices
|
||||
* zero, one and two, three. If adding anything to this
|
||||
* enumeration, make sure you have updated num_constants above.*/
|
||||
enum {zero=0, one=1, nan=2, two_over_pi=3};
|
||||
/** The tree index of the last nulary term. */
|
||||
int last_nulary;
|
||||
public:
|
||||
/** This is a number of constants set in the following
|
||||
* enum. This number reserves space in a vector of terms for
|
||||
* the constants. */
|
||||
static const int num_constants = 4;
|
||||
/** Enumeration for special terms. We need zero, one, nan and
|
||||
* 2/pi. These will be always first four terms having indices
|
||||
* zero, one and two, three. If adding anything to this
|
||||
* enumeration, make sure you have updated num_constants above.*/
|
||||
enum {zero = 0, one = 1, nan = 2, two_over_pi = 3};
|
||||
|
||||
/** The unique constructor which initializes the object to
|
||||
* contain only zero, one and nan and two_over_pi.*/
|
||||
OperationTree();
|
||||
/** The unique constructor which initializes the object to
|
||||
* contain only zero, one and nan and two_over_pi.*/
|
||||
OperationTree();
|
||||
|
||||
/** Copy constructor. */
|
||||
OperationTree(const OperationTree& ot)
|
||||
: terms(ot.terms), opmap(ot.opmap), nul_incidence(ot.nul_incidence),
|
||||
derivatives(ot.derivatives),
|
||||
last_nulary(ot.last_nulary)
|
||||
{}
|
||||
/** Copy constructor. */
|
||||
OperationTree(const OperationTree &ot)
|
||||
: terms(ot.terms), opmap(ot.opmap), nul_incidence(ot.nul_incidence),
|
||||
derivatives(ot.derivatives),
|
||||
last_nulary(ot.last_nulary)
|
||||
{
|
||||
}
|
||||
|
||||
/** Add a nulary operation. The caller is responsible for not
|
||||
* inserting two semantically equivalent nulary operations.
|
||||
* @return newly allocated index
|
||||
*/
|
||||
int add_nulary();
|
||||
/** Add a nulary operation. The caller is responsible for not
|
||||
* inserting two semantically equivalent nulary operations.
|
||||
* @return newly allocated index
|
||||
*/
|
||||
int add_nulary();
|
||||
|
||||
/** Add a unary operation. The uniqness is checked, if it
|
||||
* already exists, then it is not added.
|
||||
* @param code the code of the unary operation
|
||||
* @param op the index of the operand
|
||||
* @return the index of the operation
|
||||
*/
|
||||
int add_unary(code_t code, int op);
|
||||
/** Add a unary operation. The uniqness is checked, if it
|
||||
* already exists, then it is not added.
|
||||
* @param code the code of the unary operation
|
||||
* @param op the index of the operand
|
||||
* @return the index of the operation
|
||||
*/
|
||||
int add_unary(code_t code, int op);
|
||||
|
||||
/** Add a binary operation. The uniqueness is checked, if it
|
||||
* already exists, then it is not added.
|
||||
* @param code the code of the binary operation
|
||||
* @param op1 the index of the first operand
|
||||
* @param op2 the index of the second operand
|
||||
* @return the index of the operation
|
||||
*/
|
||||
int add_binary(code_t code, int op1, int op2);
|
||||
/** Add a binary operation. The uniqueness is checked, if it
|
||||
* already exists, then it is not added.
|
||||
* @param code the code of the binary operation
|
||||
* @param op1 the index of the first operand
|
||||
* @param op2 the index of the second operand
|
||||
* @return the index of the operation
|
||||
*/
|
||||
int add_binary(code_t code, int op1, int op2);
|
||||
|
||||
/** Add the derivative of the given term with respect to the
|
||||
* given nulary operation.
|
||||
* @param t the index of the operation being differentiated
|
||||
* @param v the index of the nulary operation
|
||||
* @return the index of the derivative
|
||||
*/
|
||||
int add_derivative(int t, int v);
|
||||
/** Add the derivative of the given term with respect to the
|
||||
* given nulary operation.
|
||||
* @param t the index of the operation being differentiated
|
||||
* @param v the index of the nulary operation
|
||||
* @return the index of the derivative
|
||||
*/
|
||||
int add_derivative(int t, int v);
|
||||
|
||||
/** Add the substitution given by the map. This adds a new
|
||||
* term which is equal to the given term with applied
|
||||
* substitutions given by the map replacing each term on the
|
||||
* left by a term on the right. We do not check that the terms
|
||||
* on the left are not subterms of the terms on the right. If
|
||||
* so, the substituted terms are not subject of further
|
||||
* substitution. */
|
||||
int add_substitution(int t, const map<int,int>& subst);
|
||||
/** Add the substitution given by the map. This adds a new
|
||||
* term which is equal to the given term with applied
|
||||
* substitutions given by the map replacing each term on the
|
||||
* left by a term on the right. We do not check that the terms
|
||||
* on the left are not subterms of the terms on the right. If
|
||||
* so, the substituted terms are not subject of further
|
||||
* substitution. */
|
||||
int add_substitution(int t, const map<int, int> &subst);
|
||||
|
||||
/** Add the substitution given by the map where left sides of
|
||||
* substitutions come from another tree. The right sides are
|
||||
* from this tree. The given t is from the given otree. */
|
||||
int add_substitution(int t, const map<int,int>& subst,
|
||||
const OperationTree& otree);
|
||||
/** Add the substitution given by the map where left sides of
|
||||
* substitutions come from another tree. The right sides are
|
||||
* from this tree. The given t is from the given otree. */
|
||||
int add_substitution(int t, const map<int, int> &subst,
|
||||
const OperationTree &otree);
|
||||
|
||||
/** This method turns the given term to a nulary
|
||||
* operation. This is an only method, which changes already
|
||||
* existing term (all other methods add something new). User
|
||||
* should use this with caution and must make sure that
|
||||
* something similar has happened for atoms. In addition, it
|
||||
* does not do anything with derivatives, so it should not be
|
||||
* used after some derivatives were created, and derivatives
|
||||
* already created and saved in derivatives mappings should be
|
||||
* forgotten with forget_derivative_maps. */
|
||||
void nularify(int t);
|
||||
/** This method turns the given term to a nulary
|
||||
* operation. This is an only method, which changes already
|
||||
* existing term (all other methods add something new). User
|
||||
* should use this with caution and must make sure that
|
||||
* something similar has happened for atoms. In addition, it
|
||||
* does not do anything with derivatives, so it should not be
|
||||
* used after some derivatives were created, and derivatives
|
||||
* already created and saved in derivatives mappings should be
|
||||
* forgotten with forget_derivative_maps. */
|
||||
void nularify(int t);
|
||||
|
||||
/** Return the set of nulary terms of the given term. */
|
||||
const unordered_set<int>& nulary_of_term(int t) const
|
||||
{return nul_incidence[t];}
|
||||
/** Return the set of nulary terms of the given term. */
|
||||
const unordered_set<int> &
|
||||
nulary_of_term(int t) const
|
||||
{
|
||||
return nul_incidence[t];
|
||||
}
|
||||
|
||||
/** Select subterms of the given term according a given
|
||||
* operation selector and return the set of terms that
|
||||
* correspond to the compounded operations. The given term is
|
||||
* a compound function of the returned subterms and the
|
||||
* function consists only from operations which yield false in
|
||||
* the selector. */
|
||||
unordered_set<int> select_terms(int t, const opselector& sel) const;
|
||||
/** Select subterms of the given term according a given
|
||||
* operation selector and return the set of terms that
|
||||
* correspond to the compounded operations. The given term is
|
||||
* a compound function of the returned subterms and the
|
||||
* function consists only from operations which yield false in
|
||||
* the selector. */
|
||||
unordered_set<int> select_terms(int t, const opselector &sel) const;
|
||||
|
||||
/** Select subterms of the given term according a given
|
||||
* operation selector and return the set of terms that
|
||||
* correspond to the compounded operations. The given term is
|
||||
* a compound function of the returned subterms and the
|
||||
* subterms are maximal subterms consisting from operations
|
||||
* yielding true in the selector. */
|
||||
unordered_set<int> select_terms_inv(int t, const opselector& sel) const;
|
||||
/** Select subterms of the given term according a given
|
||||
* operation selector and return the set of terms that
|
||||
* correspond to the compounded operations. The given term is
|
||||
* a compound function of the returned subterms and the
|
||||
* subterms are maximal subterms consisting from operations
|
||||
* yielding true in the selector. */
|
||||
unordered_set<int> select_terms_inv(int t, const opselector &sel) const;
|
||||
|
||||
/** This forgets all the derivative mappings. It is used after
|
||||
* a term has been nularified, and then the derivative
|
||||
* mappings carry wrong information. Note that the derivatives
|
||||
* mappings serve only as a tool for quick returns in
|
||||
* add_derivative. Resseting the mappings is harmless, all the
|
||||
* information is rebuilt in add_derivative without any
|
||||
* additional nodes (trees). */
|
||||
void forget_derivative_maps();
|
||||
/** This forgets all the derivative mappings. It is used after
|
||||
* a term has been nularified, and then the derivative
|
||||
* mappings carry wrong information. Note that the derivatives
|
||||
* mappings serve only as a tool for quick returns in
|
||||
* add_derivative. Resseting the mappings is harmless, all the
|
||||
* information is rebuilt in add_derivative without any
|
||||
* additional nodes (trees). */
|
||||
void forget_derivative_maps();
|
||||
|
||||
/** This returns an operation of a given term. */
|
||||
const Operation& operation(int t) const
|
||||
{return terms[t];}
|
||||
/** This returns an operation of a given term. */
|
||||
const Operation &
|
||||
operation(int t) const
|
||||
{
|
||||
return terms[t];
|
||||
}
|
||||
|
||||
/** This outputs the operation to the given file descriptor
|
||||
* using the given OperationFormatter. */
|
||||
void print_operation_tree(int t, FILE* fd, OperationFormatter& f) const;
|
||||
/** This outputs the operation to the given file descriptor
|
||||
* using the given OperationFormatter. */
|
||||
void print_operation_tree(int t, FILE *fd, OperationFormatter &f) const;
|
||||
|
||||
/** Debug print of a given operation: */
|
||||
void print_operation(int t) const;
|
||||
/** Debug print of a given operation: */
|
||||
void print_operation(int t) const;
|
||||
|
||||
/** Return the last tree index of a nulary term. */
|
||||
int get_last_nulary() const
|
||||
{return last_nulary;}
|
||||
/** Return the last tree index of a nulary term. */
|
||||
int
|
||||
get_last_nulary() const
|
||||
{
|
||||
return last_nulary;
|
||||
}
|
||||
|
||||
/** Get the number of all operations. */
|
||||
int get_num_op() const
|
||||
{return (int)(terms.size());}
|
||||
private:
|
||||
/** This registers a calculated derivative of the term in the
|
||||
* #derivatives vector.
|
||||
* @param t the index of the term for which we register the derivative
|
||||
* @param v the index of the nulary term (variable) to which
|
||||
* respect the derivative was taken
|
||||
* @param tder the index of the resulting derivative
|
||||
*/
|
||||
void register_derivative(int t, int v, int tder);
|
||||
/** This does the same job as select_terms with the only
|
||||
* difference, that it adds the terms to the given set and
|
||||
* hence can be used recursivelly. */
|
||||
void select_terms(int t, const opselector& sel, unordered_set<int>& subterms) const;
|
||||
/** This does the same job as select_terms_inv with the only
|
||||
* difference, that it adds the terms to the given set and
|
||||
* hence can be used recursivelly and returns true if the term
|
||||
* was selected. */
|
||||
bool select_terms_inv(int t, const opselector& sel, unordered_set<int>& subterms) const;
|
||||
/** This updates nul_incidence information after the term t
|
||||
* was turned to a nulary term in all terms. It goes through
|
||||
* the tree from simplest terms to teh more complex ones and
|
||||
* changes the nul_incidence information where necesary. It
|
||||
* maintains a set where the changes have been made.*/
|
||||
void update_nul_incidence_after_nularify(int t);
|
||||
};
|
||||
/** Get the number of all operations. */
|
||||
int
|
||||
get_num_op() const
|
||||
{
|
||||
return (int) (terms.size());
|
||||
}
|
||||
private:
|
||||
/** This registers a calculated derivative of the term in the
|
||||
* #derivatives vector.
|
||||
* @param t the index of the term for which we register the derivative
|
||||
* @param v the index of the nulary term (variable) to which
|
||||
* respect the derivative was taken
|
||||
* @param tder the index of the resulting derivative
|
||||
*/
|
||||
void register_derivative(int t, int v, int tder);
|
||||
/** This does the same job as select_terms with the only
|
||||
* difference, that it adds the terms to the given set and
|
||||
* hence can be used recursivelly. */
|
||||
void select_terms(int t, const opselector &sel, unordered_set<int> &subterms) const;
|
||||
/** This does the same job as select_terms_inv with the only
|
||||
* difference, that it adds the terms to the given set and
|
||||
* hence can be used recursivelly and returns true if the term
|
||||
* was selected. */
|
||||
bool select_terms_inv(int t, const opselector &sel, unordered_set<int> &subterms) const;
|
||||
/** This updates nul_incidence information after the term t
|
||||
* was turned to a nulary term in all terms. It goes through
|
||||
* the tree from simplest terms to teh more complex ones and
|
||||
* changes the nul_incidence information where necesary. It
|
||||
* maintains a set where the changes have been made.*/
|
||||
void update_nul_incidence_after_nularify(int t);
|
||||
};
|
||||
|
||||
/** EvalTree class allows for an evaluation of the given tree for
|
||||
* a given values of nulary terms. For each term in the
|
||||
* OperationTree the class maintains a resulting value and a flag
|
||||
* if the value has been calculated or set. The life cycle of the
|
||||
* class is the following: After it is initialized, the user must
|
||||
* set values for necessary nulary terms. Then the object can be
|
||||
* requested to evaluate particular terms. During this process,
|
||||
* the number of evaluated terms is increasing. Then the user can
|
||||
* request overall reset of evaluation flags, set the nulary terms
|
||||
* to new values and evaluate a number of terms.
|
||||
*
|
||||
* Note that currently the user cannot request a reset of
|
||||
* evaluation flags only for those terms depending on a given
|
||||
* nulary term. This might be added in future and handeled by a
|
||||
* subclasses of OperationTree and EvalTree, since we need a
|
||||
* support for this in OperationTree.
|
||||
*/
|
||||
class EvalTree {
|
||||
protected:
|
||||
/** Reference to the OperationTree over which all evaluations
|
||||
* are done. */
|
||||
const OperationTree& otree;
|
||||
/** The array of values. */
|
||||
double* const values;
|
||||
/** The array of evaluation flags. */
|
||||
bool* const flags;
|
||||
/** The index of last operation in the EvalTree. Length of
|
||||
* values and flags will be then last_operation+1. */
|
||||
int last_operation;
|
||||
public:
|
||||
/** Initializes the evaluation tree for the given operation
|
||||
* tree. If last is greater than -1, that the evaluation tree
|
||||
* will contain only formulas up to the given last index
|
||||
* (included). */
|
||||
EvalTree(const OperationTree& otree, int last = -1);
|
||||
virtual ~EvalTree()
|
||||
{ delete [] values; delete [] flags; }
|
||||
/** Set evaluation flag to all terms (besides the first
|
||||
* special terms) to false. */
|
||||
void reset_all();
|
||||
/** Set value for a given nulary term. */
|
||||
void set_nulary(int t, double val);
|
||||
/** Evaluate the given term with nulary terms set so far. */
|
||||
double eval(int t);
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
/* Return the operation tree. */
|
||||
const OperationTree& getOperationTree() const
|
||||
{return otree;}
|
||||
private:
|
||||
EvalTree(const EvalTree&);
|
||||
};
|
||||
/** EvalTree class allows for an evaluation of the given tree for
|
||||
* a given values of nulary terms. For each term in the
|
||||
* OperationTree the class maintains a resulting value and a flag
|
||||
* if the value has been calculated or set. The life cycle of the
|
||||
* class is the following: After it is initialized, the user must
|
||||
* set values for necessary nulary terms. Then the object can be
|
||||
* requested to evaluate particular terms. During this process,
|
||||
* the number of evaluated terms is increasing. Then the user can
|
||||
* request overall reset of evaluation flags, set the nulary terms
|
||||
* to new values and evaluate a number of terms.
|
||||
*
|
||||
* Note that currently the user cannot request a reset of
|
||||
* evaluation flags only for those terms depending on a given
|
||||
* nulary term. This might be added in future and handeled by a
|
||||
* subclasses of OperationTree and EvalTree, since we need a
|
||||
* support for this in OperationTree.
|
||||
*/
|
||||
class EvalTree
|
||||
{
|
||||
protected:
|
||||
/** Reference to the OperationTree over which all evaluations
|
||||
* are done. */
|
||||
const OperationTree &otree;
|
||||
/** The array of values. */
|
||||
double *const values;
|
||||
/** The array of evaluation flags. */
|
||||
bool *const flags;
|
||||
/** The index of last operation in the EvalTree. Length of
|
||||
* values and flags will be then last_operation+1. */
|
||||
int last_operation;
|
||||
public:
|
||||
/** Initializes the evaluation tree for the given operation
|
||||
* tree. If last is greater than -1, that the evaluation tree
|
||||
* will contain only formulas up to the given last index
|
||||
* (included). */
|
||||
EvalTree(const OperationTree &otree, int last = -1);
|
||||
virtual ~EvalTree()
|
||||
{
|
||||
delete [] values; delete [] flags;
|
||||
}
|
||||
/** Set evaluation flag to all terms (besides the first
|
||||
* special terms) to false. */
|
||||
void reset_all();
|
||||
/** Set value for a given nulary term. */
|
||||
void set_nulary(int t, double val);
|
||||
/** Evaluate the given term with nulary terms set so far. */
|
||||
double eval(int t);
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
/* Return the operation tree. */
|
||||
const OperationTree &
|
||||
getOperationTree() const
|
||||
{
|
||||
return otree;
|
||||
}
|
||||
private:
|
||||
EvalTree(const EvalTree &);
|
||||
};
|
||||
|
||||
/** This is an interface describing how a given operation is
|
||||
* formatted for output. */
|
||||
class OperationFormatter {
|
||||
public:
|
||||
/** Empty virtual destructor. */
|
||||
virtual ~OperationFormatter() {}
|
||||
/** Print the formatted operation op with a given tree index t
|
||||
* to a given descriptor. (See class OperationTree to know
|
||||
* what is a tree index.) This prints all the tree. This
|
||||
* always writes equation, left hand side is a string
|
||||
* represenation (a variable, temporary, whatever) of the
|
||||
* term, the right hand side is a string representation of the
|
||||
* operation (which will refer to other string representation
|
||||
* of subterms). */
|
||||
virtual void format(const Operation& op, int t, FILE* fd)=0;
|
||||
};
|
||||
/** This is an interface describing how a given operation is
|
||||
* formatted for output. */
|
||||
class OperationFormatter
|
||||
{
|
||||
public:
|
||||
/** Empty virtual destructor. */
|
||||
virtual ~OperationFormatter()
|
||||
{
|
||||
}
|
||||
/** Print the formatted operation op with a given tree index t
|
||||
* to a given descriptor. (See class OperationTree to know
|
||||
* what is a tree index.) This prints all the tree. This
|
||||
* always writes equation, left hand side is a string
|
||||
* represenation (a variable, temporary, whatever) of the
|
||||
* term, the right hand side is a string representation of the
|
||||
* operation (which will refer to other string representation
|
||||
* of subterms). */
|
||||
virtual void format(const Operation &op, int t, FILE *fd) = 0;
|
||||
};
|
||||
|
||||
/** The default formatter formats the formulas with a usual syntax
|
||||
* (for example Matlab). A formatting of atoms and terms might be
|
||||
* reimplemented by a subclass. In addition, during its life, the
|
||||
* object maintains a set of tree indices which have been output
|
||||
* and they are not output any more. */
|
||||
class DefaultOperationFormatter : public OperationFormatter {
|
||||
protected:
|
||||
const OperationTree& otree;
|
||||
set<int> stop_set;
|
||||
public:
|
||||
DefaultOperationFormatter(const OperationTree& ot)
|
||||
: otree(ot) {}
|
||||
/** Format the operation with the default syntax. */
|
||||
void format(const Operation& op, int t, FILE* fd);
|
||||
/** This prints a string represenation of the given term, for
|
||||
* example 'tmp10' for term 10. In this implementation it
|
||||
* prints $10. */
|
||||
virtual void format_term(int t, FILE* fd) const;
|
||||
/** Print a string representation of the nulary term. */
|
||||
virtual void format_nulary(int t, FILE* fd) const;
|
||||
/** Print a delimiter between two statements. By default it is
|
||||
* "\n". */
|
||||
virtual void print_delim(FILE* fd) const;
|
||||
};
|
||||
/** The default formatter formats the formulas with a usual syntax
|
||||
* (for example Matlab). A formatting of atoms and terms might be
|
||||
* reimplemented by a subclass. In addition, during its life, the
|
||||
* object maintains a set of tree indices which have been output
|
||||
* and they are not output any more. */
|
||||
class DefaultOperationFormatter : public OperationFormatter
|
||||
{
|
||||
protected:
|
||||
const OperationTree &otree;
|
||||
set<int> stop_set;
|
||||
public:
|
||||
DefaultOperationFormatter(const OperationTree &ot)
|
||||
: otree(ot)
|
||||
{
|
||||
}
|
||||
/** Format the operation with the default syntax. */
|
||||
void format(const Operation &op, int t, FILE *fd);
|
||||
/** This prints a string represenation of the given term, for
|
||||
* example 'tmp10' for term 10. In this implementation it
|
||||
* prints $10. */
|
||||
virtual void format_term(int t, FILE *fd) const;
|
||||
/** Print a string representation of the nulary term. */
|
||||
virtual void format_nulary(int t, FILE *fd) const;
|
||||
/** Print a delimiter between two statements. By default it is
|
||||
* "\n". */
|
||||
virtual void print_delim(FILE *fd) const;
|
||||
};
|
||||
|
||||
class NularyStringConvertor {
|
||||
public:
|
||||
virtual ~NularyStringConvertor() {}
|
||||
/** Return the string representation of the atom with the tree
|
||||
* index t. */
|
||||
virtual std::string convert(int t) const = 0;
|
||||
};
|
||||
class NularyStringConvertor
|
||||
{
|
||||
public:
|
||||
virtual ~NularyStringConvertor()
|
||||
{
|
||||
}
|
||||
/** Return the string representation of the atom with the tree
|
||||
* index t. */
|
||||
virtual std::string convert(int t) const = 0;
|
||||
};
|
||||
|
||||
/** This class converts the given term to its mathematical string representation. */
|
||||
class OperationStringConvertor {
|
||||
protected:
|
||||
const NularyStringConvertor& nulsc;
|
||||
const OperationTree& otree;
|
||||
public:
|
||||
OperationStringConvertor(const NularyStringConvertor& nsc, const OperationTree& ot)
|
||||
: nulsc(nsc), otree(ot) {}
|
||||
/** Empty virtual destructor. */
|
||||
virtual ~OperationStringConvertor() {}
|
||||
/** Convert the operation to the string mathematical
|
||||
* representation. This does not write any equation, just
|
||||
* returns a string representation of the formula. */
|
||||
std::string convert(const Operation& op, int t) const;
|
||||
};
|
||||
/** This class converts the given term to its mathematical string representation. */
|
||||
class OperationStringConvertor
|
||||
{
|
||||
protected:
|
||||
const NularyStringConvertor &nulsc;
|
||||
const OperationTree &otree;
|
||||
public:
|
||||
OperationStringConvertor(const NularyStringConvertor &nsc, const OperationTree &ot)
|
||||
: nulsc(nsc), otree(ot)
|
||||
{
|
||||
}
|
||||
/** Empty virtual destructor. */
|
||||
virtual ~OperationStringConvertor()
|
||||
{
|
||||
}
|
||||
/** Convert the operation to the string mathematical
|
||||
* representation. This does not write any equation, just
|
||||
* returns a string representation of the formula. */
|
||||
std::string convert(const Operation &op, int t) const;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,175 +18,286 @@
|
|||
|
||||
class Dynare;
|
||||
|
||||
class DynareNameList : public NameList {
|
||||
vector<const char*> names;
|
||||
class DynareNameList : public NameList
|
||||
{
|
||||
vector<const char *> names;
|
||||
public:
|
||||
DynareNameList(const Dynare& dynare);
|
||||
int getNum() const
|
||||
{return (int)names.size();}
|
||||
const char* getName(int i) const
|
||||
{return names[i];}
|
||||
/** This for each string of the input vector calculates its index
|
||||
* in the names. And returns the resulting vector of indices. If
|
||||
* the name cannot be found, then an exception is raised. */
|
||||
vector<int> selectIndices(const vector<const char*>& ns) const;
|
||||
DynareNameList(const Dynare &dynare);
|
||||
int
|
||||
getNum() const
|
||||
{
|
||||
return (int) names.size();
|
||||
}
|
||||
const char *
|
||||
getName(int i) const
|
||||
{
|
||||
return names[i];
|
||||
}
|
||||
/** This for each string of the input vector calculates its index
|
||||
* in the names. And returns the resulting vector of indices. If
|
||||
* the name cannot be found, then an exception is raised. */
|
||||
vector<int> selectIndices(const vector<const char *> &ns) const;
|
||||
};
|
||||
|
||||
class DynareExogNameList : public NameList {
|
||||
vector<const char*> names;
|
||||
class DynareExogNameList : public NameList
|
||||
{
|
||||
vector<const char *> names;
|
||||
public:
|
||||
DynareExogNameList(const Dynare& dynare);
|
||||
int getNum() const
|
||||
{return (int)names.size();}
|
||||
const char* getName(int i) const
|
||||
{return names[i];}
|
||||
DynareExogNameList(const Dynare &dynare);
|
||||
int
|
||||
getNum() const
|
||||
{
|
||||
return (int) names.size();
|
||||
}
|
||||
const char *
|
||||
getName(int i) const
|
||||
{
|
||||
return names[i];
|
||||
}
|
||||
};
|
||||
|
||||
class DynareStateNameList : public NameList {
|
||||
vector<const char*> names;
|
||||
class DynareStateNameList : public NameList
|
||||
{
|
||||
vector<const char *> names;
|
||||
public:
|
||||
DynareStateNameList(const Dynare& dynare, const DynareNameList& dnl,
|
||||
const DynareExogNameList& denl);
|
||||
int getNum() const
|
||||
{return (int)names.size();}
|
||||
const char* getName(int i) const
|
||||
{return names[i];}
|
||||
DynareStateNameList(const Dynare &dynare, const DynareNameList &dnl,
|
||||
const DynareExogNameList &denl);
|
||||
int
|
||||
getNum() const
|
||||
{
|
||||
return (int) names.size();
|
||||
}
|
||||
const char *
|
||||
getName(int i) const
|
||||
{
|
||||
return names[i];
|
||||
}
|
||||
};
|
||||
|
||||
// The following only implements DynamicModel with help of ogdyn::DynareModel
|
||||
|
||||
class DynareJacobian;
|
||||
class Dynare : public DynamicModel {
|
||||
friend class DynareNameList;
|
||||
friend class DynareExogNameList;
|
||||
friend class DynareStateNameList;
|
||||
friend class DynareJacobian;
|
||||
Journal& journal;
|
||||
ogdyn::DynareModel* model;
|
||||
Vector* ysteady;
|
||||
TensorContainer<FSSparseTensor> md;
|
||||
DynareNameList* dnl;
|
||||
DynareExogNameList* denl;
|
||||
DynareStateNameList* dsnl;
|
||||
ogp::FormulaEvaluator* fe;
|
||||
ogp::FormulaDerEvaluator* fde;
|
||||
const double ss_tol;
|
||||
class Dynare : public DynamicModel
|
||||
{
|
||||
friend class DynareNameList;
|
||||
friend class DynareExogNameList;
|
||||
friend class DynareStateNameList;
|
||||
friend class DynareJacobian;
|
||||
Journal &journal;
|
||||
ogdyn::DynareModel *model;
|
||||
Vector *ysteady;
|
||||
TensorContainer<FSSparseTensor> md;
|
||||
DynareNameList *dnl;
|
||||
DynareExogNameList *denl;
|
||||
DynareStateNameList *dsnl;
|
||||
ogp::FormulaEvaluator *fe;
|
||||
ogp::FormulaDerEvaluator *fde;
|
||||
const double ss_tol;
|
||||
public:
|
||||
/** Parses the given model file and uses the given order to
|
||||
* override order from the model file (if it is != -1). */
|
||||
Dynare(const char* modname, int ord, double sstol, Journal& jr);
|
||||
/** Parses the given equations with explicitly given names. */
|
||||
Dynare(const char** endo, int num_endo,
|
||||
const char** exo, int num_exo,
|
||||
const char** par, int num_par,
|
||||
const char* equations, int len, int ord,
|
||||
double sstol, Journal& jr);
|
||||
/** Makes a deep copy of the object. */
|
||||
Dynare(const Dynare& dyn);
|
||||
DynamicModel* clone() const
|
||||
{return new Dynare(*this);}
|
||||
virtual ~Dynare();
|
||||
int nstat() const
|
||||
{return model->getAtoms().nstat();}
|
||||
int nboth() const
|
||||
{return model->getAtoms().nboth();}
|
||||
int npred() const
|
||||
{return model->getAtoms().npred();}
|
||||
int nforw() const
|
||||
{return model->getAtoms().nforw();}
|
||||
int nexog() const
|
||||
{return model->getAtoms().nexo();}
|
||||
int nys() const
|
||||
{return model->getAtoms().nys();}
|
||||
int nyss() const
|
||||
{return model->getAtoms().nyss();}
|
||||
int ny() const
|
||||
{return model->getAtoms().ny();}
|
||||
int order() const
|
||||
{return model->getOrder();}
|
||||
/** Parses the given model file and uses the given order to
|
||||
* override order from the model file (if it is != -1). */
|
||||
Dynare(const char *modname, int ord, double sstol, Journal &jr);
|
||||
/** Parses the given equations with explicitly given names. */
|
||||
Dynare(const char **endo, int num_endo,
|
||||
const char **exo, int num_exo,
|
||||
const char **par, int num_par,
|
||||
const char *equations, int len, int ord,
|
||||
double sstol, Journal &jr);
|
||||
/** Makes a deep copy of the object. */
|
||||
Dynare(const Dynare &dyn);
|
||||
DynamicModel *
|
||||
clone() const
|
||||
{
|
||||
return new Dynare(*this);
|
||||
}
|
||||
virtual
|
||||
~Dynare();
|
||||
int
|
||||
nstat() const
|
||||
{
|
||||
return model->getAtoms().nstat();
|
||||
}
|
||||
int
|
||||
nboth() const
|
||||
{
|
||||
return model->getAtoms().nboth();
|
||||
}
|
||||
int
|
||||
npred() const
|
||||
{
|
||||
return model->getAtoms().npred();
|
||||
}
|
||||
int
|
||||
nforw() const
|
||||
{
|
||||
return model->getAtoms().nforw();
|
||||
}
|
||||
int
|
||||
nexog() const
|
||||
{
|
||||
return model->getAtoms().nexo();
|
||||
}
|
||||
int
|
||||
nys() const
|
||||
{
|
||||
return model->getAtoms().nys();
|
||||
}
|
||||
int
|
||||
nyss() const
|
||||
{
|
||||
return model->getAtoms().nyss();
|
||||
}
|
||||
int
|
||||
ny() const
|
||||
{
|
||||
return model->getAtoms().ny();
|
||||
}
|
||||
int
|
||||
order() const
|
||||
{
|
||||
return model->getOrder();
|
||||
}
|
||||
|
||||
const NameList& getAllEndoNames() const
|
||||
{return *dnl;}
|
||||
const NameList& getStateNames() const
|
||||
{return *dsnl;}
|
||||
const NameList& getExogNames() const
|
||||
{return *denl;}
|
||||
const NameList &
|
||||
getAllEndoNames() const
|
||||
{
|
||||
return *dnl;
|
||||
}
|
||||
const NameList &
|
||||
getStateNames() const
|
||||
{
|
||||
return *dsnl;
|
||||
}
|
||||
const NameList &
|
||||
getExogNames() const
|
||||
{
|
||||
return *denl;
|
||||
}
|
||||
|
||||
TwoDMatrix& getVcov()
|
||||
{return model->getVcov();}
|
||||
const TwoDMatrix& getVcov() const
|
||||
{return model->getVcov();}
|
||||
Vector& getParams()
|
||||
{return model->getParams();}
|
||||
const Vector& getParams() const
|
||||
{return model->getParams();}
|
||||
void setInitOuter(const Vector& x)
|
||||
{model->setInitOuter(x);}
|
||||
TwoDMatrix &
|
||||
getVcov()
|
||||
{
|
||||
return model->getVcov();
|
||||
}
|
||||
const TwoDMatrix &
|
||||
getVcov() const
|
||||
{
|
||||
return model->getVcov();
|
||||
}
|
||||
Vector &
|
||||
getParams()
|
||||
{
|
||||
return model->getParams();
|
||||
}
|
||||
const Vector &
|
||||
getParams() const
|
||||
{
|
||||
return model->getParams();
|
||||
}
|
||||
void
|
||||
setInitOuter(const Vector &x)
|
||||
{
|
||||
model->setInitOuter(x);
|
||||
}
|
||||
|
||||
const TensorContainer<FSSparseTensor>& getModelDerivatives() const
|
||||
{return md;}
|
||||
const Vector& getSteady() const
|
||||
{return *ysteady;}
|
||||
Vector& getSteady()
|
||||
{return *ysteady;}
|
||||
const ogdyn::DynareModel& getModel() const
|
||||
{return *model;}
|
||||
const TensorContainer<FSSparseTensor> &
|
||||
getModelDerivatives() const
|
||||
{
|
||||
return md;
|
||||
}
|
||||
const Vector &
|
||||
getSteady() const
|
||||
{
|
||||
return *ysteady;
|
||||
}
|
||||
Vector &
|
||||
getSteady()
|
||||
{
|
||||
return *ysteady;
|
||||
}
|
||||
const ogdyn::DynareModel &
|
||||
getModel() const
|
||||
{
|
||||
return *model;
|
||||
}
|
||||
|
||||
// here is true public interface
|
||||
void solveDeterministicSteady(Vector& steady);
|
||||
void solveDeterministicSteady()
|
||||
{solveDeterministicSteady(*ysteady);}
|
||||
void evaluateSystem(Vector& out, const Vector& yy, const Vector& xx);
|
||||
void evaluateSystem(Vector& out, const Vector& yym, const Vector& yy,
|
||||
const Vector& yyp, const Vector& xx);
|
||||
void calcDerivatives(const Vector& yy, const Vector& xx);
|
||||
void calcDerivativesAtSteady();
|
||||
// here is true public interface
|
||||
void solveDeterministicSteady(Vector &steady);
|
||||
void
|
||||
solveDeterministicSteady()
|
||||
{
|
||||
solveDeterministicSteady(*ysteady);
|
||||
}
|
||||
void evaluateSystem(Vector &out, const Vector &yy, const Vector &xx);
|
||||
void evaluateSystem(Vector &out, const Vector &yym, const Vector &yy,
|
||||
const Vector &yyp, const Vector &xx);
|
||||
void calcDerivatives(const Vector &yy, const Vector &xx);
|
||||
void calcDerivativesAtSteady();
|
||||
|
||||
void writeMat(mat_t *fd, const char* prefix) const;
|
||||
void writeDump(const std::string& basename) const;
|
||||
void writeMat(mat_t *fd, const char *prefix) const;
|
||||
void writeDump(const std::string &basename) const;
|
||||
private:
|
||||
void writeModelInfo(Journal& jr) const;
|
||||
void writeModelInfo(Journal &jr) const;
|
||||
};
|
||||
|
||||
class DynareEvalLoader : public ogp::FormulaEvalLoader, public Vector {
|
||||
class DynareEvalLoader : public ogp::FormulaEvalLoader, public Vector
|
||||
{
|
||||
public:
|
||||
DynareEvalLoader(const ogp::FineAtoms& a, Vector& out);
|
||||
void load(int i, double res)
|
||||
{operator[](i) = res;}
|
||||
DynareEvalLoader(const ogp::FineAtoms &a, Vector &out);
|
||||
void
|
||||
load(int i, double res)
|
||||
{
|
||||
operator[](i) = res;
|
||||
}
|
||||
};
|
||||
|
||||
class DynareDerEvalLoader : public ogp::FormulaDerEvalLoader {
|
||||
class DynareDerEvalLoader : public ogp::FormulaDerEvalLoader
|
||||
{
|
||||
protected:
|
||||
const ogp::FineAtoms& atoms;
|
||||
TensorContainer<FSSparseTensor>& md;
|
||||
const ogp::FineAtoms &atoms;
|
||||
TensorContainer<FSSparseTensor> &md;
|
||||
public:
|
||||
DynareDerEvalLoader(const ogp::FineAtoms& a, TensorContainer<FSSparseTensor>& mod_ders,
|
||||
int order);
|
||||
void load(int i, int iord, const int* vars, double res);
|
||||
DynareDerEvalLoader(const ogp::FineAtoms &a, TensorContainer<FSSparseTensor> &mod_ders,
|
||||
int order);
|
||||
void load(int i, int iord, const int *vars, double res);
|
||||
};
|
||||
|
||||
class DynareJacobian : public ogu::Jacobian, public ogp::FormulaDerEvalLoader {
|
||||
class DynareJacobian : public ogu::Jacobian, public ogp::FormulaDerEvalLoader
|
||||
{
|
||||
protected:
|
||||
Dynare& d;
|
||||
Dynare &d;
|
||||
public:
|
||||
DynareJacobian(Dynare& dyn);
|
||||
virtual ~DynareJacobian() {}
|
||||
void load(int i, int iord, const int* vars, double res);
|
||||
void eval(const Vector& in);
|
||||
DynareJacobian(Dynare &dyn);
|
||||
virtual ~DynareJacobian()
|
||||
{
|
||||
}
|
||||
void load(int i, int iord, const int *vars, double res);
|
||||
void eval(const Vector &in);
|
||||
};
|
||||
|
||||
class DynareVectorFunction : public ogu::VectorFunction {
|
||||
class DynareVectorFunction : public ogu::VectorFunction
|
||||
{
|
||||
protected:
|
||||
Dynare& d;
|
||||
Dynare &d;
|
||||
public:
|
||||
DynareVectorFunction(Dynare& dyn)
|
||||
: d(dyn) {}
|
||||
virtual ~DynareVectorFunction() {}
|
||||
int inDim() const
|
||||
{return d.ny();}
|
||||
int outDim() const
|
||||
{return d.ny();}
|
||||
void eval(const ConstVector& in, Vector& out);
|
||||
DynareVectorFunction(Dynare &dyn)
|
||||
: d(dyn)
|
||||
{
|
||||
}
|
||||
virtual ~DynareVectorFunction()
|
||||
{
|
||||
}
|
||||
int
|
||||
inDim() const
|
||||
{
|
||||
return d.ny();
|
||||
}
|
||||
int
|
||||
outDim() const
|
||||
{
|
||||
return d.ny();
|
||||
}
|
||||
void eval(const ConstVector &in, Vector &out);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,196 +15,222 @@
|
|||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace ogdyn {
|
||||
namespace ogdyn
|
||||
{
|
||||
|
||||
using std::map;
|
||||
using std::vector;
|
||||
using std::map;
|
||||
using std::vector;
|
||||
|
||||
/** A definition of a type mapping a string to an integer. Used as
|
||||
* a substitution map, saying what names are substituted for what
|
||||
* expressions represented by tree indices. */
|
||||
typedef map<const char*, int, ogp::ltstr> Tsubstmap;
|
||||
/** A definition of a type mapping a string to an integer. Used as
|
||||
* a substitution map, saying what names are substituted for what
|
||||
* expressions represented by tree indices. */
|
||||
typedef map<const char *, int, ogp::ltstr> Tsubstmap;
|
||||
|
||||
class DynareStaticAtoms : public ogp::StaticAtoms {
|
||||
public:
|
||||
DynareStaticAtoms()
|
||||
: StaticAtoms() {}
|
||||
DynareStaticAtoms(const DynareStaticAtoms& a)
|
||||
: StaticAtoms(a) {}
|
||||
virtual ~DynareStaticAtoms() {}
|
||||
/** This registers a unique varname identifier. It throws an
|
||||
* exception if the variable name is duplicate. It checks the
|
||||
* uniqueness and then it calls StaticAtoms::register_name. */
|
||||
void register_name(const char* name);
|
||||
protected:
|
||||
/** This returns a tree index of the given variable, and if
|
||||
* the variable has not been registered, it throws an
|
||||
* exception. */
|
||||
int check_variable(const char* name) const;
|
||||
};
|
||||
class DynareStaticAtoms : public ogp::StaticAtoms
|
||||
{
|
||||
public:
|
||||
DynareStaticAtoms()
|
||||
: StaticAtoms()
|
||||
{
|
||||
}
|
||||
DynareStaticAtoms(const DynareStaticAtoms &a)
|
||||
: StaticAtoms(a)
|
||||
{
|
||||
}
|
||||
virtual ~DynareStaticAtoms()
|
||||
{
|
||||
}
|
||||
/** This registers a unique varname identifier. It throws an
|
||||
* exception if the variable name is duplicate. It checks the
|
||||
* uniqueness and then it calls StaticAtoms::register_name. */
|
||||
void register_name(const char *name);
|
||||
protected:
|
||||
/** This returns a tree index of the given variable, and if
|
||||
* the variable has not been registered, it throws an
|
||||
* exception. */
|
||||
int check_variable(const char *name) const;
|
||||
};
|
||||
|
||||
class DynareDynamicAtoms : public ogp::SAtoms, public ogp::NularyStringConvertor
|
||||
{
|
||||
public:
|
||||
enum atype {endovar, exovar, param};
|
||||
protected:
|
||||
typedef map<const char *, atype, ogp::ltstr> Tatypemap;
|
||||
/** The map assigining a type to each name. */
|
||||
Tatypemap atom_type;
|
||||
public:
|
||||
DynareDynamicAtoms()
|
||||
: ogp::SAtoms()
|
||||
{
|
||||
}
|
||||
DynareDynamicAtoms(const DynareDynamicAtoms &dda);
|
||||
virtual ~DynareDynamicAtoms()
|
||||
{
|
||||
}
|
||||
/** This parses a variable of the forms: varname(+3),
|
||||
* varname(3), varname, varname(-3), varname(0), varname(+0),
|
||||
* varname(-0). */
|
||||
virtual void parse_variable(const char *in, std::string &out, int &ll) const;
|
||||
/** Registers unique name of endogenous variable. */
|
||||
void register_uniq_endo(const char *name);
|
||||
/** Registers unique name of exogenous variable. */
|
||||
void register_uniq_exo(const char *name);
|
||||
/** Registers unique name of parameter. */
|
||||
void register_uniq_param(const char *name);
|
||||
/** Return true if the name is a given type. */
|
||||
bool is_type(const char *name, atype tp) const;
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
/** Implement NularyStringConvertor::convert. */
|
||||
std::string convert(int t) const;
|
||||
};
|
||||
|
||||
class DynareDynamicAtoms : public ogp::SAtoms, public ogp::NularyStringConvertor {
|
||||
public:
|
||||
enum atype {endovar, exovar, param};
|
||||
protected:
|
||||
typedef map<const char*, atype, ogp::ltstr> Tatypemap;
|
||||
/** The map assigining a type to each name. */
|
||||
Tatypemap atom_type;
|
||||
public:
|
||||
DynareDynamicAtoms()
|
||||
: ogp::SAtoms() {}
|
||||
DynareDynamicAtoms(const DynareDynamicAtoms& dda);
|
||||
virtual ~DynareDynamicAtoms() {}
|
||||
/** This parses a variable of the forms: varname(+3),
|
||||
* varname(3), varname, varname(-3), varname(0), varname(+0),
|
||||
* varname(-0). */
|
||||
virtual void parse_variable(const char* in, std::string& out, int& ll) const;
|
||||
/** Registers unique name of endogenous variable. */
|
||||
void register_uniq_endo(const char* name);
|
||||
/** Registers unique name of exogenous variable. */
|
||||
void register_uniq_exo(const char* name);
|
||||
/** Registers unique name of parameter. */
|
||||
void register_uniq_param(const char* name);
|
||||
/** Return true if the name is a given type. */
|
||||
bool is_type(const char* name, atype tp) const;
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
/** Implement NularyStringConvertor::convert. */
|
||||
std::string convert(int t) const;
|
||||
};
|
||||
/** This class represents the atom values for dynare, where
|
||||
* exogenous variables can occur only at time t, and endogenous at
|
||||
* times t-1, t, and t+1. */
|
||||
class DynareAtomValues : public ogp::AtomValues
|
||||
{
|
||||
protected:
|
||||
/** Reference to the atoms (we suppose that they are only at
|
||||
* t-1,t,t+1. */
|
||||
const ogp::FineAtoms &atoms;
|
||||
/** De facto reference to the values of parameters. */
|
||||
const ConstVector paramvals;
|
||||
/** De facto reference to the values of endogenous at time t-1. Only
|
||||
* predetermined and both part. */
|
||||
const ConstVector yym;
|
||||
/** De facto reference to the values of endogenous at time t. Ordering
|
||||
* given by the atoms. */
|
||||
const ConstVector yy;
|
||||
/** De facto reference to the values of endogenous at time t+1. Only
|
||||
* both and forward looking part. */
|
||||
const ConstVector yyp;
|
||||
/** De facto reference to the values of exogenous at time t. */
|
||||
const ConstVector xx;
|
||||
public:
|
||||
DynareAtomValues(const ogp::FineAtoms &a, const Vector &pvals, const Vector &ym,
|
||||
const Vector &y, const Vector &yp, const Vector &x)
|
||||
: atoms(a), paramvals(pvals), yym(ym), yy(y), yyp(yp), xx(x)
|
||||
{
|
||||
}
|
||||
DynareAtomValues(const ogp::FineAtoms &a, const Vector &pvals, const ConstVector &ym,
|
||||
const Vector &y, const ConstVector &yp, const Vector &x)
|
||||
: atoms(a), paramvals(pvals), yym(ym), yy(y), yyp(yp), xx(x)
|
||||
{
|
||||
}
|
||||
void setValues(ogp::EvalTree &et) const;
|
||||
};
|
||||
|
||||
/** This class represents the atom values at the steady state. It
|
||||
* makes only appropriate subvector yym and yyp of the y vector,
|
||||
* makes a vector of zero exogenous variables and uses
|
||||
* DynareAtomValues with more general interface. */
|
||||
class DynareSteadyAtomValues : public ogp::AtomValues
|
||||
{
|
||||
protected:
|
||||
/** Subvector of yy. */
|
||||
const ConstVector yym;
|
||||
/** Subvector of yy. */
|
||||
const ConstVector yyp;
|
||||
/** Vector of zeros for exogenous variables. */
|
||||
Vector xx;
|
||||
/** Atom values using this yym, yyp and xx. */
|
||||
DynareAtomValues av;
|
||||
public:
|
||||
DynareSteadyAtomValues(const ogp::FineAtoms &a, const Vector &pvals, const Vector &y)
|
||||
: yym(y, a.nstat(), a.nys()),
|
||||
yyp(y, a.nstat()+a.npred(), a.nyss()),
|
||||
xx(a.nexo()),
|
||||
av(a, pvals, yym, y, yyp, xx)
|
||||
{
|
||||
xx.zeros();
|
||||
}
|
||||
void
|
||||
setValues(ogp::EvalTree &et) const
|
||||
{
|
||||
av.setValues(et);
|
||||
}
|
||||
};
|
||||
|
||||
/** This class represents the atom values for dynare, where
|
||||
* exogenous variables can occur only at time t, and endogenous at
|
||||
* times t-1, t, and t+1. */
|
||||
class DynareAtomValues : public ogp::AtomValues {
|
||||
protected:
|
||||
/** Reference to the atoms (we suppose that they are only at
|
||||
* t-1,t,t+1. */
|
||||
const ogp::FineAtoms& atoms;
|
||||
/** De facto reference to the values of parameters. */
|
||||
const ConstVector paramvals;
|
||||
/** De facto reference to the values of endogenous at time t-1. Only
|
||||
* predetermined and both part. */
|
||||
const ConstVector yym;
|
||||
/** De facto reference to the values of endogenous at time t. Ordering
|
||||
* given by the atoms. */
|
||||
const ConstVector yy;
|
||||
/** De facto reference to the values of endogenous at time t+1. Only
|
||||
* both and forward looking part. */
|
||||
const ConstVector yyp;
|
||||
/** De facto reference to the values of exogenous at time t. */
|
||||
const ConstVector xx;
|
||||
public:
|
||||
DynareAtomValues(const ogp::FineAtoms& a, const Vector& pvals, const Vector& ym,
|
||||
const Vector& y, const Vector& yp, const Vector& x)
|
||||
: atoms(a), paramvals(pvals), yym(ym), yy(y), yyp(yp), xx(x) {}
|
||||
DynareAtomValues(const ogp::FineAtoms& a, const Vector& pvals, const ConstVector& ym,
|
||||
const Vector& y, const ConstVector& yp, const Vector& x)
|
||||
: atoms(a), paramvals(pvals), yym(ym), yy(y), yyp(yp), xx(x) {}
|
||||
void setValues(ogp::EvalTree& et) const;
|
||||
};
|
||||
class DynareStaticSteadyAtomValues : public ogp::AtomValues
|
||||
{
|
||||
protected:
|
||||
/** Reference to static atoms over which the tree, where the
|
||||
* values go, is defined. */
|
||||
const ogp::StaticFineAtoms &atoms_static;
|
||||
/** Reference to dynamic atoms for which the class gets input
|
||||
* data. */
|
||||
const ogp::FineAtoms &atoms;
|
||||
/** De facto reference to input data, this is a vector of
|
||||
* endogenous variables in internal ordering of the dynamic
|
||||
* atoms. */
|
||||
ConstVector yy;
|
||||
/** De facto reference to input parameters corresponding to
|
||||
* ordering defined by the dynamic atoms. */
|
||||
ConstVector paramvals;
|
||||
public:
|
||||
/** Construct the object. */
|
||||
DynareStaticSteadyAtomValues(const ogp::FineAtoms &a, const ogp::StaticFineAtoms &sa,
|
||||
const Vector &pvals, const Vector &yyy)
|
||||
: atoms_static(sa),
|
||||
atoms(a),
|
||||
yy(yyy),
|
||||
paramvals(pvals)
|
||||
{
|
||||
}
|
||||
/** Set the values to the tree defined over the static atoms. */
|
||||
void setValues(ogp::EvalTree &et) const;
|
||||
};
|
||||
|
||||
/** This class represents the atom values at the steady state. It
|
||||
* makes only appropriate subvector yym and yyp of the y vector,
|
||||
* makes a vector of zero exogenous variables and uses
|
||||
* DynareAtomValues with more general interface. */
|
||||
class DynareSteadyAtomValues : public ogp::AtomValues {
|
||||
protected:
|
||||
/** Subvector of yy. */
|
||||
const ConstVector yym;
|
||||
/** Subvector of yy. */
|
||||
const ConstVector yyp;
|
||||
/** Vector of zeros for exogenous variables. */
|
||||
Vector xx;
|
||||
/** Atom values using this yym, yyp and xx. */
|
||||
DynareAtomValues av;
|
||||
public:
|
||||
DynareSteadyAtomValues(const ogp::FineAtoms& a, const Vector& pvals, const Vector& y)
|
||||
: yym(y, a.nstat(), a.nys()),
|
||||
yyp(y, a.nstat()+a.npred(), a.nyss()),
|
||||
xx(a.nexo()),
|
||||
av(a, pvals, yym, y, yyp, xx)
|
||||
{xx.zeros();}
|
||||
void setValues(ogp::EvalTree& et) const
|
||||
{av.setValues(et);}
|
||||
};
|
||||
/** This class takes a vector of endogenous variables and a
|
||||
* substitution map. It supposes that variables at the right hand
|
||||
* sides of the substitutions are set in the endogenous vector. It
|
||||
* evaluates the substitutions and if the variables corresponding
|
||||
* to left hand sides are not set in the endogenous vector it sets
|
||||
* them to calculated values. If a variable is already set, it
|
||||
* does not override its value. It has no methods, everything is
|
||||
* done in the constructor. */
|
||||
class DynareSteadySubstitutions : public ogp::FormulaEvalLoader
|
||||
{
|
||||
protected:
|
||||
const ogp::FineAtoms &atoms;
|
||||
public:
|
||||
DynareSteadySubstitutions(const ogp::FineAtoms &a, const ogp::OperationTree &tree,
|
||||
const Tsubstmap &subst,
|
||||
const Vector &pvals, Vector &yy);
|
||||
void load(int i, double res);
|
||||
protected:
|
||||
Vector &y;
|
||||
vector<const char *> left_hand_sides;
|
||||
vector<int> right_hand_sides;
|
||||
};
|
||||
|
||||
class DynareStaticSteadyAtomValues : public ogp::AtomValues {
|
||||
protected:
|
||||
/** Reference to static atoms over which the tree, where the
|
||||
* values go, is defined. */
|
||||
const ogp::StaticFineAtoms& atoms_static;
|
||||
/** Reference to dynamic atoms for which the class gets input
|
||||
* data. */
|
||||
const ogp::FineAtoms& atoms;
|
||||
/** De facto reference to input data, this is a vector of
|
||||
* endogenous variables in internal ordering of the dynamic
|
||||
* atoms. */
|
||||
ConstVector yy;
|
||||
/** De facto reference to input parameters corresponding to
|
||||
* ordering defined by the dynamic atoms. */
|
||||
ConstVector paramvals;
|
||||
public:
|
||||
/** Construct the object. */
|
||||
DynareStaticSteadyAtomValues(const ogp::FineAtoms& a, const ogp::StaticFineAtoms& sa,
|
||||
const Vector& pvals, const Vector& yyy)
|
||||
: atoms_static(sa),
|
||||
atoms(a),
|
||||
yy(yyy),
|
||||
paramvals(pvals) {}
|
||||
/** Set the values to the tree defined over the static atoms. */
|
||||
void setValues(ogp::EvalTree& et) const;
|
||||
};
|
||||
|
||||
/** This class takes a vector of endogenous variables and a
|
||||
* substitution map. It supposes that variables at the right hand
|
||||
* sides of the substitutions are set in the endogenous vector. It
|
||||
* evaluates the substitutions and if the variables corresponding
|
||||
* to left hand sides are not set in the endogenous vector it sets
|
||||
* them to calculated values. If a variable is already set, it
|
||||
* does not override its value. It has no methods, everything is
|
||||
* done in the constructor. */
|
||||
class DynareSteadySubstitutions : public ogp::FormulaEvalLoader {
|
||||
protected:
|
||||
const ogp::FineAtoms& atoms;
|
||||
public:
|
||||
DynareSteadySubstitutions(const ogp::FineAtoms& a, const ogp::OperationTree& tree,
|
||||
const Tsubstmap& subst,
|
||||
const Vector& pvals, Vector& yy);
|
||||
void load(int i, double res);
|
||||
protected:
|
||||
Vector& y;
|
||||
vector<const char*> left_hand_sides;
|
||||
vector<int> right_hand_sides;
|
||||
};
|
||||
|
||||
/** This class is a static version of DynareSteadySustitutions. It
|
||||
* works for static atoms and static tree and substitution map
|
||||
* over the static tree. It also needs dynamic version of the
|
||||
* atoms, since it defines ordering of the vectors pvals, and
|
||||
* yy. */
|
||||
class DynareStaticSteadySubstitutions : public ogp::FormulaEvalLoader {
|
||||
protected:
|
||||
const ogp::FineAtoms& atoms;
|
||||
const ogp::StaticFineAtoms& atoms_static;
|
||||
public:
|
||||
DynareStaticSteadySubstitutions(const ogp::FineAtoms& a,
|
||||
const ogp::StaticFineAtoms& sa,
|
||||
const ogp::OperationTree& tree,
|
||||
const Tsubstmap& subst,
|
||||
const Vector& pvals, Vector& yy);
|
||||
void load(int i, double res);
|
||||
protected:
|
||||
Vector& y;
|
||||
vector<const char*> left_hand_sides;
|
||||
vector<int> right_hand_sides;
|
||||
};
|
||||
/** This class is a static version of DynareSteadySustitutions. It
|
||||
* works for static atoms and static tree and substitution map
|
||||
* over the static tree. It also needs dynamic version of the
|
||||
* atoms, since it defines ordering of the vectors pvals, and
|
||||
* yy. */
|
||||
class DynareStaticSteadySubstitutions : public ogp::FormulaEvalLoader
|
||||
{
|
||||
protected:
|
||||
const ogp::FineAtoms &atoms;
|
||||
const ogp::StaticFineAtoms &atoms_static;
|
||||
public:
|
||||
DynareStaticSteadySubstitutions(const ogp::FineAtoms &a,
|
||||
const ogp::StaticFineAtoms &sa,
|
||||
const ogp::OperationTree &tree,
|
||||
const Tsubstmap &subst,
|
||||
const Vector &pvals, Vector &yy);
|
||||
void load(int i, double res);
|
||||
protected:
|
||||
Vector &y;
|
||||
vector<const char *> left_hand_sides;
|
||||
vector<int> right_hand_sides;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -7,31 +7,39 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
class DynareException {
|
||||
char* mes;
|
||||
class DynareException
|
||||
{
|
||||
char *mes;
|
||||
public:
|
||||
DynareException(const char* m, const char* fname, int line, int col)
|
||||
{
|
||||
mes = new char[strlen(m) + strlen(fname) + 100];
|
||||
sprintf(mes, "Parse error at %s, line %d, column %d: %s", fname, line, col, m);
|
||||
}
|
||||
DynareException(const char* fname, int line, const std::string& m)
|
||||
{
|
||||
mes = new char[m.size() + strlen(fname) + 50];
|
||||
sprintf(mes, "%s:%d: %s", fname, line, m.c_str());
|
||||
}
|
||||
DynareException(const char* m, int offset)
|
||||
{
|
||||
mes = new char[strlen(m) + 100];
|
||||
sprintf(mes, "Parse error in provided string at offset %d: %s", offset, m);
|
||||
}
|
||||
DynareException(const DynareException& e)
|
||||
: mes(new char[strlen(e.mes)+1])
|
||||
{strcpy(mes, e.mes);}
|
||||
virtual ~DynareException()
|
||||
{delete [] mes;}
|
||||
const char* message() const
|
||||
{return mes;}
|
||||
DynareException(const char *m, const char *fname, int line, int col)
|
||||
{
|
||||
mes = new char[strlen(m) + strlen(fname) + 100];
|
||||
sprintf(mes, "Parse error at %s, line %d, column %d: %s", fname, line, col, m);
|
||||
}
|
||||
DynareException(const char *fname, int line, const std::string &m)
|
||||
{
|
||||
mes = new char[m.size() + strlen(fname) + 50];
|
||||
sprintf(mes, "%s:%d: %s", fname, line, m.c_str());
|
||||
}
|
||||
DynareException(const char *m, int offset)
|
||||
{
|
||||
mes = new char[strlen(m) + 100];
|
||||
sprintf(mes, "Parse error in provided string at offset %d: %s", offset, m);
|
||||
}
|
||||
DynareException(const DynareException &e)
|
||||
: mes(new char[strlen(e.mes)+1])
|
||||
{
|
||||
strcpy(mes, e.mes);
|
||||
}
|
||||
virtual ~DynareException()
|
||||
{
|
||||
delete [] mes;
|
||||
}
|
||||
const char *
|
||||
message() const
|
||||
{
|
||||
return mes;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,377 +15,463 @@
|
|||
#include <map>
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
namespace ogdyn {
|
||||
using boost::unordered_set;
|
||||
using std::map;
|
||||
namespace ogdyn
|
||||
{
|
||||
using boost::unordered_set;
|
||||
using std::map;
|
||||
|
||||
/** This represents an interval in a string by the pair of
|
||||
* positions (including the first, excluding the second). A
|
||||
* position is given by the line and the column within the line
|
||||
* (both starting from 1). */
|
||||
struct PosInterval {
|
||||
int fl;
|
||||
int fc;
|
||||
int ll;
|
||||
int lc;
|
||||
PosInterval() {}
|
||||
PosInterval(int ifl, int ifc, int ill, int ilc)
|
||||
: fl(ifl), fc(ifc), ll(ill), lc(ilc) {}
|
||||
const PosInterval& operator=(const PosInterval& pi)
|
||||
{fl = pi.fl; fc = pi.fc; ll = pi.ll; lc = pi.lc; return *this;}
|
||||
/** This returns the interval beginning and interval length
|
||||
* within the given string. */
|
||||
void translate(const char* beg, int len, const char*& ibeg, int& ilen) const;
|
||||
/** Debug print. */
|
||||
void print() const
|
||||
{printf("fl=%d fc=%d ll=%d lc=%d\n",fl,fc,ll,lc);}
|
||||
};
|
||||
/** This represents an interval in a string by the pair of
|
||||
* positions (including the first, excluding the second). A
|
||||
* position is given by the line and the column within the line
|
||||
* (both starting from 1). */
|
||||
struct PosInterval
|
||||
{
|
||||
int fl;
|
||||
int fc;
|
||||
int ll;
|
||||
int lc;
|
||||
PosInterval()
|
||||
{
|
||||
}
|
||||
PosInterval(int ifl, int ifc, int ill, int ilc)
|
||||
: fl(ifl), fc(ifc), ll(ill), lc(ilc)
|
||||
{
|
||||
}
|
||||
const PosInterval &
|
||||
operator=(const PosInterval &pi)
|
||||
{
|
||||
fl = pi.fl; fc = pi.fc; ll = pi.ll; lc = pi.lc; return *this;
|
||||
}
|
||||
/** This returns the interval beginning and interval length
|
||||
* within the given string. */
|
||||
void translate(const char *beg, int len, const char * &ibeg, int &ilen) const;
|
||||
/** Debug print. */
|
||||
void
|
||||
print() const
|
||||
{
|
||||
printf("fl=%d fc=%d ll=%d lc=%d\n", fl, fc, ll, lc);
|
||||
}
|
||||
};
|
||||
|
||||
/** This class is basically a GeneralMatrix but is created from
|
||||
* parsed matrix data. */
|
||||
class ParsedMatrix : public TwoDMatrix {
|
||||
public:
|
||||
/** Construct the object from the parsed data of ogp::MatrixParser. */
|
||||
ParsedMatrix(const ogp::MatrixParser& mp);
|
||||
};
|
||||
/** This class is basically a GeneralMatrix but is created from
|
||||
* parsed matrix data. */
|
||||
class ParsedMatrix : public TwoDMatrix
|
||||
{
|
||||
public:
|
||||
/** Construct the object from the parsed data of ogp::MatrixParser. */
|
||||
ParsedMatrix(const ogp::MatrixParser &mp);
|
||||
};
|
||||
|
||||
class PlannerBuilder;
|
||||
class PlannerInfo;
|
||||
class ForwSubstBuilder;
|
||||
class ForwSubstInfo;
|
||||
class MultInitSS;
|
||||
class ModelSSWriter;
|
||||
|
||||
class PlannerBuilder;
|
||||
class PlannerInfo;
|
||||
class ForwSubstBuilder;
|
||||
class ForwSubstInfo;
|
||||
class MultInitSS;
|
||||
class ModelSSWriter;
|
||||
/** A subclass is responsible for creating param_vals, init_vals,
|
||||
* and vcov_mat. */
|
||||
class DynareModel
|
||||
{
|
||||
friend class PlannerBuilder;
|
||||
friend class ForwSubstBuilder;
|
||||
friend class MultInitSS;
|
||||
friend class ModelSSWriter;
|
||||
protected:
|
||||
/** All atoms for whole model. */
|
||||
DynareDynamicAtoms atoms;
|
||||
/** Parsed model equations. */
|
||||
ogp::FormulaParser eqs;
|
||||
/** Order of approximation. */
|
||||
int order;
|
||||
/** A vector of parameters values created by a subclass. It
|
||||
* is stored with natural ordering (outer) of the parameters
|
||||
* given by atoms. */
|
||||
Vector *param_vals;
|
||||
/** A vector of initial values created by a subclass. It is
|
||||
* stored with internal ordering given by atoms. */
|
||||
Vector *init_vals;
|
||||
/** A matrix for vcov. It is created by a subclass. */
|
||||
TwoDMatrix *vcov_mat;
|
||||
/** Tree index of the planner objective. If there was no
|
||||
* planner objective keyword, the value is set to -1. */
|
||||
int t_plobjective;
|
||||
/** Tree index of the planner discount. If there was no
|
||||
* planner discount keyword, the value is set to -1. */
|
||||
int t_pldiscount;
|
||||
/** Pointer to PlannerBuilder, which is created only if the
|
||||
* planner's FOC are added to the model. */
|
||||
PlannerBuilder *pbuilder;
|
||||
/** Pointer to an object which builds auxiliary variables and
|
||||
* equations to rewrite a model containing multiple leads to
|
||||
* an equivalent model having only +1 leads. */
|
||||
ForwSubstBuilder *fbuilder;
|
||||
/** Pointer to AtomSubstitutions which are created when the
|
||||
* atoms are being substituted because of multiple lags
|
||||
* etc. It uses also an old copy of atoms, which is
|
||||
* created. */
|
||||
ogp::AtomSubstitutions *atom_substs;
|
||||
/** Pointer to a copy of original atoms before substitutions
|
||||
* took place. */
|
||||
ogp::SAtoms *old_atoms;
|
||||
public:
|
||||
/** Initializes the object to an empty state. */
|
||||
DynareModel();
|
||||
/** Construct a new deep copy. */
|
||||
DynareModel(const DynareModel &dm);
|
||||
virtual
|
||||
~DynareModel();
|
||||
virtual DynareModel *clone() const = 0;
|
||||
const DynareDynamicAtoms &
|
||||
getAtoms() const
|
||||
{
|
||||
return atoms;
|
||||
}
|
||||
const ogp::FormulaParser &
|
||||
getParser() const
|
||||
{
|
||||
return eqs;
|
||||
}
|
||||
int
|
||||
getOrder() const
|
||||
{
|
||||
return order;
|
||||
}
|
||||
/** Return the vector of parameter values. */
|
||||
const Vector &
|
||||
getParams() const
|
||||
{
|
||||
return *param_vals;
|
||||
}
|
||||
Vector &
|
||||
getParams()
|
||||
{
|
||||
return *param_vals;
|
||||
}
|
||||
/** Return the vector of initial values of endo variables. */
|
||||
const Vector &
|
||||
getInit() const
|
||||
{
|
||||
return *init_vals;
|
||||
}
|
||||
Vector &
|
||||
getInit()
|
||||
{
|
||||
return *init_vals;
|
||||
}
|
||||
/** Return the vcov matrix. */
|
||||
const TwoDMatrix &
|
||||
getVcov() const
|
||||
{
|
||||
return *vcov_mat;
|
||||
}
|
||||
TwoDMatrix &
|
||||
getVcov()
|
||||
{
|
||||
return *vcov_mat;
|
||||
}
|
||||
/** Return planner info. */
|
||||
const PlannerInfo *get_planner_info() const;
|
||||
/** Return forward substitutions info. */
|
||||
const ForwSubstInfo *get_forw_subst_info() const;
|
||||
/** Return substitutions info. */
|
||||
const ogp::SubstInfo *get_subst_info() const;
|
||||
/** This sets initial values given in outer ordering. */
|
||||
void setInitOuter(const Vector &x);
|
||||
/** This returns true if the given term is a function of
|
||||
* hardwired constants, numerical constants and parameters. */
|
||||
bool is_constant_term(int t) const;
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
/** Dump the model to the output stream. This includes
|
||||
* variable declarations, parameter values, model code,
|
||||
* initval, vcov and order. */
|
||||
void dump_model(std::ostream &os) const;
|
||||
protected:
|
||||
/** Adds a name of endogenous, exogenous or a parameter. The
|
||||
* sort is governed by the flag. See dynglob.y for values of
|
||||
* the flag. This is used by a subclass when declaring the
|
||||
* names. */
|
||||
void add_name(const char *name, int flag);
|
||||
/** This checks the model consistency. Thus includes: number
|
||||
* of endo variables and number of equations, min and max lag
|
||||
* of endogenous variables and occurrrences of exogenous
|
||||
* variables. It throws an exception, if there is a problem. */
|
||||
void check_model() const;
|
||||
/** This shifts the given variable identified by the tree
|
||||
* index in time. So if the given tree index represents a(+3)
|
||||
* and the tshift is -4, the method returns tree index of the
|
||||
* a(-1). If a(-1) doesn't exist, it is added to the tree. If
|
||||
* it exists, its tree index is returned. If the tree index
|
||||
* doesn't correspond to an endogenous nor exogenous variable,
|
||||
* an exception is thrown. */
|
||||
int variable_shift(int t, int tshift);
|
||||
/** For the given set of atoms identified by tree indices and
|
||||
* given time shift, this method returns a map mapping each
|
||||
* variable in the given set to its time shifted variable. The
|
||||
* map is passed through the reference and is cleared in the
|
||||
* beginning. */
|
||||
void variable_shift_map(const unordered_set<int> &a_set, int tshift,
|
||||
map<int, int> &s_map);
|
||||
/** This returns maximum lead and minimum lag of an endogenous
|
||||
* or exogenous variable in the given term. If there are no
|
||||
* endo or exo variables, than it returns the least integer as
|
||||
* max lead and the greatest integer as min lag. */
|
||||
void termspan(int t, int &mlead, int &mlag) const;
|
||||
/** This function returns a set of non-linear subterms of the
|
||||
* given term, these are terms whose linear combination
|
||||
* constitutes the given term. */
|
||||
unordered_set<int> get_nonlinear_subterms(int t) const;
|
||||
/** This method assigns already used tree index of some term
|
||||
* to the not-yet used atom name with the given lead/lag. In
|
||||
* this way, all occurrences of term t are substituted with
|
||||
* the atom name(ll). The method handles also rewriting
|
||||
* operation tree including derivatives of the term t. */
|
||||
void substitute_atom_for_term(const char *name, int ll, int t);
|
||||
/** This performs a final job after the model is parsed. It
|
||||
* creates the PlannerBuilder object if the planner's FOC are
|
||||
* needed, then it creates ForwSubstBuilder handling multiple
|
||||
* leads and finally it creates the substitution object saving
|
||||
* old atoms and performs the substitutions. */
|
||||
void final_job();
|
||||
};
|
||||
|
||||
/** A subclass is responsible for creating param_vals, init_vals,
|
||||
* and vcov_mat. */
|
||||
class DynareModel {
|
||||
friend class PlannerBuilder;
|
||||
friend class ForwSubstBuilder;
|
||||
friend class MultInitSS;
|
||||
friend class ModelSSWriter;
|
||||
protected:
|
||||
/** All atoms for whole model. */
|
||||
DynareDynamicAtoms atoms;
|
||||
/** Parsed model equations. */
|
||||
ogp::FormulaParser eqs;
|
||||
/** Order of approximation. */
|
||||
int order;
|
||||
/** A vector of parameters values created by a subclass. It
|
||||
* is stored with natural ordering (outer) of the parameters
|
||||
* given by atoms. */
|
||||
Vector* param_vals;
|
||||
/** A vector of initial values created by a subclass. It is
|
||||
* stored with internal ordering given by atoms. */
|
||||
Vector* init_vals;
|
||||
/** A matrix for vcov. It is created by a subclass. */
|
||||
TwoDMatrix* vcov_mat;
|
||||
/** Tree index of the planner objective. If there was no
|
||||
* planner objective keyword, the value is set to -1. */
|
||||
int t_plobjective;
|
||||
/** Tree index of the planner discount. If there was no
|
||||
* planner discount keyword, the value is set to -1. */
|
||||
int t_pldiscount;
|
||||
/** Pointer to PlannerBuilder, which is created only if the
|
||||
* planner's FOC are added to the model. */
|
||||
PlannerBuilder* pbuilder;
|
||||
/** Pointer to an object which builds auxiliary variables and
|
||||
* equations to rewrite a model containing multiple leads to
|
||||
* an equivalent model having only +1 leads. */
|
||||
ForwSubstBuilder* fbuilder;
|
||||
/** Pointer to AtomSubstitutions which are created when the
|
||||
* atoms are being substituted because of multiple lags
|
||||
* etc. It uses also an old copy of atoms, which is
|
||||
* created. */
|
||||
ogp::AtomSubstitutions* atom_substs;
|
||||
/** Pointer to a copy of original atoms before substitutions
|
||||
* took place. */
|
||||
ogp::SAtoms* old_atoms;
|
||||
public:
|
||||
/** Initializes the object to an empty state. */
|
||||
DynareModel();
|
||||
/** Construct a new deep copy. */
|
||||
DynareModel(const DynareModel& dm);
|
||||
virtual ~DynareModel();
|
||||
virtual DynareModel* clone() const = 0;
|
||||
const DynareDynamicAtoms& getAtoms() const
|
||||
{return atoms;}
|
||||
const ogp::FormulaParser& getParser() const
|
||||
{return eqs;}
|
||||
int getOrder() const
|
||||
{return order;}
|
||||
/** Return the vector of parameter values. */
|
||||
const Vector& getParams() const
|
||||
{return *param_vals;}
|
||||
Vector& getParams()
|
||||
{return *param_vals;}
|
||||
/** Return the vector of initial values of endo variables. */
|
||||
const Vector& getInit() const
|
||||
{return *init_vals;}
|
||||
Vector& getInit()
|
||||
{return *init_vals;}
|
||||
/** Return the vcov matrix. */
|
||||
const TwoDMatrix& getVcov() const
|
||||
{return *vcov_mat;}
|
||||
TwoDMatrix& getVcov()
|
||||
{return *vcov_mat;}
|
||||
/** Return planner info. */
|
||||
const PlannerInfo* get_planner_info() const;
|
||||
/** Return forward substitutions info. */
|
||||
const ForwSubstInfo* get_forw_subst_info() const;
|
||||
/** Return substitutions info. */
|
||||
const ogp::SubstInfo* get_subst_info() const;
|
||||
/** This sets initial values given in outer ordering. */
|
||||
void setInitOuter(const Vector& x);
|
||||
/** This returns true if the given term is a function of
|
||||
* hardwired constants, numerical constants and parameters. */
|
||||
bool is_constant_term(int t) const;
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
/** Dump the model to the output stream. This includes
|
||||
* variable declarations, parameter values, model code,
|
||||
* initval, vcov and order. */
|
||||
void dump_model(std::ostream& os) const;
|
||||
protected:
|
||||
/** Adds a name of endogenous, exogenous or a parameter. The
|
||||
* sort is governed by the flag. See dynglob.y for values of
|
||||
* the flag. This is used by a subclass when declaring the
|
||||
* names. */
|
||||
void add_name(const char* name, int flag);
|
||||
/** This checks the model consistency. Thus includes: number
|
||||
* of endo variables and number of equations, min and max lag
|
||||
* of endogenous variables and occurrrences of exogenous
|
||||
* variables. It throws an exception, if there is a problem. */
|
||||
void check_model() const;
|
||||
/** This shifts the given variable identified by the tree
|
||||
* index in time. So if the given tree index represents a(+3)
|
||||
* and the tshift is -4, the method returns tree index of the
|
||||
* a(-1). If a(-1) doesn't exist, it is added to the tree. If
|
||||
* it exists, its tree index is returned. If the tree index
|
||||
* doesn't correspond to an endogenous nor exogenous variable,
|
||||
* an exception is thrown. */
|
||||
int variable_shift(int t, int tshift);
|
||||
/** For the given set of atoms identified by tree indices and
|
||||
* given time shift, this method returns a map mapping each
|
||||
* variable in the given set to its time shifted variable. The
|
||||
* map is passed through the reference and is cleared in the
|
||||
* beginning. */
|
||||
void variable_shift_map(const unordered_set<int>& a_set, int tshift,
|
||||
map<int,int>& s_map);
|
||||
/** This returns maximum lead and minimum lag of an endogenous
|
||||
* or exogenous variable in the given term. If there are no
|
||||
* endo or exo variables, than it returns the least integer as
|
||||
* max lead and the greatest integer as min lag. */
|
||||
void termspan(int t, int& mlead, int& mlag) const;
|
||||
/** This function returns a set of non-linear subterms of the
|
||||
* given term, these are terms whose linear combination
|
||||
* constitutes the given term. */
|
||||
unordered_set<int> get_nonlinear_subterms(int t) const;
|
||||
/** This method assigns already used tree index of some term
|
||||
* to the not-yet used atom name with the given lead/lag. In
|
||||
* this way, all occurrences of term t are substituted with
|
||||
* the atom name(ll). The method handles also rewriting
|
||||
* operation tree including derivatives of the term t. */
|
||||
void substitute_atom_for_term(const char* name, int ll, int t);
|
||||
/** This performs a final job after the model is parsed. It
|
||||
* creates the PlannerBuilder object if the planner's FOC are
|
||||
* needed, then it creates ForwSubstBuilder handling multiple
|
||||
* leads and finally it creates the substitution object saving
|
||||
* old atoms and performs the substitutions. */
|
||||
void final_job();
|
||||
};
|
||||
/** This class constructs DynareModel from dynare++ model file. It
|
||||
* parses variable declarations, model equations, parameter
|
||||
* assignments, initval assignments, vcov matrix and order of
|
||||
* approximation. */
|
||||
class DynareParser : public DynareModel
|
||||
{
|
||||
protected:
|
||||
/** Static atoms for parameter assignments. */
|
||||
DynareStaticAtoms pa_atoms;
|
||||
/** Assignments for the parameters. */
|
||||
ogp::AtomAssignings paramset;
|
||||
/** Static atoms for initval assignments. */
|
||||
DynareStaticAtoms ia_atoms;
|
||||
/** Assignments for the initval. */
|
||||
ogp::AtomAssignings initval;
|
||||
/** Matrix parser for vcov. */
|
||||
ogp::MatrixParser vcov;
|
||||
public:
|
||||
/** This, in fact, creates DynareModel from the given string
|
||||
* of the given length corresponding to the Dynare++ model
|
||||
* file. If the given ord is not -1, then it overrides setting
|
||||
* in the model file. */
|
||||
DynareParser(const char *str, int len, int ord);
|
||||
DynareParser(const DynareParser &p);
|
||||
virtual
|
||||
~DynareParser();
|
||||
DynareModel *
|
||||
clone() const
|
||||
{
|
||||
return new DynareParser(*this);
|
||||
}
|
||||
/** Adds a name of endogenous, exogenous or a parameter. This
|
||||
* addss the name to the parent class DynareModel and also
|
||||
* registers the name to either paramset, or initval. */
|
||||
void add_name(const char *name, int flag);
|
||||
/** Sets position of the model section. Called from
|
||||
* dynglob.y. */
|
||||
void
|
||||
set_model_pos(int off1, int off2)
|
||||
{
|
||||
model_beg = off1; model_end = off2;
|
||||
}
|
||||
/** Sets position of the section setting parameters. Called
|
||||
* from dynglob.y. */
|
||||
void
|
||||
set_paramset_pos(int off1, int off2)
|
||||
{
|
||||
paramset_beg = off1; paramset_end = off2;
|
||||
}
|
||||
/** Sets position of the initval section. Called from
|
||||
* dynglob.y. */
|
||||
void
|
||||
set_initval_pos(int off1, int off2)
|
||||
{
|
||||
initval_beg = off1; initval_end = off2;
|
||||
}
|
||||
/** Sets position of the vcov section. Called from
|
||||
* dynglob.y. */
|
||||
void
|
||||
set_vcov_pos(int off1, int off2)
|
||||
{
|
||||
vcov_beg = off1; vcov_end = off2;
|
||||
}
|
||||
/** Parser the given string as integer and set to as the
|
||||
* order. */
|
||||
void
|
||||
set_order_pos(int off1, int off2)
|
||||
{
|
||||
order_beg = off1; order_end = off2;
|
||||
}
|
||||
/** Sets position of the planner_objective section. Called
|
||||
* from dynglob.y. */
|
||||
void
|
||||
set_pl_objective_pos(int off1, int off2)
|
||||
{
|
||||
plobjective_beg = off1; plobjective_end = off2;
|
||||
}
|
||||
/** Sets position of the planner_discount section. Called from
|
||||
* dynglob.y. */
|
||||
void
|
||||
set_pl_discount_pos(int off1, int off2)
|
||||
{
|
||||
pldiscount_beg = off1; pldiscount_end = off2;
|
||||
}
|
||||
/** Processes a syntax error from bison. */
|
||||
void error(const char *mes);
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
protected:
|
||||
void parse_glob(int length, const char *stream);
|
||||
int parse_order(int length, const char *stream);
|
||||
int parse_pldiscount(int length, const char *stream);
|
||||
/** Evaluate paramset assignings and set param_vals. */
|
||||
void calc_params();
|
||||
/** Evaluate initval assignings and set init_vals. */
|
||||
void calc_init();
|
||||
/** Do the final job. This includes building the planner
|
||||
* problem (if any) and substituting for multiple lags, and
|
||||
* one period leads of exogenous variables, and calculating
|
||||
* initial guess of lagrange multipliers in the social planner
|
||||
* problem. Precondtion: everything parsed and calculated
|
||||
* parameters, postcondition: calculated initvals vector and
|
||||
* parsing_finished for expanded vectors. */
|
||||
void final_job();
|
||||
private:
|
||||
int model_beg, model_end;
|
||||
int paramset_beg, paramset_end;
|
||||
int initval_beg, initval_end;
|
||||
int vcov_beg, vcov_end;
|
||||
int order_beg, order_end;
|
||||
int plobjective_beg, plobjective_end;
|
||||
int pldiscount_beg, pldiscount_end;
|
||||
};
|
||||
|
||||
/** This class constructs DynareModel from dynare++ model file. It
|
||||
* parses variable declarations, model equations, parameter
|
||||
* assignments, initval assignments, vcov matrix and order of
|
||||
* approximation. */
|
||||
class DynareParser : public DynareModel {
|
||||
protected:
|
||||
/** Static atoms for parameter assignments. */
|
||||
DynareStaticAtoms pa_atoms;
|
||||
/** Assignments for the parameters. */
|
||||
ogp::AtomAssignings paramset;
|
||||
/** Static atoms for initval assignments. */
|
||||
DynareStaticAtoms ia_atoms;
|
||||
/** Assignments for the initval. */
|
||||
ogp::AtomAssignings initval;
|
||||
/** Matrix parser for vcov. */
|
||||
ogp::MatrixParser vcov;
|
||||
public:
|
||||
/** This, in fact, creates DynareModel from the given string
|
||||
* of the given length corresponding to the Dynare++ model
|
||||
* file. If the given ord is not -1, then it overrides setting
|
||||
* in the model file. */
|
||||
DynareParser(const char* str, int len, int ord);
|
||||
DynareParser(const DynareParser& p);
|
||||
virtual ~DynareParser();
|
||||
DynareModel* clone() const
|
||||
{return new DynareParser(*this);}
|
||||
/** Adds a name of endogenous, exogenous or a parameter. This
|
||||
* addss the name to the parent class DynareModel and also
|
||||
* registers the name to either paramset, or initval. */
|
||||
void add_name(const char* name, int flag);
|
||||
/** Sets position of the model section. Called from
|
||||
* dynglob.y. */
|
||||
void set_model_pos(int off1, int off2)
|
||||
{model_beg = off1; model_end = off2;}
|
||||
/** Sets position of the section setting parameters. Called
|
||||
* from dynglob.y. */
|
||||
void set_paramset_pos(int off1, int off2)
|
||||
{paramset_beg = off1; paramset_end = off2;}
|
||||
/** Sets position of the initval section. Called from
|
||||
* dynglob.y. */
|
||||
void set_initval_pos(int off1, int off2)
|
||||
{initval_beg = off1; initval_end = off2;}
|
||||
/** Sets position of the vcov section. Called from
|
||||
* dynglob.y. */
|
||||
void set_vcov_pos(int off1, int off2)
|
||||
{vcov_beg = off1; vcov_end = off2;}
|
||||
/** Parser the given string as integer and set to as the
|
||||
* order. */
|
||||
void set_order_pos(int off1, int off2)
|
||||
{order_beg = off1; order_end = off2;}
|
||||
/** Sets position of the planner_objective section. Called
|
||||
* from dynglob.y. */
|
||||
void set_pl_objective_pos(int off1, int off2)
|
||||
{plobjective_beg = off1; plobjective_end = off2;}
|
||||
/** Sets position of the planner_discount section. Called from
|
||||
* dynglob.y. */
|
||||
void set_pl_discount_pos(int off1, int off2)
|
||||
{pldiscount_beg = off1; pldiscount_end = off2;}
|
||||
/** Processes a syntax error from bison. */
|
||||
void error(const char* mes);
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
protected:
|
||||
void parse_glob(int length, const char* stream);
|
||||
int parse_order(int length, const char* stream);
|
||||
int parse_pldiscount(int length, const char* stream);
|
||||
/** Evaluate paramset assignings and set param_vals. */
|
||||
void calc_params();
|
||||
/** Evaluate initval assignings and set init_vals. */
|
||||
void calc_init();
|
||||
/** Do the final job. This includes building the planner
|
||||
* problem (if any) and substituting for multiple lags, and
|
||||
* one period leads of exogenous variables, and calculating
|
||||
* initial guess of lagrange multipliers in the social planner
|
||||
* problem. Precondtion: everything parsed and calculated
|
||||
* parameters, postcondition: calculated initvals vector and
|
||||
* parsing_finished for expanded vectors. */
|
||||
void final_job();
|
||||
private:
|
||||
int model_beg, model_end;
|
||||
int paramset_beg, paramset_end;
|
||||
int initval_beg, initval_end;
|
||||
int vcov_beg, vcov_end;
|
||||
int order_beg, order_end;
|
||||
int plobjective_beg, plobjective_end;
|
||||
int pldiscount_beg, pldiscount_end;
|
||||
};
|
||||
/** Semiparsed model. The equations are given by a string,
|
||||
* everything other by C/C++ objects. The initial values are set
|
||||
* manually after the creation of this object. This implies that
|
||||
* no automatic substitutions cannot be done here, which in turn
|
||||
* implies that we cannot do here a social planner nor substitutions
|
||||
* of multiple lags. */
|
||||
class DynareSPModel : public DynareModel
|
||||
{
|
||||
public:
|
||||
DynareSPModel(const char **endo, int num_endo,
|
||||
const char **exo, int num_exo,
|
||||
const char **par, int num_par,
|
||||
const char *equations, int len, int ord);
|
||||
DynareSPModel(const DynareSPModel &dm)
|
||||
: DynareModel(dm)
|
||||
{
|
||||
}
|
||||
~DynareSPModel()
|
||||
{
|
||||
}
|
||||
virtual DynareModel *
|
||||
clone() const
|
||||
{
|
||||
return new DynareSPModel(*this);
|
||||
}
|
||||
};
|
||||
|
||||
/** Semiparsed model. The equations are given by a string,
|
||||
* everything other by C/C++ objects. The initial values are set
|
||||
* manually after the creation of this object. This implies that
|
||||
* no automatic substitutions cannot be done here, which in turn
|
||||
* implies that we cannot do here a social planner nor substitutions
|
||||
* of multiple lags. */
|
||||
class DynareSPModel : public DynareModel {
|
||||
public:
|
||||
DynareSPModel(const char** endo, int num_endo,
|
||||
const char** exo, int num_exo,
|
||||
const char** par, int num_par,
|
||||
const char* equations, int len, int ord);
|
||||
DynareSPModel(const DynareSPModel& dm)
|
||||
: DynareModel(dm) {}
|
||||
~DynareSPModel() {}
|
||||
virtual DynareModel* clone() const
|
||||
{return new DynareSPModel(*this);}
|
||||
};
|
||||
/** This class implements a selector of operations which correspond
|
||||
* to non-linear functions. This inherits from ogp::opselector and
|
||||
* is used to calculate non-linear subterms in
|
||||
* DynareModel::get_nonlinear_subterms(). */
|
||||
class NLSelector : public ogp::opselector
|
||||
{
|
||||
private:
|
||||
const DynareModel &model;
|
||||
public:
|
||||
NLSelector(const DynareModel &m) : model(m)
|
||||
{
|
||||
}
|
||||
bool operator()(int t) const;
|
||||
};
|
||||
|
||||
/** This class implements a selector of operations which correspond
|
||||
* to non-linear functions. This inherits from ogp::opselector and
|
||||
* is used to calculate non-linear subterms in
|
||||
* DynareModel::get_nonlinear_subterms(). */
|
||||
class NLSelector : public ogp::opselector {
|
||||
private:
|
||||
const DynareModel& model;
|
||||
public:
|
||||
NLSelector(const DynareModel& m) : model(m) {}
|
||||
bool operator()(int t) const;
|
||||
};
|
||||
/** This class writes a mathematical code evaluating the system of
|
||||
* equations and the first derivatives at zero shocks and at the
|
||||
* given (static) state. Static means that lags and leads are
|
||||
* ignored. */
|
||||
class ModelSSWriter : public ogp::DefaultOperationFormatter
|
||||
{
|
||||
protected:
|
||||
const DynareModel &model;
|
||||
public:
|
||||
ModelSSWriter(const DynareModel &m)
|
||||
: DefaultOperationFormatter(m.eqs.getTree()),
|
||||
model(m)
|
||||
{
|
||||
}
|
||||
/** This writes the evaluation of the system. It calls pure
|
||||
* virtual methods for writing a preamble, then assignment of
|
||||
* atoms, and then assignment for resulting object. These are
|
||||
* language dependent and are implemented in the subclass. */
|
||||
void write_der0(FILE *fd);
|
||||
/** This writes the evaluation of the first order derivative of
|
||||
the system. It calls pure virtual methods for writing a
|
||||
preamble, assignment, and assignemnt of the resulting
|
||||
objects. */
|
||||
void write_der1(FILE *fd);
|
||||
protected:
|
||||
virtual void write_der0_preamble(FILE *fd) const = 0;
|
||||
virtual void write_der1_preamble(FILE *fd) const = 0;
|
||||
virtual void write_atom_assignment(FILE *fd) const = 0;
|
||||
virtual void write_der0_assignment(FILE *fd) const = 0;
|
||||
virtual void write_der1_assignment(FILE *fd) const = 0;
|
||||
};
|
||||
|
||||
/** This class writes a mathematical code evaluating the system of
|
||||
* equations and the first derivatives at zero shocks and at the
|
||||
* given (static) state. Static means that lags and leads are
|
||||
* ignored. */
|
||||
class ModelSSWriter : public ogp::DefaultOperationFormatter {
|
||||
protected:
|
||||
const DynareModel& model;
|
||||
public:
|
||||
ModelSSWriter(const DynareModel& m)
|
||||
: DefaultOperationFormatter(m.eqs.getTree()),
|
||||
model(m) {}
|
||||
/** This writes the evaluation of the system. It calls pure
|
||||
* virtual methods for writing a preamble, then assignment of
|
||||
* atoms, and then assignment for resulting object. These are
|
||||
* language dependent and are implemented in the subclass. */
|
||||
void write_der0(FILE* fd);
|
||||
/** This writes the evaluation of the first order derivative of
|
||||
the system. It calls pure virtual methods for writing a
|
||||
preamble, assignment, and assignemnt of the resulting
|
||||
objects. */
|
||||
void write_der1(FILE* fd);
|
||||
protected:
|
||||
virtual void write_der0_preamble(FILE* fd) const =0;
|
||||
virtual void write_der1_preamble(FILE* fd) const =0;
|
||||
virtual void write_atom_assignment(FILE* fd) const =0;
|
||||
virtual void write_der0_assignment(FILE* fd) const =0;
|
||||
virtual void write_der1_assignment(FILE* fd) const =0;
|
||||
};
|
||||
class MatlabSSWriter : public ModelSSWriter
|
||||
{
|
||||
protected:
|
||||
/** Identifier used in function names. */
|
||||
char *id;
|
||||
public:
|
||||
MatlabSSWriter(const DynareModel &dm, const char *idd);
|
||||
virtual ~MatlabSSWriter()
|
||||
{
|
||||
delete [] id;
|
||||
}
|
||||
protected:
|
||||
// from ModelSSWriter
|
||||
void write_der0_preamble(FILE *fd) const;
|
||||
void write_der1_preamble(FILE *fd) const;
|
||||
/** This writes atom assignments. We have four kinds of atoms
|
||||
* set here: endogenous vars coming from one parameter,
|
||||
* parameter values given by the second parameter, constants,
|
||||
* and the OperationTree::num_constants hardwired constants in
|
||||
* ogp::OperationTree. */
|
||||
void write_atom_assignment(FILE *fd) const;
|
||||
void write_der0_assignment(FILE *fd) const;
|
||||
void write_der1_assignment(FILE *fd) const;
|
||||
/** This prints t10 for t=10. */
|
||||
void format_term(int t, FILE *fd) const;
|
||||
/** This prints a10 for t=10. The atoms a10 are supposed to be
|
||||
* set by write_atom_assignments(). */
|
||||
void format_nulary(int t, FILE *fd) const;
|
||||
private:
|
||||
void write_common1_preamble(FILE *fd) const;
|
||||
void write_common2_preamble(FILE *fd) const;
|
||||
};
|
||||
|
||||
|
||||
class MatlabSSWriter : public ModelSSWriter {
|
||||
protected:
|
||||
/** Identifier used in function names. */
|
||||
char* id;
|
||||
public:
|
||||
MatlabSSWriter(const DynareModel& dm, const char* idd);
|
||||
virtual ~MatlabSSWriter()
|
||||
{delete [] id;}
|
||||
protected:
|
||||
// from ModelSSWriter
|
||||
void write_der0_preamble(FILE* fd) const;
|
||||
void write_der1_preamble(FILE* fd) const;
|
||||
/** This writes atom assignments. We have four kinds of atoms
|
||||
* set here: endogenous vars coming from one parameter,
|
||||
* parameter values given by the second parameter, constants,
|
||||
* and the OperationTree::num_constants hardwired constants in
|
||||
* ogp::OperationTree. */
|
||||
void write_atom_assignment(FILE* fd) const;
|
||||
void write_der0_assignment(FILE* fd) const;
|
||||
void write_der1_assignment(FILE* fd) const;
|
||||
/** This prints t10 for t=10. */
|
||||
void format_term(int t, FILE* fd) const;
|
||||
/** This prints a10 for t=10. The atoms a10 are supposed to be
|
||||
* set by write_atom_assignments(). */
|
||||
void format_nulary(int t, FILE* fd) const;
|
||||
private:
|
||||
void write_common1_preamble(FILE* fd) const;
|
||||
void write_common2_preamble(FILE* fd) const;
|
||||
};
|
||||
|
||||
/** This class implements OperationFormatter for debugging
|
||||
* purposes. It renders atoms in a more friendly way than the
|
||||
* ogp::DefaulOperationFormatter. */
|
||||
class DebugOperationFormatter : public ogp::DefaultOperationFormatter {
|
||||
protected:
|
||||
const DynareModel& model;
|
||||
public:
|
||||
DebugOperationFormatter(const DynareModel& m)
|
||||
: DefaultOperationFormatter(m.getParser().getTree()),
|
||||
model(m) {}
|
||||
void format_nulary(int t, FILE* fd) const;
|
||||
};
|
||||
/** This class implements OperationFormatter for debugging
|
||||
* purposes. It renders atoms in a more friendly way than the
|
||||
* ogp::DefaulOperationFormatter. */
|
||||
class DebugOperationFormatter : public ogp::DefaultOperationFormatter
|
||||
{
|
||||
protected:
|
||||
const DynareModel &model;
|
||||
public:
|
||||
DebugOperationFormatter(const DynareModel &m)
|
||||
: DefaultOperationFormatter(m.getParser().getTree()),
|
||||
model(m)
|
||||
{
|
||||
}
|
||||
void format_nulary(int t, FILE *fd) const;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,71 +3,87 @@
|
|||
// Copyright 2004, Ondra Kamenik
|
||||
|
||||
/*
|
||||
along shocks: m mult max_evals
|
||||
ellipse: m mult max_evals (10*m) (0.5*mult)
|
||||
simul: m max_evals (10*m)
|
||||
along shocks: m mult max_evals
|
||||
ellipse: m mult max_evals (10*m) (0.5*mult)
|
||||
simul: m max_evals (10*m)
|
||||
|
||||
--check-scale 2.0 --check-evals 1000 --check-num 10 --check PES
|
||||
*/
|
||||
--check-scale 2.0 --check-evals 1000 --check-num 10 --check PES
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct DynareParams {
|
||||
const char* modname;
|
||||
std::string basename;
|
||||
int num_per;
|
||||
int num_burn;
|
||||
int num_sim;
|
||||
int num_rtper;
|
||||
int num_rtsim;
|
||||
int num_condper;
|
||||
int num_condsim;
|
||||
int num_threads;
|
||||
int num_steps;
|
||||
const char* prefix;
|
||||
int seed;
|
||||
int order;
|
||||
/** Tolerance used for steady state calcs. */
|
||||
double ss_tol;
|
||||
bool check_along_path;
|
||||
bool check_along_shocks;
|
||||
bool check_on_ellipse;
|
||||
int check_evals;
|
||||
int check_num;
|
||||
double check_scale;
|
||||
/** Flag for doing IRFs even if the irf_list is empty. */
|
||||
bool do_irfs_all;
|
||||
/** List of shocks for which IRF will be calculated. */
|
||||
std::vector<const char*> irf_list;
|
||||
bool do_centralize;
|
||||
double qz_criterium;
|
||||
bool help;
|
||||
bool version;
|
||||
DynareParams(int argc, char** argv);
|
||||
void printHelp() const;
|
||||
int getCheckShockPoints() const
|
||||
{return check_num;}
|
||||
double getCheckShockScale() const
|
||||
{return check_scale;}
|
||||
int getCheckEllipsePoints() const
|
||||
{return 10*check_num;}
|
||||
double getCheckEllipseScale() const
|
||||
{return 0.5*check_scale;}
|
||||
int getCheckPathPoints() const
|
||||
{return 10*check_num;}
|
||||
struct DynareParams
|
||||
{
|
||||
const char *modname;
|
||||
std::string basename;
|
||||
int num_per;
|
||||
int num_burn;
|
||||
int num_sim;
|
||||
int num_rtper;
|
||||
int num_rtsim;
|
||||
int num_condper;
|
||||
int num_condsim;
|
||||
int num_threads;
|
||||
int num_steps;
|
||||
const char *prefix;
|
||||
int seed;
|
||||
int order;
|
||||
/** Tolerance used for steady state calcs. */
|
||||
double ss_tol;
|
||||
bool check_along_path;
|
||||
bool check_along_shocks;
|
||||
bool check_on_ellipse;
|
||||
int check_evals;
|
||||
int check_num;
|
||||
double check_scale;
|
||||
/** Flag for doing IRFs even if the irf_list is empty. */
|
||||
bool do_irfs_all;
|
||||
/** List of shocks for which IRF will be calculated. */
|
||||
std::vector<const char *> irf_list;
|
||||
bool do_centralize;
|
||||
double qz_criterium;
|
||||
bool help;
|
||||
bool version;
|
||||
DynareParams(int argc, char **argv);
|
||||
void printHelp() const;
|
||||
int
|
||||
getCheckShockPoints() const
|
||||
{
|
||||
return check_num;
|
||||
}
|
||||
double
|
||||
getCheckShockScale() const
|
||||
{
|
||||
return check_scale;
|
||||
}
|
||||
int
|
||||
getCheckEllipsePoints() const
|
||||
{
|
||||
return 10*check_num;
|
||||
}
|
||||
double
|
||||
getCheckEllipseScale() const
|
||||
{
|
||||
return 0.5*check_scale;
|
||||
}
|
||||
int
|
||||
getCheckPathPoints() const
|
||||
{
|
||||
return 10*check_num;
|
||||
}
|
||||
private:
|
||||
enum {opt_per, opt_burn, opt_sim, opt_rtper, opt_rtsim, opt_condper, opt_condsim,
|
||||
opt_prefix, opt_threads,
|
||||
opt_steps, opt_seed, opt_order, opt_ss_tol, opt_check,
|
||||
opt_check_along_path, opt_check_along_shocks, opt_check_on_ellipse,
|
||||
opt_check_evals, opt_check_scale, opt_check_num, opt_noirfs, opt_irfs,
|
||||
opt_help, opt_version, opt_centralize, opt_no_centralize, opt_qz_criterium};
|
||||
void processCheckFlags(const char* flags);
|
||||
/** This gathers strings from argv[optind] and on not starting
|
||||
* with '-' to the irf_list. It stops one item before the end,
|
||||
* since this is the model file. */
|
||||
void processIRFList(int argc, char** argv);
|
||||
enum {opt_per, opt_burn, opt_sim, opt_rtper, opt_rtsim, opt_condper, opt_condsim,
|
||||
opt_prefix, opt_threads,
|
||||
opt_steps, opt_seed, opt_order, opt_ss_tol, opt_check,
|
||||
opt_check_along_path, opt_check_along_shocks, opt_check_on_ellipse,
|
||||
opt_check_evals, opt_check_scale, opt_check_num, opt_noirfs, opt_irfs,
|
||||
opt_help, opt_version, opt_centralize, opt_no_centralize, opt_qz_criterium};
|
||||
void processCheckFlags(const char *flags);
|
||||
/** This gathers strings from argv[optind] and on not starting
|
||||
* with '-' to the irf_list. It stops one item before the end,
|
||||
* since this is the model file. */
|
||||
void processIRFList(int argc, char **argv);
|
||||
};
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -5,75 +5,85 @@
|
|||
#ifndef FORW_SUBST_BUILDER_H
|
||||
#define FORW_SUBST_BUILDER_H
|
||||
|
||||
|
||||
#include "dynare_model.h"
|
||||
|
||||
namespace ogdyn {
|
||||
namespace ogdyn
|
||||
{
|
||||
|
||||
/** This struct encapsulates information about the process of
|
||||
* forward substitutions. */
|
||||
struct ForwSubstInfo {
|
||||
int num_affected_equations;
|
||||
int num_subst_terms;
|
||||
int num_aux_variables;
|
||||
int num_new_terms;
|
||||
ForwSubstInfo()
|
||||
: num_affected_equations(0),
|
||||
num_subst_terms(0),
|
||||
num_aux_variables(0),
|
||||
num_new_terms(0) {}
|
||||
};
|
||||
/** This struct encapsulates information about the process of
|
||||
* forward substitutions. */
|
||||
struct ForwSubstInfo
|
||||
{
|
||||
int num_affected_equations;
|
||||
int num_subst_terms;
|
||||
int num_aux_variables;
|
||||
int num_new_terms;
|
||||
ForwSubstInfo()
|
||||
: num_affected_equations(0),
|
||||
num_subst_terms(0),
|
||||
num_aux_variables(0),
|
||||
num_new_terms(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class ForwSubstBuilder {
|
||||
typedef map<int, const char*> Ttermauxmap;
|
||||
protected:
|
||||
/** Reference to the model, to which we will add equations and
|
||||
* change some equations. */
|
||||
DynareModel& model;
|
||||
/** A map mapping new auxiliary variables to the terms in the
|
||||
* tree in the DynareModel. */
|
||||
Tsubstmap aux_map;
|
||||
/** Information about the substitutions. */
|
||||
ForwSubstInfo info;
|
||||
public:
|
||||
/** Do all the jobs needed. This scans all equations in the
|
||||
* model, and for equations containing forward looking
|
||||
* variables greater than 1 lead, it makes corresponding
|
||||
* substitutions. Basically, it breaks each equation to its
|
||||
* non-linear components and creates substitutions for these
|
||||
* components, not for whole equation. This is because the
|
||||
* expectation operator can go through the linear part of the
|
||||
* function. This will save us many occurrences of other
|
||||
* variables involved in the equation. */
|
||||
ForwSubstBuilder(DynareModel& m);
|
||||
/** Copy constructor with a new instance of the model. */
|
||||
ForwSubstBuilder(const ForwSubstBuilder& b, DynareModel& m);
|
||||
/** Return the auxiliary variable mapping. */
|
||||
const Tsubstmap& get_aux_map() const
|
||||
{return aux_map;}
|
||||
/** Return the information. */
|
||||
const ForwSubstInfo& get_info() const
|
||||
{return info;}
|
||||
private:
|
||||
ForwSubstBuilder(const ForwSubstBuilder& b);
|
||||
/** This method takes a nonlinear term t, and if it has leads
|
||||
* of greater than 1, then it substitutes the term for the new
|
||||
* variable (or string of variables). Note that the
|
||||
* substitution is done by DynamicAtoms::assign_variable. This
|
||||
* means that the substitution is made for all other
|
||||
* ocurrences of t in the model. So there is no need of
|
||||
* tracking already substituted terms. The other two
|
||||
* parameters are just for identification of the new auxiliary
|
||||
* variables. When called from the constructor, i is an
|
||||
* equation number, j is an order of the non-linear term in
|
||||
* the equation. */
|
||||
void substitute_for_term(int t, int i, int j);
|
||||
/** This is called just at the end of the job. It unassigns
|
||||
* all nulary terms with a lead greater than 1. */
|
||||
void unassign_gt_1_leads();
|
||||
/** This unassigns all leads greater than 1 of the given name. */
|
||||
void unassign_gt_1_leads(const char* name);
|
||||
};
|
||||
class ForwSubstBuilder
|
||||
{
|
||||
typedef map<int, const char *> Ttermauxmap;
|
||||
protected:
|
||||
/** Reference to the model, to which we will add equations and
|
||||
* change some equations. */
|
||||
DynareModel &model;
|
||||
/** A map mapping new auxiliary variables to the terms in the
|
||||
* tree in the DynareModel. */
|
||||
Tsubstmap aux_map;
|
||||
/** Information about the substitutions. */
|
||||
ForwSubstInfo info;
|
||||
public:
|
||||
/** Do all the jobs needed. This scans all equations in the
|
||||
* model, and for equations containing forward looking
|
||||
* variables greater than 1 lead, it makes corresponding
|
||||
* substitutions. Basically, it breaks each equation to its
|
||||
* non-linear components and creates substitutions for these
|
||||
* components, not for whole equation. This is because the
|
||||
* expectation operator can go through the linear part of the
|
||||
* function. This will save us many occurrences of other
|
||||
* variables involved in the equation. */
|
||||
ForwSubstBuilder(DynareModel &m);
|
||||
/** Copy constructor with a new instance of the model. */
|
||||
ForwSubstBuilder(const ForwSubstBuilder &b, DynareModel &m);
|
||||
/** Return the auxiliary variable mapping. */
|
||||
const Tsubstmap &
|
||||
get_aux_map() const
|
||||
{
|
||||
return aux_map;
|
||||
}
|
||||
/** Return the information. */
|
||||
const ForwSubstInfo &
|
||||
get_info() const
|
||||
{
|
||||
return info;
|
||||
}
|
||||
private:
|
||||
ForwSubstBuilder(const ForwSubstBuilder &b);
|
||||
/** This method takes a nonlinear term t, and if it has leads
|
||||
* of greater than 1, then it substitutes the term for the new
|
||||
* variable (or string of variables). Note that the
|
||||
* substitution is done by DynamicAtoms::assign_variable. This
|
||||
* means that the substitution is made for all other
|
||||
* ocurrences of t in the model. So there is no need of
|
||||
* tracking already substituted terms. The other two
|
||||
* parameters are just for identification of the new auxiliary
|
||||
* variables. When called from the constructor, i is an
|
||||
* equation number, j is an order of the non-linear term in
|
||||
* the equation. */
|
||||
void substitute_for_term(int t, int i, int j);
|
||||
/** This is called just at the end of the job. It unassigns
|
||||
* all nulary terms with a lead greater than 1. */
|
||||
void unassign_gt_1_leads();
|
||||
/** This unassigns all leads greater than 1 of the given name. */
|
||||
void unassign_gt_1_leads(const char *name);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,82 +8,102 @@
|
|||
#include "twod_matrix.h"
|
||||
#include "journal.h"
|
||||
|
||||
namespace ogu {
|
||||
namespace ogu
|
||||
{
|
||||
|
||||
class OneDFunction {
|
||||
public:
|
||||
virtual ~OneDFunction() {}
|
||||
virtual double eval(double) = 0;
|
||||
};
|
||||
class OneDFunction
|
||||
{
|
||||
public:
|
||||
virtual ~OneDFunction()
|
||||
{
|
||||
}
|
||||
virtual double eval(double) = 0;
|
||||
};
|
||||
|
||||
class GoldenSectionSearch {
|
||||
protected:
|
||||
static double tol;
|
||||
static double golden;
|
||||
public:
|
||||
static double search(OneDFunction& f, double x1, double x2);
|
||||
protected:
|
||||
/** This initializes a bracket by moving x2 and b (as a golden
|
||||
* section of x1,x2) so that f(x1)>f(b) && f(b)<f(x2). The point
|
||||
* x1 is not moved, since it is considered as reliable and f(x1)
|
||||
* is supposed to be finite. If initialization of a bracket
|
||||
* succeeded, then [x1, b, x2] is the bracket and true is
|
||||
* returned. Otherwise, b is the minimum found and false is
|
||||
* returned. */
|
||||
static bool init_bracket(OneDFunction& f, double x1, double& x2, double& b);
|
||||
/** This supposes that f(x1) is finite and it moves x2 toward x1
|
||||
* until x2 and b (as a golden section of x1,x2) are finite. If
|
||||
* succeeded, the routine returns true and x2, and b. Otherwise,
|
||||
* it returns false. */
|
||||
static bool search_for_finite(OneDFunction& f, double x1, double& x2, double& b);
|
||||
};
|
||||
class GoldenSectionSearch
|
||||
{
|
||||
protected:
|
||||
static double tol;
|
||||
static double golden;
|
||||
public:
|
||||
static double search(OneDFunction &f, double x1, double x2);
|
||||
protected:
|
||||
/** This initializes a bracket by moving x2 and b (as a golden
|
||||
* section of x1,x2) so that f(x1)>f(b) && f(b)<f(x2). The point
|
||||
* x1 is not moved, since it is considered as reliable and f(x1)
|
||||
* is supposed to be finite. If initialization of a bracket
|
||||
* succeeded, then [x1, b, x2] is the bracket and true is
|
||||
* returned. Otherwise, b is the minimum found and false is
|
||||
* returned. */
|
||||
static bool init_bracket(OneDFunction &f, double x1, double &x2, double &b);
|
||||
/** This supposes that f(x1) is finite and it moves x2 toward x1
|
||||
* until x2 and b (as a golden section of x1,x2) are finite. If
|
||||
* succeeded, the routine returns true and x2, and b. Otherwise,
|
||||
* it returns false. */
|
||||
static bool search_for_finite(OneDFunction &f, double x1, double &x2, double &b);
|
||||
};
|
||||
|
||||
class VectorFunction {
|
||||
public:
|
||||
VectorFunction() {}
|
||||
virtual ~VectorFunction() {}
|
||||
virtual int inDim() const = 0;
|
||||
virtual int outDim() const = 0;
|
||||
/** Check dimensions of eval parameters. */
|
||||
void check_for_eval(const ConstVector& in, Vector& out) const;
|
||||
/** Evaluate the vector function. */
|
||||
virtual void eval(const ConstVector& in, Vector& out) = 0;
|
||||
};
|
||||
class VectorFunction
|
||||
{
|
||||
public:
|
||||
VectorFunction()
|
||||
{
|
||||
}
|
||||
virtual ~VectorFunction()
|
||||
{
|
||||
}
|
||||
virtual int inDim() const = 0;
|
||||
virtual int outDim() const = 0;
|
||||
/** Check dimensions of eval parameters. */
|
||||
void check_for_eval(const ConstVector &in, Vector &out) const;
|
||||
/** Evaluate the vector function. */
|
||||
virtual void eval(const ConstVector &in, Vector &out) = 0;
|
||||
};
|
||||
|
||||
class Jacobian : public TwoDMatrix {
|
||||
public:
|
||||
Jacobian(int n)
|
||||
: TwoDMatrix(n,n) {}
|
||||
virtual ~Jacobian() {}
|
||||
virtual void eval(const Vector& in) = 0;
|
||||
};
|
||||
class Jacobian : public TwoDMatrix
|
||||
{
|
||||
public:
|
||||
Jacobian(int n)
|
||||
: TwoDMatrix(n, n)
|
||||
{
|
||||
}
|
||||
virtual ~Jacobian()
|
||||
{
|
||||
}
|
||||
virtual void eval(const Vector &in) = 0;
|
||||
};
|
||||
|
||||
class NLSolver : public OneDFunction {
|
||||
protected:
|
||||
Journal& journal;
|
||||
VectorFunction& func;
|
||||
Jacobian& jacob;
|
||||
const int max_iter;
|
||||
const double tol;
|
||||
private:
|
||||
Vector xnewton;
|
||||
Vector xcauchy;
|
||||
Vector x;
|
||||
public:
|
||||
NLSolver(VectorFunction& f, Jacobian& j, int maxit, double tl, Journal& jr)
|
||||
: journal(jr), func(f), jacob(j), max_iter(maxit), tol(tl),
|
||||
xnewton(f.inDim()), xcauchy(f.inDim()), x(f.inDim())
|
||||
{xnewton.zeros(); xcauchy.zeros(); x.zeros();}
|
||||
virtual ~NLSolver() {}
|
||||
/** Returns true if the problem has converged. xx as input is the
|
||||
* starting value, as output it is a solution. */
|
||||
bool solve(Vector& xx, int& iter);
|
||||
/** To implement OneDFunction interface. It returns
|
||||
* func(xx)^T*func(xx), where
|
||||
* xx=x+lambda*xcauchy+(1-lambda)*xnewton. It is non-const only
|
||||
* because it calls func, x, xnewton, xcauchy is not changed. */
|
||||
double eval(double lambda);
|
||||
};
|
||||
class NLSolver : public OneDFunction
|
||||
{
|
||||
protected:
|
||||
Journal &journal;
|
||||
VectorFunction &func;
|
||||
Jacobian &jacob;
|
||||
const int max_iter;
|
||||
const double tol;
|
||||
private:
|
||||
Vector xnewton;
|
||||
Vector xcauchy;
|
||||
Vector x;
|
||||
public:
|
||||
NLSolver(VectorFunction &f, Jacobian &j, int maxit, double tl, Journal &jr)
|
||||
: journal(jr), func(f), jacob(j), max_iter(maxit), tol(tl),
|
||||
xnewton(f.inDim()), xcauchy(f.inDim()), x(f.inDim())
|
||||
{
|
||||
xnewton.zeros(); xcauchy.zeros(); x.zeros();
|
||||
}
|
||||
virtual ~NLSolver()
|
||||
{
|
||||
}
|
||||
/** Returns true if the problem has converged. xx as input is the
|
||||
* starting value, as output it is a solution. */
|
||||
bool solve(Vector &xx, int &iter);
|
||||
/** To implement OneDFunction interface. It returns
|
||||
* func(xx)^T*func(xx), where
|
||||
* xx=x+lambda*xcauchy+(1-lambda)*xnewton. It is non-const only
|
||||
* because it calls func, x, xnewton, xcauchy is not changed. */
|
||||
double eval(double lambda);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -5,273 +5,322 @@
|
|||
|
||||
#include "dynare_model.h"
|
||||
|
||||
namespace ogdyn {
|
||||
namespace ogdyn
|
||||
{
|
||||
|
||||
using boost::unordered_set;
|
||||
using std::map;
|
||||
using std::vector;
|
||||
using boost::unordered_set;
|
||||
using std::map;
|
||||
using std::vector;
|
||||
|
||||
/** This is a two dimensional array of integers. Nothing
|
||||
* difficult. */
|
||||
class IntegerMatrix {
|
||||
protected:
|
||||
/** Number of rows. */
|
||||
int nr;
|
||||
/** Number of columns. */
|
||||
int nc;
|
||||
/** The pointer to the data. */
|
||||
int* data;
|
||||
public:
|
||||
/** Construct uninitialized array. */
|
||||
IntegerMatrix(int nrr, int ncc)
|
||||
: nr(nrr), nc(ncc), data(new int[nr*nc]) {}
|
||||
/** Copy constructor. */
|
||||
IntegerMatrix(const IntegerMatrix& im)
|
||||
: nr(im.nr), nc(im.nc), data(new int[nr*nc])
|
||||
{memcpy(data, im.data, nr*nc*sizeof(int));}
|
||||
virtual ~IntegerMatrix()
|
||||
{delete [] data;}
|
||||
/** Assignment operator. It can only assing array with the
|
||||
* same dimensions. */
|
||||
const IntegerMatrix& operator=(const IntegerMatrix& im);
|
||||
int& operator()(int i, int j)
|
||||
{return data[i+j*nr];}
|
||||
const int& operator()(int i, int j) const
|
||||
{return data[i+j*nr];}
|
||||
int nrows() const
|
||||
{return nr;}
|
||||
int ncols() const
|
||||
{return nc;}
|
||||
};
|
||||
/** This is a two dimensional array of integers. Nothing
|
||||
* difficult. */
|
||||
class IntegerMatrix
|
||||
{
|
||||
protected:
|
||||
/** Number of rows. */
|
||||
int nr;
|
||||
/** Number of columns. */
|
||||
int nc;
|
||||
/** The pointer to the data. */
|
||||
int *data;
|
||||
public:
|
||||
/** Construct uninitialized array. */
|
||||
IntegerMatrix(int nrr, int ncc)
|
||||
: nr(nrr), nc(ncc), data(new int[nr*nc])
|
||||
{
|
||||
}
|
||||
/** Copy constructor. */
|
||||
IntegerMatrix(const IntegerMatrix &im)
|
||||
: nr(im.nr), nc(im.nc), data(new int[nr*nc])
|
||||
{
|
||||
memcpy(data, im.data, nr*nc*sizeof(int));
|
||||
}
|
||||
virtual ~IntegerMatrix()
|
||||
{
|
||||
delete [] data;
|
||||
}
|
||||
/** Assignment operator. It can only assing array with the
|
||||
* same dimensions. */
|
||||
const IntegerMatrix &operator=(const IntegerMatrix &im);
|
||||
int &
|
||||
operator()(int i, int j)
|
||||
{
|
||||
return data[i+j*nr];
|
||||
}
|
||||
const int &
|
||||
operator()(int i, int j) const
|
||||
{
|
||||
return data[i+j*nr];
|
||||
}
|
||||
int
|
||||
nrows() const
|
||||
{
|
||||
return nr;
|
||||
}
|
||||
int
|
||||
ncols() const
|
||||
{
|
||||
return nc;
|
||||
}
|
||||
};
|
||||
|
||||
/** The three dimensional array of integers. Nothing difficult. */
|
||||
class IntegerArray3 {
|
||||
protected:
|
||||
/** First dimension. */
|
||||
int n1;
|
||||
/** Second dimension. */
|
||||
int n2;
|
||||
/** Third dimension. */
|
||||
int n3;
|
||||
/** The data. */
|
||||
int* data;
|
||||
public:
|
||||
/** Constrcut unitialized array. */
|
||||
IntegerArray3(int nn1, int nn2, int nn3)
|
||||
: n1(nn1), n2(nn2), n3(nn3), data(new int[n1*n2*n3]) {}
|
||||
/** Copy constructor. */
|
||||
IntegerArray3(const IntegerArray3& ia3)
|
||||
: n1(ia3.n1), n2(ia3.n2), n3(ia3.n3), data(new int[n1*n2*n3])
|
||||
{memcpy(data, ia3.data, n1*n2*n3*sizeof(int));}
|
||||
virtual ~IntegerArray3()
|
||||
{delete [] data;}
|
||||
/** Assignment operator assigning the arrays with the same dimensions. */
|
||||
const IntegerArray3& operator=(const IntegerArray3& ia3);
|
||||
int& operator()(int i, int j, int k)
|
||||
{return data[i+j*n1+k*n1*n2];}
|
||||
const int& operator()(int i, int j, int k) const
|
||||
{return data[i+j*n1+k*n1*n2];}
|
||||
int dim1() const
|
||||
{return n1;}
|
||||
int dim2() const
|
||||
{return n2;}
|
||||
int dim3() const
|
||||
{return n3;}
|
||||
};
|
||||
/** The three dimensional array of integers. Nothing difficult. */
|
||||
class IntegerArray3
|
||||
{
|
||||
protected:
|
||||
/** First dimension. */
|
||||
int n1;
|
||||
/** Second dimension. */
|
||||
int n2;
|
||||
/** Third dimension. */
|
||||
int n3;
|
||||
/** The data. */
|
||||
int *data;
|
||||
public:
|
||||
/** Constrcut unitialized array. */
|
||||
IntegerArray3(int nn1, int nn2, int nn3)
|
||||
: n1(nn1), n2(nn2), n3(nn3), data(new int[n1*n2*n3])
|
||||
{
|
||||
}
|
||||
/** Copy constructor. */
|
||||
IntegerArray3(const IntegerArray3 &ia3)
|
||||
: n1(ia3.n1), n2(ia3.n2), n3(ia3.n3), data(new int[n1*n2*n3])
|
||||
{
|
||||
memcpy(data, ia3.data, n1*n2*n3*sizeof(int));
|
||||
}
|
||||
virtual ~IntegerArray3()
|
||||
{
|
||||
delete [] data;
|
||||
}
|
||||
/** Assignment operator assigning the arrays with the same dimensions. */
|
||||
const IntegerArray3 &operator=(const IntegerArray3 &ia3);
|
||||
int &
|
||||
operator()(int i, int j, int k)
|
||||
{
|
||||
return data[i+j*n1+k*n1*n2];
|
||||
}
|
||||
const int &
|
||||
operator()(int i, int j, int k) const
|
||||
{
|
||||
return data[i+j*n1+k*n1*n2];
|
||||
}
|
||||
int
|
||||
dim1() const
|
||||
{
|
||||
return n1;
|
||||
}
|
||||
int
|
||||
dim2() const
|
||||
{
|
||||
return n2;
|
||||
}
|
||||
int
|
||||
dim3() const
|
||||
{
|
||||
return n3;
|
||||
}
|
||||
};
|
||||
|
||||
/** This struct encapsulates information about the building of a
|
||||
* planner's problem. */
|
||||
struct PlannerInfo {
|
||||
int num_lagrange_mults;
|
||||
int num_aux_variables;
|
||||
int num_new_terms;
|
||||
PlannerInfo()
|
||||
: num_lagrange_mults(0),
|
||||
num_aux_variables(0),
|
||||
num_new_terms(0) {}
|
||||
};
|
||||
/** This struct encapsulates information about the building of a
|
||||
* planner's problem. */
|
||||
struct PlannerInfo
|
||||
{
|
||||
int num_lagrange_mults;
|
||||
int num_aux_variables;
|
||||
int num_new_terms;
|
||||
PlannerInfo()
|
||||
: num_lagrange_mults(0),
|
||||
num_aux_variables(0),
|
||||
num_new_terms(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class MultInitSS;
|
||||
class MultInitSS;
|
||||
|
||||
/** This class builds the first order conditions of the social
|
||||
* planner problem with constraints being the equations in the
|
||||
* model. The model is non-const parameter to the constructor
|
||||
* which adds appropriate FOCs to the system. It also allows for
|
||||
* an estimation of the lagrange multipliers given all other
|
||||
* endogenous variables of the static system. For this purpose we
|
||||
* need to create static atoms and static versions of all the tree
|
||||
* index matrices. The algorithm and algebra are documented in
|
||||
* dynare++-ramsey.pdf. */
|
||||
class PlannerBuilder {
|
||||
friend class MultInitSS;
|
||||
public:
|
||||
/** Type for a set of variable names. */
|
||||
typedef unordered_set<const char*> Tvarset;
|
||||
/** Type for a set of equations. An equation is identified by
|
||||
* an index to an equation in the equation vector given by
|
||||
* DynareModel::eqs. The tree index of the i-th formula is
|
||||
* retrieved as DynareModel::egs.formula(i). */
|
||||
typedef vector<int> Teqset;
|
||||
protected:
|
||||
/** This is a set of variables wrt which the planner
|
||||
* optimizes. These could be all endogenous variables, but it
|
||||
* is beneficial to exclude all variables which are
|
||||
* deterministic transformations of past exogenous variables,
|
||||
* since the planner cannot influence them. This could save a
|
||||
* few equations. This is not changed after it is constructed,
|
||||
* but it is constructed manually, so it cannot be declared as
|
||||
* const. */
|
||||
Tvarset yset;
|
||||
/** These are the equation indices constituing the constraints
|
||||
* for the planner. Again, it is beneficial to exclude all
|
||||
* equations defining exogenous variables excluded from
|
||||
* yset. */
|
||||
const Teqset fset;
|
||||
/** Reference to the model. */
|
||||
ogdyn::DynareModel& model;
|
||||
/** Tree index of the planner objective. */
|
||||
int tb;
|
||||
/** Tree index of the planner discount parameter. */
|
||||
int tbeta;
|
||||
/** The maximum lead in the model including the planner's
|
||||
* objective before building the planner's FOCs. */
|
||||
const int maxlead;
|
||||
/** The minimum lag in the model including the planner's objective
|
||||
* before building the planner's FOCs. */
|
||||
const int minlag;
|
||||
/** Tree indices of formulas in the planner FOCs involving
|
||||
* derivatives of the planner's objective. Rows correspond to the
|
||||
* endogenous variables, columns correspond to lags in the
|
||||
* objective function. The contents of the matrix will evolve as
|
||||
* the algorithm proceeds. */
|
||||
IntegerMatrix diff_b;
|
||||
/** Tree indices of formulas in the planner FOCs involving
|
||||
* derivatives of the model equations (constraints). The first
|
||||
* dimension corresponds to endogenous variables, the second to
|
||||
* the constraints, the third to lags or leads of endogenous
|
||||
* variables in the constraints. The contents of the array will
|
||||
* evolve as the algorithm proceeds.*/
|
||||
IntegerArray3 diff_f;
|
||||
/** Static version of the model atoms. It is needed to build
|
||||
* static version of diff_b and diff_f. */
|
||||
ogp::StaticFineAtoms static_atoms;
|
||||
/** Static version of all the trees of diff_b and diff_f build
|
||||
* over static_atoms. */
|
||||
ogp::OperationTree static_tree;
|
||||
/** Tree indices of static version of diff_b over static_atoms and static_tree. */
|
||||
IntegerMatrix diff_b_static;
|
||||
/** Tree indices of static version of diff_f over static_atoms
|
||||
* and static_tree. This member is created before calling
|
||||
* lagrange_mult_f(), so it does not contain the
|
||||
* multiplication with the lagrange multipliers. */
|
||||
IntegerArray3 diff_f_static;
|
||||
/** Auxiliary variables mapping. During the algorithm, some
|
||||
* auxiliary variables for the terms might be created, so we
|
||||
* remember their names and tree indices of the terms. This
|
||||
* maps a name to the tree index of an expression equal to the
|
||||
* auxiliary variable at time zero. The auxiliary variables
|
||||
* names point to the dynamic atoms storage, tree inidices to
|
||||
* the dynamic model tree. */
|
||||
Tsubstmap aux_map;
|
||||
/** Static version of aux_map. The names point to static_atoms
|
||||
* storage, the tree indices to the static_tree. */
|
||||
Tsubstmap static_aux_map;
|
||||
/** Information about the number of various things. */
|
||||
PlannerInfo info;
|
||||
public:
|
||||
/** Build the planner problem for the given model optimizing
|
||||
* through the given endogenous variables with the given
|
||||
* constraints. We allow for a selection of a subset of
|
||||
* equations and variables in order to eliminate exogenous
|
||||
* predetermined process which cannot be influenced by the
|
||||
* social planner. */
|
||||
PlannerBuilder(ogdyn::DynareModel& m, const Tvarset& yyset,
|
||||
const Teqset& ffset);
|
||||
/** Construct a copy of the builder with provided model, which
|
||||
* is supposed to be the copy of the model in the builder. */
|
||||
PlannerBuilder(const PlannerBuilder& pb, ogdyn::DynareModel& m);
|
||||
/** Return the information. */
|
||||
const PlannerInfo& get_info() const
|
||||
{return info;}
|
||||
protected:
|
||||
/** Differentiate the planner objective wrt endogenous
|
||||
* variables with different lags. */
|
||||
void add_derivatives_of_b();
|
||||
/** Differentiate the constraints wrt endogenous variables
|
||||
* with different lags and leads. */
|
||||
void add_derivatives_of_f();
|
||||
/** Shift derivatives of diff_b. */
|
||||
void shift_derivatives_of_b();
|
||||
/** Shift derivatives of diff_ff. */
|
||||
void shift_derivatives_of_f();
|
||||
/** Multiply with the discount factor terms in diff_b. */
|
||||
void beta_multiply_b();
|
||||
/** Multiply with the discount factor terms in diff_f. */
|
||||
void beta_multiply_f();
|
||||
/** Fill static_atoms and static_tree and build diff_b_static,
|
||||
* diff_f_static and aux_map_static with static versions of diff_b,
|
||||
* diff_f and aux_map. */
|
||||
void make_static_version();
|
||||
/** Multiply diff_f with Langrange multipliers. */
|
||||
void lagrange_mult_f();
|
||||
/** Add the equations to the mode, including equation for auxiliary variables. */
|
||||
void form_equations();
|
||||
private:
|
||||
/** Fill yset for a given yyset and given name storage. */
|
||||
void fill_yset(const ogp::NameStorage& ns, const Tvarset& yyset);
|
||||
/** Fill aux_map and aux_map_static for a given aaux_map and
|
||||
* aaux_map_static for a given storage of dynamic atoms (used
|
||||
* for aux_map) and static atoms storage from this object for
|
||||
* aux_map_static. */
|
||||
void fill_aux_map(const ogp::NameStorage& ns, const Tsubstmap& aaux_map,
|
||||
const Tsubstmap& astatic_aux_map);
|
||||
/** Avoid copying from only PlannerBuilder. */
|
||||
PlannerBuilder(const PlannerBuilder& pb);
|
||||
};
|
||||
/** This class builds the first order conditions of the social
|
||||
* planner problem with constraints being the equations in the
|
||||
* model. The model is non-const parameter to the constructor
|
||||
* which adds appropriate FOCs to the system. It also allows for
|
||||
* an estimation of the lagrange multipliers given all other
|
||||
* endogenous variables of the static system. For this purpose we
|
||||
* need to create static atoms and static versions of all the tree
|
||||
* index matrices. The algorithm and algebra are documented in
|
||||
* dynare++-ramsey.pdf. */
|
||||
class PlannerBuilder
|
||||
{
|
||||
friend class MultInitSS;
|
||||
public:
|
||||
/** Type for a set of variable names. */
|
||||
typedef unordered_set<const char *> Tvarset;
|
||||
/** Type for a set of equations. An equation is identified by
|
||||
* an index to an equation in the equation vector given by
|
||||
* DynareModel::eqs. The tree index of the i-th formula is
|
||||
* retrieved as DynareModel::egs.formula(i). */
|
||||
typedef vector<int> Teqset;
|
||||
protected:
|
||||
/** This is a set of variables wrt which the planner
|
||||
* optimizes. These could be all endogenous variables, but it
|
||||
* is beneficial to exclude all variables which are
|
||||
* deterministic transformations of past exogenous variables,
|
||||
* since the planner cannot influence them. This could save a
|
||||
* few equations. This is not changed after it is constructed,
|
||||
* but it is constructed manually, so it cannot be declared as
|
||||
* const. */
|
||||
Tvarset yset;
|
||||
/** These are the equation indices constituing the constraints
|
||||
* for the planner. Again, it is beneficial to exclude all
|
||||
* equations defining exogenous variables excluded from
|
||||
* yset. */
|
||||
const Teqset fset;
|
||||
/** Reference to the model. */
|
||||
ogdyn::DynareModel &model;
|
||||
/** Tree index of the planner objective. */
|
||||
int tb;
|
||||
/** Tree index of the planner discount parameter. */
|
||||
int tbeta;
|
||||
/** The maximum lead in the model including the planner's
|
||||
* objective before building the planner's FOCs. */
|
||||
const int maxlead;
|
||||
/** The minimum lag in the model including the planner's objective
|
||||
* before building the planner's FOCs. */
|
||||
const int minlag;
|
||||
/** Tree indices of formulas in the planner FOCs involving
|
||||
* derivatives of the planner's objective. Rows correspond to the
|
||||
* endogenous variables, columns correspond to lags in the
|
||||
* objective function. The contents of the matrix will evolve as
|
||||
* the algorithm proceeds. */
|
||||
IntegerMatrix diff_b;
|
||||
/** Tree indices of formulas in the planner FOCs involving
|
||||
* derivatives of the model equations (constraints). The first
|
||||
* dimension corresponds to endogenous variables, the second to
|
||||
* the constraints, the third to lags or leads of endogenous
|
||||
* variables in the constraints. The contents of the array will
|
||||
* evolve as the algorithm proceeds.*/
|
||||
IntegerArray3 diff_f;
|
||||
/** Static version of the model atoms. It is needed to build
|
||||
* static version of diff_b and diff_f. */
|
||||
ogp::StaticFineAtoms static_atoms;
|
||||
/** Static version of all the trees of diff_b and diff_f build
|
||||
* over static_atoms. */
|
||||
ogp::OperationTree static_tree;
|
||||
/** Tree indices of static version of diff_b over static_atoms and static_tree. */
|
||||
IntegerMatrix diff_b_static;
|
||||
/** Tree indices of static version of diff_f over static_atoms
|
||||
* and static_tree. This member is created before calling
|
||||
* lagrange_mult_f(), so it does not contain the
|
||||
* multiplication with the lagrange multipliers. */
|
||||
IntegerArray3 diff_f_static;
|
||||
/** Auxiliary variables mapping. During the algorithm, some
|
||||
* auxiliary variables for the terms might be created, so we
|
||||
* remember their names and tree indices of the terms. This
|
||||
* maps a name to the tree index of an expression equal to the
|
||||
* auxiliary variable at time zero. The auxiliary variables
|
||||
* names point to the dynamic atoms storage, tree inidices to
|
||||
* the dynamic model tree. */
|
||||
Tsubstmap aux_map;
|
||||
/** Static version of aux_map. The names point to static_atoms
|
||||
* storage, the tree indices to the static_tree. */
|
||||
Tsubstmap static_aux_map;
|
||||
/** Information about the number of various things. */
|
||||
PlannerInfo info;
|
||||
public:
|
||||
/** Build the planner problem for the given model optimizing
|
||||
* through the given endogenous variables with the given
|
||||
* constraints. We allow for a selection of a subset of
|
||||
* equations and variables in order to eliminate exogenous
|
||||
* predetermined process which cannot be influenced by the
|
||||
* social planner. */
|
||||
PlannerBuilder(ogdyn::DynareModel &m, const Tvarset &yyset,
|
||||
const Teqset &ffset);
|
||||
/** Construct a copy of the builder with provided model, which
|
||||
* is supposed to be the copy of the model in the builder. */
|
||||
PlannerBuilder(const PlannerBuilder &pb, ogdyn::DynareModel &m);
|
||||
/** Return the information. */
|
||||
const PlannerInfo &
|
||||
get_info() const
|
||||
{
|
||||
return info;
|
||||
}
|
||||
protected:
|
||||
/** Differentiate the planner objective wrt endogenous
|
||||
* variables with different lags. */
|
||||
void add_derivatives_of_b();
|
||||
/** Differentiate the constraints wrt endogenous variables
|
||||
* with different lags and leads. */
|
||||
void add_derivatives_of_f();
|
||||
/** Shift derivatives of diff_b. */
|
||||
void shift_derivatives_of_b();
|
||||
/** Shift derivatives of diff_ff. */
|
||||
void shift_derivatives_of_f();
|
||||
/** Multiply with the discount factor terms in diff_b. */
|
||||
void beta_multiply_b();
|
||||
/** Multiply with the discount factor terms in diff_f. */
|
||||
void beta_multiply_f();
|
||||
/** Fill static_atoms and static_tree and build diff_b_static,
|
||||
* diff_f_static and aux_map_static with static versions of diff_b,
|
||||
* diff_f and aux_map. */
|
||||
void make_static_version();
|
||||
/** Multiply diff_f with Langrange multipliers. */
|
||||
void lagrange_mult_f();
|
||||
/** Add the equations to the mode, including equation for auxiliary variables. */
|
||||
void form_equations();
|
||||
private:
|
||||
/** Fill yset for a given yyset and given name storage. */
|
||||
void fill_yset(const ogp::NameStorage &ns, const Tvarset &yyset);
|
||||
/** Fill aux_map and aux_map_static for a given aaux_map and
|
||||
* aaux_map_static for a given storage of dynamic atoms (used
|
||||
* for aux_map) and static atoms storage from this object for
|
||||
* aux_map_static. */
|
||||
void fill_aux_map(const ogp::NameStorage &ns, const Tsubstmap &aaux_map,
|
||||
const Tsubstmap &astatic_aux_map);
|
||||
/** Avoid copying from only PlannerBuilder. */
|
||||
PlannerBuilder(const PlannerBuilder &pb);
|
||||
};
|
||||
|
||||
/** This class only calculates for the given initial guess of
|
||||
* endogenous variables, initial guess of the Langrange
|
||||
* multipliers of the social planner problem yielding the least
|
||||
* square error. It is used by just calling its constructor. The
|
||||
* constructor takes non-const reference to the vector of
|
||||
* endogenous variables, calculates lambdas and put the values of
|
||||
* lambdas to the vector. The algbera is found in
|
||||
* dynare++-ramsey.pdf.
|
||||
*
|
||||
* The code can be run only after the parsing has been finished in
|
||||
* atoms. */
|
||||
class MultInitSS : public ogp::FormulaEvalLoader {
|
||||
protected:
|
||||
/** The constant reference to the builder. */
|
||||
const PlannerBuilder& builder;
|
||||
/** The constant term of the problem. Its length is the number
|
||||
* of endogenous variable wrt the planner optimizes. */
|
||||
Vector b;
|
||||
/** The matrix of the overdetermined problem. The number of
|
||||
* rows is equal to the number of endogenous variables wrt
|
||||
* which the planner optimizes, the number of columns is equal
|
||||
* to the number of Langrange multipliers which is equal to
|
||||
* the number of constraints which is smaller than the number
|
||||
* of endogenous variables. Hence the system b+F*lambda=0 is
|
||||
* overdetermined. */
|
||||
GeneralMatrix F;
|
||||
public:
|
||||
/** The constructor of the object which does everything. Its
|
||||
* main goal is to update yy. Note that if an item of yy
|
||||
* corresponding to a lagrange multiplier is already set, it
|
||||
* is not reset. */
|
||||
MultInitSS(const PlannerBuilder& pb, const Vector& pvals, Vector& yy);
|
||||
/** This loads evaluated parts of b or F and decodes i and
|
||||
* advances b or F depending on the decoded i. The decoding is
|
||||
* dependent on the way how the terms of builder.diff_b and
|
||||
* builder.diff_f_save have been put the the
|
||||
* ogp::FormulaCustomEvaluator. This is documented in the code
|
||||
* of the constructor. */
|
||||
void load(int i, double res);
|
||||
};
|
||||
/** This class only calculates for the given initial guess of
|
||||
* endogenous variables, initial guess of the Langrange
|
||||
* multipliers of the social planner problem yielding the least
|
||||
* square error. It is used by just calling its constructor. The
|
||||
* constructor takes non-const reference to the vector of
|
||||
* endogenous variables, calculates lambdas and put the values of
|
||||
* lambdas to the vector. The algbera is found in
|
||||
* dynare++-ramsey.pdf.
|
||||
*
|
||||
* The code can be run only after the parsing has been finished in
|
||||
* atoms. */
|
||||
class MultInitSS : public ogp::FormulaEvalLoader
|
||||
{
|
||||
protected:
|
||||
/** The constant reference to the builder. */
|
||||
const PlannerBuilder &builder;
|
||||
/** The constant term of the problem. Its length is the number
|
||||
* of endogenous variable wrt the planner optimizes. */
|
||||
Vector b;
|
||||
/** The matrix of the overdetermined problem. The number of
|
||||
* rows is equal to the number of endogenous variables wrt
|
||||
* which the planner optimizes, the number of columns is equal
|
||||
* to the number of Langrange multipliers which is equal to
|
||||
* the number of constraints which is smaller than the number
|
||||
* of endogenous variables. Hence the system b+F*lambda=0 is
|
||||
* overdetermined. */
|
||||
GeneralMatrix F;
|
||||
public:
|
||||
/** The constructor of the object which does everything. Its
|
||||
* main goal is to update yy. Note that if an item of yy
|
||||
* corresponding to a lagrange multiplier is already set, it
|
||||
* is not reset. */
|
||||
MultInitSS(const PlannerBuilder &pb, const Vector &pvals, Vector &yy);
|
||||
/** This loads evaluated parts of b or F and decodes i and
|
||||
* advances b or F depending on the decoded i. The decoding is
|
||||
* dependent on the way how the terms of builder.diff_b and
|
||||
* builder.diff_f_save have been put the the
|
||||
* ogp::FormulaCustomEvaluator. This is documented in the code
|
||||
* of the constructor. */
|
||||
void load(int i, double res);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -7,47 +7,55 @@
|
|||
|
||||
#include "QuasiTriangular.h"
|
||||
|
||||
|
||||
class BlockDiagonal : public QuasiTriangular {
|
||||
int* const row_len;
|
||||
int* const col_len;
|
||||
class BlockDiagonal : public QuasiTriangular
|
||||
{
|
||||
int *const row_len;
|
||||
int *const col_len;
|
||||
public:
|
||||
BlockDiagonal(const double* d, int d_size);
|
||||
BlockDiagonal(int p, const BlockDiagonal& b);
|
||||
BlockDiagonal(const BlockDiagonal& b);
|
||||
BlockDiagonal(const QuasiTriangular& t);
|
||||
const BlockDiagonal& operator=(const QuasiTriangular& t)
|
||||
{GeneralMatrix::operator=(t); return *this;}
|
||||
const BlockDiagonal& operator=(const BlockDiagonal& b);
|
||||
~BlockDiagonal() {delete [] row_len; delete [] col_len;}
|
||||
void setZeroBlockEdge(diag_iter edge);
|
||||
int getNumZeros() const;
|
||||
int getNumBlocks() const;
|
||||
int getLargestBlock() const;
|
||||
void printInfo() const;
|
||||
BlockDiagonal(const double *d, int d_size);
|
||||
BlockDiagonal(int p, const BlockDiagonal &b);
|
||||
BlockDiagonal(const BlockDiagonal &b);
|
||||
BlockDiagonal(const QuasiTriangular &t);
|
||||
const BlockDiagonal &
|
||||
operator=(const QuasiTriangular &t)
|
||||
{
|
||||
GeneralMatrix::operator=(t); return *this;
|
||||
}
|
||||
const BlockDiagonal &operator=(const BlockDiagonal &b);
|
||||
~BlockDiagonal()
|
||||
{
|
||||
delete [] row_len; delete [] col_len;
|
||||
}
|
||||
void setZeroBlockEdge(diag_iter edge);
|
||||
int getNumZeros() const;
|
||||
int getNumBlocks() const;
|
||||
int getLargestBlock() const;
|
||||
void printInfo() const;
|
||||
|
||||
void multKron(KronVector& x) const;
|
||||
void multKronTrans(KronVector& x) const;
|
||||
void multKron(KronVector &x) const;
|
||||
void multKronTrans(KronVector &x) const;
|
||||
|
||||
const_col_iter col_begin(const DiagonalBlock& b) const;
|
||||
col_iter col_begin(const DiagonalBlock& b);
|
||||
const_row_iter row_end(const DiagonalBlock& b) const;
|
||||
row_iter row_end(const DiagonalBlock& b);
|
||||
QuasiTriangular* clone() const
|
||||
{return new BlockDiagonal(*this);}
|
||||
const_col_iter col_begin(const DiagonalBlock &b) const;
|
||||
col_iter col_begin(const DiagonalBlock &b);
|
||||
const_row_iter row_end(const DiagonalBlock &b) const;
|
||||
row_iter row_end(const DiagonalBlock &b);
|
||||
QuasiTriangular *
|
||||
clone() const
|
||||
{
|
||||
return new BlockDiagonal(*this);
|
||||
}
|
||||
private:
|
||||
void setZerosToRU(diag_iter edge);
|
||||
const_diag_iter findBlockStart(const_diag_iter from) const;
|
||||
static void savePartOfX(int si, int ei, const KronVector& x, Vector& work);
|
||||
void multKronBlock(const_diag_iter start, const_diag_iter end,
|
||||
KronVector& x, Vector& work) const;
|
||||
void multKronBlockTrans(const_diag_iter start, const_diag_iter end,
|
||||
KronVector& x, Vector& work) const;
|
||||
void setZerosToRU(diag_iter edge);
|
||||
const_diag_iter findBlockStart(const_diag_iter from) const;
|
||||
static void savePartOfX(int si, int ei, const KronVector &x, Vector &work);
|
||||
void multKronBlock(const_diag_iter start, const_diag_iter end,
|
||||
KronVector &x, Vector &work) const;
|
||||
void multKronBlockTrans(const_diag_iter start, const_diag_iter end,
|
||||
KronVector &x, Vector &work) const;
|
||||
};
|
||||
|
||||
#endif /* BLOCK_DIAGONAL_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -11,310 +11,484 @@
|
|||
|
||||
class GeneralMatrix;
|
||||
|
||||
class ConstGeneralMatrix {
|
||||
friend class GeneralMatrix;
|
||||
class ConstGeneralMatrix
|
||||
{
|
||||
friend class GeneralMatrix;
|
||||
protected:
|
||||
ConstVector data;
|
||||
int rows;
|
||||
int cols;
|
||||
int ld;
|
||||
ConstVector data;
|
||||
int rows;
|
||||
int cols;
|
||||
int ld;
|
||||
public:
|
||||
ConstGeneralMatrix(const double* d, int m, int n)
|
||||
: data(d, m*n), rows(m), cols(n), ld(m) {}
|
||||
ConstGeneralMatrix(const GeneralMatrix& m);
|
||||
ConstGeneralMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols);
|
||||
ConstGeneralMatrix(const ConstGeneralMatrix& m, int i, int j, int nrows, int ncols);
|
||||
virtual ~ConstGeneralMatrix() {}
|
||||
ConstGeneralMatrix(const double *d, int m, int n)
|
||||
: data(d, m*n), rows(m), cols(n), ld(m)
|
||||
{
|
||||
}
|
||||
ConstGeneralMatrix(const GeneralMatrix &m);
|
||||
ConstGeneralMatrix(const GeneralMatrix &m, int i, int j, int nrows, int ncols);
|
||||
ConstGeneralMatrix(const ConstGeneralMatrix &m, int i, int j, int nrows, int ncols);
|
||||
virtual ~ConstGeneralMatrix()
|
||||
{
|
||||
}
|
||||
|
||||
const double& get(int i, int j) const
|
||||
{return data[j*ld+i];}
|
||||
int numRows() const {return rows;}
|
||||
int numCols() const {return cols;}
|
||||
int getLD() const {return ld;}
|
||||
const double* base() const {return data.base();}
|
||||
const ConstVector& getData() const {return data;}
|
||||
const double &
|
||||
get(int i, int j) const
|
||||
{
|
||||
return data[j*ld+i];
|
||||
}
|
||||
int
|
||||
numRows() const
|
||||
{
|
||||
return rows;
|
||||
}
|
||||
int
|
||||
numCols() const
|
||||
{
|
||||
return cols;
|
||||
}
|
||||
int
|
||||
getLD() const
|
||||
{
|
||||
return ld;
|
||||
}
|
||||
const double *
|
||||
base() const
|
||||
{
|
||||
return data.base();
|
||||
}
|
||||
const ConstVector &
|
||||
getData() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
double getNormInf() const;
|
||||
double getNorm1() const;
|
||||
/* x = scalar(a)*x + scalar(b)*this*d */
|
||||
void multVec(double a, Vector& x, double b, const ConstVector& d) const;
|
||||
/* x = scalar(a)*x + scalar(b)*this'*d */
|
||||
void multVecTrans(double a, Vector& x, double b, const ConstVector& d) const;
|
||||
/* x = x + this*d */
|
||||
void multaVec(Vector& x, const ConstVector& d) const
|
||||
{multVec(1.0, x, 1.0, d);}
|
||||
/* x = x + this'*d */
|
||||
void multaVecTrans(Vector& x, const ConstVector& d) const
|
||||
{multVecTrans(1.0, x, 1.0, d);}
|
||||
/* x = x - this*d */
|
||||
void multsVec(Vector& x, const ConstVector& d) const
|
||||
{multVec(1.0, x, -1.0, d);}
|
||||
/* x = x - this'*d */
|
||||
void multsVecTrans(Vector& x, const ConstVector& d) const
|
||||
{multVecTrans(1.0, x, -1.0, d);}
|
||||
/* m = inv(this)*m */
|
||||
void multInvLeft(GeneralMatrix& m) const;
|
||||
/* m = inv(this')*m */
|
||||
void multInvLeftTrans(GeneralMatrix& m) const;
|
||||
/* d = inv(this)*d */
|
||||
void multInvLeft(Vector& d) const;
|
||||
/* d = inv(this')*d */
|
||||
void multInvLeftTrans(Vector& d) const;
|
||||
double getNormInf() const;
|
||||
double getNorm1() const;
|
||||
/* x = scalar(a)*x + scalar(b)*this*d */
|
||||
void multVec(double a, Vector &x, double b, const ConstVector &d) const;
|
||||
/* x = scalar(a)*x + scalar(b)*this'*d */
|
||||
void multVecTrans(double a, Vector &x, double b, const ConstVector &d) const;
|
||||
/* x = x + this*d */
|
||||
void
|
||||
multaVec(Vector &x, const ConstVector &d) const
|
||||
{
|
||||
multVec(1.0, x, 1.0, d);
|
||||
}
|
||||
/* x = x + this'*d */
|
||||
void
|
||||
multaVecTrans(Vector &x, const ConstVector &d) const
|
||||
{
|
||||
multVecTrans(1.0, x, 1.0, d);
|
||||
}
|
||||
/* x = x - this*d */
|
||||
void
|
||||
multsVec(Vector &x, const ConstVector &d) const
|
||||
{
|
||||
multVec(1.0, x, -1.0, d);
|
||||
}
|
||||
/* x = x - this'*d */
|
||||
void
|
||||
multsVecTrans(Vector &x, const ConstVector &d) const
|
||||
{
|
||||
multVecTrans(1.0, x, -1.0, d);
|
||||
}
|
||||
/* m = inv(this)*m */
|
||||
void multInvLeft(GeneralMatrix &m) const;
|
||||
/* m = inv(this')*m */
|
||||
void multInvLeftTrans(GeneralMatrix &m) const;
|
||||
/* d = inv(this)*d */
|
||||
void multInvLeft(Vector &d) const;
|
||||
/* d = inv(this')*d */
|
||||
void multInvLeftTrans(Vector &d) const;
|
||||
|
||||
bool isFinite() const;
|
||||
/** Returns true of the matrix is exactly zero. */
|
||||
bool isZero() const;
|
||||
bool isFinite() const;
|
||||
/** Returns true of the matrix is exactly zero. */
|
||||
bool isZero() const;
|
||||
|
||||
virtual void print() const;
|
||||
virtual void print() const;
|
||||
protected:
|
||||
void multInvLeft(const char* trans, int mrows, int mcols, int mld, double* d) const;
|
||||
void multInvLeft(const char *trans, int mrows, int mcols, int mld, double *d) const;
|
||||
};
|
||||
|
||||
|
||||
class GeneralMatrix {
|
||||
friend class ConstGeneralMatrix;
|
||||
class GeneralMatrix
|
||||
{
|
||||
friend class ConstGeneralMatrix;
|
||||
protected:
|
||||
Vector data;
|
||||
int rows;
|
||||
int cols;
|
||||
int ld;
|
||||
Vector data;
|
||||
int rows;
|
||||
int cols;
|
||||
int ld;
|
||||
public:
|
||||
GeneralMatrix(int m, int n)
|
||||
: data(m*n), rows(m), cols(n), ld(m) {}
|
||||
GeneralMatrix(const double* d, int m, int n)
|
||||
: data(d, m*n), rows(m), cols(n), ld(m) {}
|
||||
GeneralMatrix(double* d, int m, int n)
|
||||
: data(d, m*n), rows(m), cols(n), ld(m) {}
|
||||
GeneralMatrix(const GeneralMatrix& m);
|
||||
GeneralMatrix(const ConstGeneralMatrix& m);
|
||||
GeneralMatrix(const GeneralMatrix&m, const char* dummy); // transpose
|
||||
GeneralMatrix(const ConstGeneralMatrix&m, const char* dummy); // transpose
|
||||
GeneralMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols);
|
||||
GeneralMatrix(GeneralMatrix& m, int i, int j, int nrows, int ncols);
|
||||
/* this = a*b */
|
||||
GeneralMatrix(const GeneralMatrix& a, const GeneralMatrix& b);
|
||||
/* this = a*b' */
|
||||
GeneralMatrix(const GeneralMatrix& a, const GeneralMatrix& b, const char* dum);
|
||||
/* this = a'*b */
|
||||
GeneralMatrix(const GeneralMatrix& a, const char* dum, const GeneralMatrix& b);
|
||||
/* this = a'*b */
|
||||
GeneralMatrix(const GeneralMatrix& a, const char* dum1,
|
||||
const GeneralMatrix& b, const char* dum2);
|
||||
GeneralMatrix(int m, int n)
|
||||
: data(m*n), rows(m), cols(n), ld(m)
|
||||
{
|
||||
}
|
||||
GeneralMatrix(const double *d, int m, int n)
|
||||
: data(d, m*n), rows(m), cols(n), ld(m)
|
||||
{
|
||||
}
|
||||
GeneralMatrix(double *d, int m, int n)
|
||||
: data(d, m*n), rows(m), cols(n), ld(m)
|
||||
{
|
||||
}
|
||||
GeneralMatrix(const GeneralMatrix &m);
|
||||
GeneralMatrix(const ConstGeneralMatrix &m);
|
||||
GeneralMatrix(const GeneralMatrix &m, const char *dummy); // transpose
|
||||
GeneralMatrix(const ConstGeneralMatrix &m, const char *dummy); // transpose
|
||||
GeneralMatrix(const GeneralMatrix &m, int i, int j, int nrows, int ncols);
|
||||
GeneralMatrix(GeneralMatrix &m, int i, int j, int nrows, int ncols);
|
||||
/* this = a*b */
|
||||
GeneralMatrix(const GeneralMatrix &a, const GeneralMatrix &b);
|
||||
/* this = a*b' */
|
||||
GeneralMatrix(const GeneralMatrix &a, const GeneralMatrix &b, const char *dum);
|
||||
/* this = a'*b */
|
||||
GeneralMatrix(const GeneralMatrix &a, const char *dum, const GeneralMatrix &b);
|
||||
/* this = a'*b */
|
||||
GeneralMatrix(const GeneralMatrix &a, const char *dum1,
|
||||
const GeneralMatrix &b, const char *dum2);
|
||||
|
||||
virtual ~GeneralMatrix();
|
||||
const GeneralMatrix& operator=(const GeneralMatrix& m)
|
||||
{data=m.data; rows=m.rows; cols=m.cols; ld=m.ld; return *this;}
|
||||
virtual
|
||||
~GeneralMatrix();
|
||||
const GeneralMatrix &
|
||||
operator=(const GeneralMatrix &m)
|
||||
{
|
||||
data = m.data; rows = m.rows; cols = m.cols; ld = m.ld; return *this;
|
||||
}
|
||||
|
||||
const double& get(int i, int j) const
|
||||
{return data[j*ld+i];}
|
||||
double& get(int i, int j)
|
||||
{return data[j*ld+i];}
|
||||
int numRows() const {return rows;}
|
||||
int numCols() const {return cols;}
|
||||
int getLD() const {return ld;}
|
||||
double* base() {return data.base();}
|
||||
const double* base() const {return data.base();}
|
||||
Vector& getData() {return data;}
|
||||
const Vector& getData() const {return data;}
|
||||
const double &
|
||||
get(int i, int j) const
|
||||
{
|
||||
return data[j*ld+i];
|
||||
}
|
||||
double &
|
||||
get(int i, int j)
|
||||
{
|
||||
return data[j*ld+i];
|
||||
}
|
||||
int
|
||||
numRows() const
|
||||
{
|
||||
return rows;
|
||||
}
|
||||
int
|
||||
numCols() const
|
||||
{
|
||||
return cols;
|
||||
}
|
||||
int
|
||||
getLD() const
|
||||
{
|
||||
return ld;
|
||||
}
|
||||
double *
|
||||
base()
|
||||
{
|
||||
return data.base();
|
||||
}
|
||||
const double *
|
||||
base() const
|
||||
{
|
||||
return data.base();
|
||||
}
|
||||
Vector &
|
||||
getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
const Vector &
|
||||
getData() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
double getNormInf() const
|
||||
{return ConstGeneralMatrix(*this).getNormInf();}
|
||||
double getNorm1() const
|
||||
{return ConstGeneralMatrix(*this).getNorm1();}
|
||||
double
|
||||
getNormInf() const
|
||||
{
|
||||
return ConstGeneralMatrix(*this).getNormInf();
|
||||
}
|
||||
double
|
||||
getNorm1() const
|
||||
{
|
||||
return ConstGeneralMatrix(*this).getNorm1();
|
||||
}
|
||||
|
||||
/* place matrix m to the position (i,j) */
|
||||
void place(const ConstGeneralMatrix& m, int i, int j);
|
||||
void place(const GeneralMatrix& m, int i, int j)
|
||||
{place(ConstGeneralMatrix(m), i, j);}
|
||||
/* place matrix m to the position (i,j) */
|
||||
void place(const ConstGeneralMatrix &m, int i, int j);
|
||||
void
|
||||
place(const GeneralMatrix &m, int i, int j)
|
||||
{
|
||||
place(ConstGeneralMatrix(m), i, j);
|
||||
}
|
||||
|
||||
/* this = a*b */
|
||||
void mult(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b);
|
||||
void mult(const GeneralMatrix& a, const GeneralMatrix& b)
|
||||
{mult(ConstGeneralMatrix(a), ConstGeneralMatrix(b));}
|
||||
/* this = a*b */
|
||||
void mult(const ConstGeneralMatrix &a, const ConstGeneralMatrix &b);
|
||||
void
|
||||
mult(const GeneralMatrix &a, const GeneralMatrix &b)
|
||||
{
|
||||
mult(ConstGeneralMatrix(a), ConstGeneralMatrix(b));
|
||||
}
|
||||
|
||||
/* this = this + scalar*a*b */
|
||||
void multAndAdd(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b,
|
||||
double mult=1.0);
|
||||
void multAndAdd(const GeneralMatrix& a, const GeneralMatrix& b,
|
||||
double mult=1.0)
|
||||
{multAndAdd(ConstGeneralMatrix(a), ConstGeneralMatrix(b), mult);}
|
||||
/* this = this + scalar*a*b */
|
||||
void multAndAdd(const ConstGeneralMatrix &a, const ConstGeneralMatrix &b,
|
||||
double mult = 1.0);
|
||||
void
|
||||
multAndAdd(const GeneralMatrix &a, const GeneralMatrix &b,
|
||||
double mult = 1.0)
|
||||
{
|
||||
multAndAdd(ConstGeneralMatrix(a), ConstGeneralMatrix(b), mult);
|
||||
}
|
||||
|
||||
/* this = this + scalar*a*b' */
|
||||
void multAndAdd(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b,
|
||||
const char* dum, double mult=1.0);
|
||||
void multAndAdd(const GeneralMatrix& a, const GeneralMatrix& b,
|
||||
const char* dum, double mult=1.0)
|
||||
{multAndAdd(ConstGeneralMatrix(a), ConstGeneralMatrix(b), dum, mult);}
|
||||
/* this = this + scalar*a*b' */
|
||||
void multAndAdd(const ConstGeneralMatrix &a, const ConstGeneralMatrix &b,
|
||||
const char *dum, double mult = 1.0);
|
||||
void
|
||||
multAndAdd(const GeneralMatrix &a, const GeneralMatrix &b,
|
||||
const char *dum, double mult = 1.0)
|
||||
{
|
||||
multAndAdd(ConstGeneralMatrix(a), ConstGeneralMatrix(b), dum, mult);
|
||||
}
|
||||
|
||||
/* this = this + scalar*a'*b */
|
||||
void multAndAdd(const ConstGeneralMatrix& a, const char* dum, const ConstGeneralMatrix& b,
|
||||
double mult=1.0);
|
||||
void multAndAdd(const GeneralMatrix& a, const char* dum, const GeneralMatrix& b,
|
||||
double mult=1.0)
|
||||
{multAndAdd(ConstGeneralMatrix(a), dum, ConstGeneralMatrix(b), mult);}
|
||||
/* this = this + scalar*a'*b */
|
||||
void multAndAdd(const ConstGeneralMatrix &a, const char *dum, const ConstGeneralMatrix &b,
|
||||
double mult = 1.0);
|
||||
void
|
||||
multAndAdd(const GeneralMatrix &a, const char *dum, const GeneralMatrix &b,
|
||||
double mult = 1.0)
|
||||
{
|
||||
multAndAdd(ConstGeneralMatrix(a), dum, ConstGeneralMatrix(b), mult);
|
||||
}
|
||||
|
||||
/* this = this + scalar*a'*b' */
|
||||
void multAndAdd(const ConstGeneralMatrix& a, const char* dum1,
|
||||
const ConstGeneralMatrix& b, const char* dum2, double mult=1.0);
|
||||
void multAndAdd(const GeneralMatrix& a, const char* dum1,
|
||||
const GeneralMatrix& b, const char* dum2, double mult=1.0)
|
||||
{multAndAdd(ConstGeneralMatrix(a), dum1, ConstGeneralMatrix(b),dum2, mult);}
|
||||
/* this = this + scalar*a'*b' */
|
||||
void multAndAdd(const ConstGeneralMatrix &a, const char *dum1,
|
||||
const ConstGeneralMatrix &b, const char *dum2, double mult = 1.0);
|
||||
void
|
||||
multAndAdd(const GeneralMatrix &a, const char *dum1,
|
||||
const GeneralMatrix &b, const char *dum2, double mult = 1.0)
|
||||
{
|
||||
multAndAdd(ConstGeneralMatrix(a), dum1, ConstGeneralMatrix(b), dum2, mult);
|
||||
}
|
||||
|
||||
/* this = this + scalar*a*a' */
|
||||
void addOuter(const ConstVector& a, double mult=1.0);
|
||||
void addOuter(const Vector& a, double mult=1.0)
|
||||
{addOuter(ConstVector(a), mult);}
|
||||
/* this = this + scalar*a*a' */
|
||||
void addOuter(const ConstVector &a, double mult = 1.0);
|
||||
void
|
||||
addOuter(const Vector &a, double mult = 1.0)
|
||||
{
|
||||
addOuter(ConstVector(a), mult);
|
||||
}
|
||||
|
||||
/* this = this * m */
|
||||
void multRight(const ConstGeneralMatrix& m);
|
||||
void multRight(const GeneralMatrix& m)
|
||||
{multRight(ConstGeneralMatrix(m));}
|
||||
/* this = this * m */
|
||||
void multRight(const ConstGeneralMatrix &m);
|
||||
void
|
||||
multRight(const GeneralMatrix &m)
|
||||
{
|
||||
multRight(ConstGeneralMatrix(m));
|
||||
}
|
||||
|
||||
/* this = m * this */
|
||||
void multLeft(const ConstGeneralMatrix& m);
|
||||
void multLeft(const GeneralMatrix& m)
|
||||
{multLeft(ConstGeneralMatrix(m));}
|
||||
/* this = m * this */
|
||||
void multLeft(const ConstGeneralMatrix &m);
|
||||
void
|
||||
multLeft(const GeneralMatrix &m)
|
||||
{
|
||||
multLeft(ConstGeneralMatrix(m));
|
||||
}
|
||||
|
||||
/* this = this * m' */
|
||||
void multRightTrans(const ConstGeneralMatrix& m);
|
||||
void multRightTrans(const GeneralMatrix& m)
|
||||
{multRightTrans(ConstGeneralMatrix(m));}
|
||||
/* this = this * m' */
|
||||
void multRightTrans(const ConstGeneralMatrix &m);
|
||||
void
|
||||
multRightTrans(const GeneralMatrix &m)
|
||||
{
|
||||
multRightTrans(ConstGeneralMatrix(m));
|
||||
}
|
||||
|
||||
/* this = m' * this */
|
||||
void multLeftTrans(const ConstGeneralMatrix& m);
|
||||
void multLeftTrans(const GeneralMatrix& m)
|
||||
{multLeftTrans(ConstGeneralMatrix(m));}
|
||||
/* this = m' * this */
|
||||
void multLeftTrans(const ConstGeneralMatrix &m);
|
||||
void
|
||||
multLeftTrans(const GeneralMatrix &m)
|
||||
{
|
||||
multLeftTrans(ConstGeneralMatrix(m));
|
||||
}
|
||||
|
||||
/* x = scalar(a)*x + scalar(b)*this*d */
|
||||
void multVec(double a, Vector& x, double b, const ConstVector& d) const
|
||||
{ConstGeneralMatrix(*this).multVec(a, x, b, d);}
|
||||
/* x = scalar(a)*x + scalar(b)*this*d */
|
||||
void
|
||||
multVec(double a, Vector &x, double b, const ConstVector &d) const
|
||||
{
|
||||
ConstGeneralMatrix(*this).multVec(a, x, b, d);
|
||||
}
|
||||
|
||||
/* x = scalar(a)*x + scalar(b)*this'*d */
|
||||
void multVecTrans(double a, Vector& x, double b, const ConstVector& d) const
|
||||
{ConstGeneralMatrix(*this).multVecTrans(a, x, b, d);}
|
||||
/* x = scalar(a)*x + scalar(b)*this'*d */
|
||||
void
|
||||
multVecTrans(double a, Vector &x, double b, const ConstVector &d) const
|
||||
{
|
||||
ConstGeneralMatrix(*this).multVecTrans(a, x, b, d);
|
||||
}
|
||||
|
||||
/* x = x + this*d */
|
||||
void multaVec(Vector& x, const ConstVector& d) const
|
||||
{ConstGeneralMatrix(*this).multaVec(x, d);}
|
||||
/* x = x + this*d */
|
||||
void
|
||||
multaVec(Vector &x, const ConstVector &d) const
|
||||
{
|
||||
ConstGeneralMatrix(*this).multaVec(x, d);
|
||||
}
|
||||
|
||||
/* x = x + this'*d */
|
||||
void multaVecTrans(Vector& x, const ConstVector& d) const
|
||||
{ConstGeneralMatrix(*this).multaVecTrans(x, d);}
|
||||
/* x = x + this'*d */
|
||||
void
|
||||
multaVecTrans(Vector &x, const ConstVector &d) const
|
||||
{
|
||||
ConstGeneralMatrix(*this).multaVecTrans(x, d);
|
||||
}
|
||||
|
||||
/* x = x - this*d */
|
||||
void multsVec(Vector& x, const ConstVector& d) const
|
||||
{ConstGeneralMatrix(*this).multsVec(x, d);}
|
||||
/* x = x - this*d */
|
||||
void
|
||||
multsVec(Vector &x, const ConstVector &d) const
|
||||
{
|
||||
ConstGeneralMatrix(*this).multsVec(x, d);
|
||||
}
|
||||
|
||||
/* x = x - this'*d */
|
||||
void multsVecTrans(Vector& x, const ConstVector& d) const
|
||||
{ConstGeneralMatrix(*this).multsVecTrans(x, d);}
|
||||
/* x = x - this'*d */
|
||||
void
|
||||
multsVecTrans(Vector &x, const ConstVector &d) const
|
||||
{
|
||||
ConstGeneralMatrix(*this).multsVecTrans(x, d);
|
||||
}
|
||||
|
||||
/* this = zero */
|
||||
void zeros();
|
||||
/* this = zero */
|
||||
void zeros();
|
||||
|
||||
/** this = unit (on main diagonal) */
|
||||
void unit();
|
||||
/** this = unit (on main diagonal) */
|
||||
void unit();
|
||||
|
||||
/* this = NaN */
|
||||
void nans();
|
||||
/* this = NaN */
|
||||
void nans();
|
||||
|
||||
/* this = Inf */
|
||||
void infs();
|
||||
/* this = Inf */
|
||||
void infs();
|
||||
|
||||
/* this = scalar*this */
|
||||
void mult(double a);
|
||||
/* this = scalar*this */
|
||||
void mult(double a);
|
||||
|
||||
/* this = this + scalar*m */
|
||||
void add(double a, const ConstGeneralMatrix& m);
|
||||
void add(double a, const GeneralMatrix& m)
|
||||
{add(a, ConstGeneralMatrix(m));}
|
||||
/* this = this + scalar*m */
|
||||
void add(double a, const ConstGeneralMatrix &m);
|
||||
void
|
||||
add(double a, const GeneralMatrix &m)
|
||||
{
|
||||
add(a, ConstGeneralMatrix(m));
|
||||
}
|
||||
|
||||
/* this = this + scalar*m' */
|
||||
void add(double a, const ConstGeneralMatrix& m, const char* dum);
|
||||
void add(double a, const GeneralMatrix& m, const char* dum)
|
||||
{add(a, ConstGeneralMatrix(m), dum);}
|
||||
/* this = this + scalar*m' */
|
||||
void add(double a, const ConstGeneralMatrix &m, const char *dum);
|
||||
void
|
||||
add(double a, const GeneralMatrix &m, const char *dum)
|
||||
{
|
||||
add(a, ConstGeneralMatrix(m), dum);
|
||||
}
|
||||
|
||||
bool isFinite() const
|
||||
{return (ConstGeneralMatrix(*this)).isFinite();}
|
||||
bool
|
||||
isFinite() const
|
||||
{
|
||||
return (ConstGeneralMatrix(*this)).isFinite();
|
||||
}
|
||||
|
||||
bool isZero() const
|
||||
{return (ConstGeneralMatrix(*this)).isZero();}
|
||||
bool
|
||||
isZero() const
|
||||
{
|
||||
return (ConstGeneralMatrix(*this)).isZero();
|
||||
}
|
||||
|
||||
virtual void print() const
|
||||
{ConstGeneralMatrix(*this).print();}
|
||||
virtual void
|
||||
print() const
|
||||
{
|
||||
ConstGeneralMatrix(*this).print();
|
||||
}
|
||||
private:
|
||||
void copy(const ConstGeneralMatrix& m, int ioff = 0, int joff = 0);
|
||||
void copy(const GeneralMatrix& m, int ioff = 0, int joff = 0)
|
||||
{copy(ConstGeneralMatrix(m), ioff, joff);}
|
||||
void copy(const ConstGeneralMatrix &m, int ioff = 0, int joff = 0);
|
||||
void
|
||||
copy(const GeneralMatrix &m, int ioff = 0, int joff = 0)
|
||||
{
|
||||
copy(ConstGeneralMatrix(m), ioff, joff);
|
||||
}
|
||||
|
||||
void gemm(const char* transa, const ConstGeneralMatrix& a,
|
||||
const char* transb, const ConstGeneralMatrix& b,
|
||||
double alpha, double beta);
|
||||
void gemm(const char* transa, const GeneralMatrix& a,
|
||||
const char* transb, const GeneralMatrix& b,
|
||||
double alpha, double beta)
|
||||
{gemm(transa, ConstGeneralMatrix(a), transb, ConstGeneralMatrix(b),
|
||||
alpha, beta);}
|
||||
void gemm(const char *transa, const ConstGeneralMatrix &a,
|
||||
const char *transb, const ConstGeneralMatrix &b,
|
||||
double alpha, double beta);
|
||||
void
|
||||
gemm(const char *transa, const GeneralMatrix &a,
|
||||
const char *transb, const GeneralMatrix &b,
|
||||
double alpha, double beta)
|
||||
{
|
||||
gemm(transa, ConstGeneralMatrix(a), transb, ConstGeneralMatrix(b),
|
||||
alpha, beta);
|
||||
}
|
||||
|
||||
/* this = this * op(m) (without whole copy of this) */
|
||||
void gemm_partial_right(const char* trans, const ConstGeneralMatrix& m,
|
||||
double alpha, double beta);
|
||||
void gemm_partial_right(const char* trans, const GeneralMatrix& m,
|
||||
double alpha, double beta)
|
||||
{gemm_partial_right(trans, ConstGeneralMatrix(m), alpha, beta);}
|
||||
/* this = this * op(m) (without whole copy of this) */
|
||||
void gemm_partial_right(const char *trans, const ConstGeneralMatrix &m,
|
||||
double alpha, double beta);
|
||||
void
|
||||
gemm_partial_right(const char *trans, const GeneralMatrix &m,
|
||||
double alpha, double beta)
|
||||
{
|
||||
gemm_partial_right(trans, ConstGeneralMatrix(m), alpha, beta);
|
||||
}
|
||||
|
||||
/* this = op(m) *this (without whole copy of this) */
|
||||
void gemm_partial_left(const char* trans, const ConstGeneralMatrix& m,
|
||||
double alpha, double beta);
|
||||
void gemm_partial_left(const char* trans, const GeneralMatrix& m,
|
||||
double alpha, double beta)
|
||||
{gemm_partial_left(trans, ConstGeneralMatrix(m), alpha, beta);}
|
||||
/* this = op(m) *this (without whole copy of this) */
|
||||
void gemm_partial_left(const char *trans, const ConstGeneralMatrix &m,
|
||||
double alpha, double beta);
|
||||
void
|
||||
gemm_partial_left(const char *trans, const GeneralMatrix &m,
|
||||
double alpha, double beta)
|
||||
{
|
||||
gemm_partial_left(trans, ConstGeneralMatrix(m), alpha, beta);
|
||||
}
|
||||
|
||||
/* number of rows/columns for copy used in gemm_partial_* */
|
||||
static int md_length;
|
||||
/* number of rows/columns for copy used in gemm_partial_* */
|
||||
static int md_length;
|
||||
};
|
||||
|
||||
class SVDDecomp {
|
||||
class SVDDecomp
|
||||
{
|
||||
protected:
|
||||
/** Minimum of number of rows and columns of the decomposed
|
||||
* matrix. */
|
||||
const int minmn;
|
||||
/** Singular values. */
|
||||
Vector sigma;
|
||||
/** Orthogonal matrix U. */
|
||||
GeneralMatrix U;
|
||||
/** Orthogonal matrix V^T. */
|
||||
GeneralMatrix VT;
|
||||
/** Convered flag. */
|
||||
bool conv;
|
||||
/** Minimum of number of rows and columns of the decomposed
|
||||
* matrix. */
|
||||
const int minmn;
|
||||
/** Singular values. */
|
||||
Vector sigma;
|
||||
/** Orthogonal matrix U. */
|
||||
GeneralMatrix U;
|
||||
/** Orthogonal matrix V^T. */
|
||||
GeneralMatrix VT;
|
||||
/** Convered flag. */
|
||||
bool conv;
|
||||
public:
|
||||
SVDDecomp(const GeneralMatrix& A)
|
||||
: minmn(std::min<int>(A.numRows(), A.numCols())),
|
||||
sigma(minmn),
|
||||
U(A.numRows(), A.numRows()),
|
||||
VT(A.numCols(), A.numCols()),
|
||||
conv(false)
|
||||
{construct(A);}
|
||||
const GeneralMatrix& getU() const
|
||||
{return U;}
|
||||
const GeneralMatrix& getVT() const
|
||||
{return VT;}
|
||||
void solve(const GeneralMatrix& B, GeneralMatrix& X) const;
|
||||
void solve(const Vector& b, Vector& x) const
|
||||
{
|
||||
GeneralMatrix xmat(x.base(), x.length(), 1);
|
||||
solve(GeneralMatrix(b.base(), b.length(), 1), xmat);
|
||||
}
|
||||
SVDDecomp(const GeneralMatrix &A)
|
||||
: minmn(std::min<int>(A.numRows(), A.numCols())),
|
||||
sigma(minmn),
|
||||
U(A.numRows(), A.numRows()),
|
||||
VT(A.numCols(), A.numCols()),
|
||||
conv(false)
|
||||
{
|
||||
construct(A);
|
||||
}
|
||||
const GeneralMatrix &
|
||||
getU() const
|
||||
{
|
||||
return U;
|
||||
}
|
||||
const GeneralMatrix &
|
||||
getVT() const
|
||||
{
|
||||
return VT;
|
||||
}
|
||||
void solve(const GeneralMatrix &B, GeneralMatrix &X) const;
|
||||
void
|
||||
solve(const Vector &b, Vector &x) const
|
||||
{
|
||||
GeneralMatrix xmat(x.base(), x.length(), 1);
|
||||
solve(GeneralMatrix(b.base(), b.length(), 1), xmat);
|
||||
}
|
||||
private:
|
||||
void construct(const GeneralMatrix& A);
|
||||
void construct(const GeneralMatrix &A);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* GENERAL_MATRIX_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -10,52 +10,73 @@
|
|||
#include "SimilarityDecomp.h"
|
||||
#include "SylvesterSolver.h"
|
||||
|
||||
class GeneralSylvester {
|
||||
SylvParams pars;
|
||||
SylvMemoryDriver mem_driver;
|
||||
int order;
|
||||
const SqSylvMatrix a;
|
||||
const SylvMatrix b;
|
||||
const SqSylvMatrix c;
|
||||
SylvMatrix d;
|
||||
bool solved;
|
||||
SchurDecompZero* bdecomp;
|
||||
SimilarityDecomp* cdecomp;
|
||||
SylvesterSolver* sylv;
|
||||
class GeneralSylvester
|
||||
{
|
||||
SylvParams pars;
|
||||
SylvMemoryDriver mem_driver;
|
||||
int order;
|
||||
const SqSylvMatrix a;
|
||||
const SylvMatrix b;
|
||||
const SqSylvMatrix c;
|
||||
SylvMatrix d;
|
||||
bool solved;
|
||||
SchurDecompZero *bdecomp;
|
||||
SimilarityDecomp *cdecomp;
|
||||
SylvesterSolver *sylv;
|
||||
public:
|
||||
/* construct with my copy of d*/
|
||||
GeneralSylvester(int ord, int n, int m, int zero_cols,
|
||||
const double* da, const double* db,
|
||||
const double* dc, const double* dd,
|
||||
const SylvParams& ps);
|
||||
GeneralSylvester(int ord, int n, int m, int zero_cols,
|
||||
const double* da, const double* db,
|
||||
const double* dc, const double* dd,
|
||||
bool alloc_for_check = false);
|
||||
/* construct with provided storage for d */
|
||||
GeneralSylvester(int ord, int n, int m, int zero_cols,
|
||||
const double* da, const double* db,
|
||||
const double* dc, double* dd,
|
||||
bool alloc_for_check = false);
|
||||
GeneralSylvester(int ord, int n, int m, int zero_cols,
|
||||
const double* da, const double* db,
|
||||
const double* dc, double* dd,
|
||||
const SylvParams& ps);
|
||||
virtual ~GeneralSylvester();
|
||||
int getM() const {return c.numRows();}
|
||||
int getN() const {return a.numRows();}
|
||||
const double* getResult() const {return d.base();}
|
||||
const SylvParams& getParams() const {return pars;}
|
||||
SylvParams& getParams() {return pars;}
|
||||
void solve();
|
||||
void check(const double* ds);
|
||||
/* construct with my copy of d*/
|
||||
GeneralSylvester(int ord, int n, int m, int zero_cols,
|
||||
const double *da, const double *db,
|
||||
const double *dc, const double *dd,
|
||||
const SylvParams &ps);
|
||||
GeneralSylvester(int ord, int n, int m, int zero_cols,
|
||||
const double *da, const double *db,
|
||||
const double *dc, const double *dd,
|
||||
bool alloc_for_check = false);
|
||||
/* construct with provided storage for d */
|
||||
GeneralSylvester(int ord, int n, int m, int zero_cols,
|
||||
const double *da, const double *db,
|
||||
const double *dc, double *dd,
|
||||
bool alloc_for_check = false);
|
||||
GeneralSylvester(int ord, int n, int m, int zero_cols,
|
||||
const double *da, const double *db,
|
||||
const double *dc, double *dd,
|
||||
const SylvParams &ps);
|
||||
virtual
|
||||
~GeneralSylvester();
|
||||
int
|
||||
getM() const
|
||||
{
|
||||
return c.numRows();
|
||||
}
|
||||
int
|
||||
getN() const
|
||||
{
|
||||
return a.numRows();
|
||||
}
|
||||
const double *
|
||||
getResult() const
|
||||
{
|
||||
return d.base();
|
||||
}
|
||||
const SylvParams &
|
||||
getParams() const
|
||||
{
|
||||
return pars;
|
||||
}
|
||||
SylvParams &
|
||||
getParams()
|
||||
{
|
||||
return pars;
|
||||
}
|
||||
void solve();
|
||||
void check(const double *ds);
|
||||
private:
|
||||
void init();
|
||||
void init();
|
||||
};
|
||||
|
||||
#endif /* GENERAL_SYLVESTER_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -10,24 +10,30 @@
|
|||
#include "QuasiTriangular.h"
|
||||
#include "SimilarityDecomp.h"
|
||||
|
||||
class IterativeSylvester : public SylvesterSolver {
|
||||
class IterativeSylvester : public SylvesterSolver
|
||||
{
|
||||
public:
|
||||
IterativeSylvester(const QuasiTriangular& k, const QuasiTriangular& f)
|
||||
: SylvesterSolver(k, f) {}
|
||||
IterativeSylvester(const SchurDecompZero& kdecomp, const SchurDecomp& fdecomp)
|
||||
: SylvesterSolver(kdecomp, fdecomp) {}
|
||||
IterativeSylvester(const SchurDecompZero& kdecomp, const SimilarityDecomp& fdecomp)
|
||||
: SylvesterSolver(kdecomp, fdecomp) {}
|
||||
void solve(SylvParams& pars, KronVector& x) const;
|
||||
IterativeSylvester(const QuasiTriangular &k, const QuasiTriangular &f)
|
||||
: SylvesterSolver(k, f)
|
||||
{
|
||||
}
|
||||
IterativeSylvester(const SchurDecompZero &kdecomp, const SchurDecomp &fdecomp)
|
||||
: SylvesterSolver(kdecomp, fdecomp)
|
||||
{
|
||||
}
|
||||
IterativeSylvester(const SchurDecompZero &kdecomp, const SimilarityDecomp &fdecomp)
|
||||
: SylvesterSolver(kdecomp, fdecomp)
|
||||
{
|
||||
}
|
||||
void solve(SylvParams &pars, KronVector &x) const;
|
||||
private:
|
||||
double performFirstStep(KronVector& x) const;
|
||||
static double performStep(const QuasiTriangular& k, const QuasiTriangular& f,
|
||||
KronVector& x);
|
||||
double performFirstStep(KronVector &x) const;
|
||||
static double performStep(const QuasiTriangular &k, const QuasiTriangular &f,
|
||||
KronVector &x);
|
||||
};
|
||||
|
||||
#endif /* ITERATIVE_SYLVESTER_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -8,21 +8,22 @@
|
|||
#include "KronVector.h"
|
||||
#include "QuasiTriangular.h"
|
||||
|
||||
class KronUtils {
|
||||
class KronUtils
|
||||
{
|
||||
public:
|
||||
/* multiplies I_m\otimes..\I_m\otimes T\otimes I_m...I_m\otimes I_n
|
||||
with given b and returns x. T must be (m,m), number of
|
||||
\otimes is b.getDepth(), level is a number of I_m's between T
|
||||
and I_n plus 1. If level=0, then we multiply
|
||||
\I_m\otimes ..\otimes I_m\otimes T, T is (n,n) */
|
||||
static void multAtLevel(int level, const QuasiTriangular& t,
|
||||
KronVector& x);
|
||||
static void multAtLevelTrans(int level, const QuasiTriangular& t,
|
||||
KronVector& x);
|
||||
/* multiplies I_m\otimes..\I_m\otimes T\otimes I_m...I_m\otimes I_n
|
||||
with given b and returns x. T must be (m,m), number of
|
||||
\otimes is b.getDepth(), level is a number of I_m's between T
|
||||
and I_n plus 1. If level=0, then we multiply
|
||||
\I_m\otimes ..\otimes I_m\otimes T, T is (n,n) */
|
||||
static void multAtLevel(int level, const QuasiTriangular &t,
|
||||
KronVector &x);
|
||||
static void multAtLevelTrans(int level, const QuasiTriangular &t,
|
||||
KronVector &x);
|
||||
|
||||
/* multiplies x=(F'\otimes F'\otimes..\otimes K)x */
|
||||
static void multKron(const QuasiTriangular& f, const QuasiTriangular& k,
|
||||
KronVector& x);
|
||||
/* multiplies x=(F'\otimes F'\otimes..\otimes K)x */
|
||||
static void multKron(const QuasiTriangular &f, const QuasiTriangular &k,
|
||||
KronVector &x);
|
||||
};
|
||||
|
||||
#endif /* KRON_UTILS_H */
|
||||
|
|
|
@ -9,44 +9,77 @@
|
|||
|
||||
class ConstKronVector;
|
||||
|
||||
class KronVector : public Vector {
|
||||
class KronVector : public Vector
|
||||
{
|
||||
protected:
|
||||
int m;
|
||||
int n;
|
||||
int depth;
|
||||
int m;
|
||||
int n;
|
||||
int depth;
|
||||
public:
|
||||
KronVector() : Vector((double*)0, 0), m(0), n(0), depth(0) {}
|
||||
KronVector(int mm, int nn, int dp); // new instance
|
||||
KronVector(Vector& v, int mm, int nn, int dp); // conversion
|
||||
KronVector(KronVector&, int i); // picks i-th subvector
|
||||
KronVector(const ConstKronVector& v); // new instance and copy
|
||||
const KronVector& operator=(KronVector& v)
|
||||
{Vector::operator=(v); m=v.m; n=v.n; depth = v.depth; return *this;}
|
||||
const KronVector& operator=(const KronVector& v)
|
||||
{Vector::operator=(v); m=v.m; n=v.n; depth = v.depth; return *this;}
|
||||
const KronVector& operator=(const ConstKronVector& v);
|
||||
const KronVector& operator=(const Vector& v);
|
||||
int getM() const {return m;}
|
||||
int getN() const {return n;}
|
||||
int getDepth() const {return depth;}
|
||||
KronVector() : Vector((double *) 0, 0), m(0), n(0), depth(0)
|
||||
{
|
||||
}
|
||||
KronVector(int mm, int nn, int dp); // new instance
|
||||
KronVector(Vector &v, int mm, int nn, int dp); // conversion
|
||||
KronVector(KronVector &, int i); // picks i-th subvector
|
||||
KronVector(const ConstKronVector &v); // new instance and copy
|
||||
const KronVector &
|
||||
operator=(KronVector &v)
|
||||
{
|
||||
Vector::operator=(v); m = v.m; n = v.n; depth = v.depth; return *this;
|
||||
}
|
||||
const KronVector &
|
||||
operator=(const KronVector &v)
|
||||
{
|
||||
Vector::operator=(v); m = v.m; n = v.n; depth = v.depth; return *this;
|
||||
}
|
||||
const KronVector &operator=(const ConstKronVector &v);
|
||||
const KronVector &operator=(const Vector &v);
|
||||
int
|
||||
getM() const
|
||||
{
|
||||
return m;
|
||||
}
|
||||
int
|
||||
getN() const
|
||||
{
|
||||
return n;
|
||||
}
|
||||
int
|
||||
getDepth() const
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
};
|
||||
|
||||
class ConstKronVector : public ConstVector
|
||||
{
|
||||
protected:
|
||||
int m;
|
||||
int n;
|
||||
int depth;
|
||||
int m;
|
||||
int n;
|
||||
int depth;
|
||||
public:
|
||||
ConstKronVector(const KronVector& v);
|
||||
ConstKronVector(const ConstKronVector& v);
|
||||
ConstKronVector(const Vector& v, int mm, int nn, int dp);
|
||||
ConstKronVector(const ConstVector& v, int mm, int nn, int dp);
|
||||
ConstKronVector(const KronVector& v, int i);
|
||||
ConstKronVector(const ConstKronVector& v, int i);
|
||||
int getM() const {return m;}
|
||||
int getN() const {return n;}
|
||||
int getDepth() const {return depth;}
|
||||
ConstKronVector(const KronVector &v);
|
||||
ConstKronVector(const ConstKronVector &v);
|
||||
ConstKronVector(const Vector &v, int mm, int nn, int dp);
|
||||
ConstKronVector(const ConstVector &v, int mm, int nn, int dp);
|
||||
ConstKronVector(const KronVector &v, int i);
|
||||
ConstKronVector(const ConstKronVector &v, int i);
|
||||
int
|
||||
getM() const
|
||||
{
|
||||
return m;
|
||||
}
|
||||
int
|
||||
getN() const
|
||||
{
|
||||
return n;
|
||||
}
|
||||
int
|
||||
getDepth() const
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
};
|
||||
|
||||
int power(int m, int depth);
|
||||
|
|
|
@ -15,325 +15,521 @@ using namespace std;
|
|||
|
||||
class DiagonalBlock;
|
||||
class Diagonal;
|
||||
class DiagPair {
|
||||
class DiagPair
|
||||
{
|
||||
private:
|
||||
double* a1;
|
||||
double* a2;
|
||||
double *a1;
|
||||
double *a2;
|
||||
public:
|
||||
DiagPair() {}
|
||||
DiagPair(double* aa1, double* aa2) {a1 = aa1; a2 = aa2;}
|
||||
DiagPair(const DiagPair& p) {a1 = p.a1; a2 = p.a2;}
|
||||
const DiagPair& operator=(const DiagPair& p) {a1 = p.a1; a2 = p.a2; return *this;}
|
||||
const DiagPair& operator=(double v) {*a1 = v; *a2 = v; return *this;}
|
||||
const double& operator*() const {return *a1;}
|
||||
/** here we must not define double& operator*(), since it wouldn't
|
||||
rewrite both values, we use operator= for this */
|
||||
friend class Diagonal;
|
||||
friend class DiagonalBlock;
|
||||
DiagPair()
|
||||
{
|
||||
}
|
||||
DiagPair(double *aa1, double *aa2)
|
||||
{
|
||||
a1 = aa1; a2 = aa2;
|
||||
}
|
||||
DiagPair(const DiagPair &p)
|
||||
{
|
||||
a1 = p.a1; a2 = p.a2;
|
||||
}
|
||||
const DiagPair &
|
||||
operator=(const DiagPair &p)
|
||||
{
|
||||
a1 = p.a1; a2 = p.a2; return *this;
|
||||
}
|
||||
const DiagPair &
|
||||
operator=(double v)
|
||||
{
|
||||
*a1 = v; *a2 = v; return *this;
|
||||
}
|
||||
const double &
|
||||
operator*() const
|
||||
{
|
||||
return *a1;
|
||||
}
|
||||
/** here we must not define double& operator*(), since it wouldn't
|
||||
rewrite both values, we use operator= for this */
|
||||
friend class Diagonal;
|
||||
friend class DiagonalBlock;
|
||||
};
|
||||
|
||||
class DiagonalBlock {
|
||||
class DiagonalBlock
|
||||
{
|
||||
private:
|
||||
int jbar;
|
||||
bool real;
|
||||
DiagPair alpha;
|
||||
double* beta1;
|
||||
double* beta2;
|
||||
int jbar;
|
||||
bool real;
|
||||
DiagPair alpha;
|
||||
double *beta1;
|
||||
double *beta2;
|
||||
|
||||
void copy(const DiagonalBlock& b) {
|
||||
jbar = b.jbar;
|
||||
real = b.real;
|
||||
alpha = b.alpha;
|
||||
beta1 = b.beta1;
|
||||
beta2 = b.beta2;
|
||||
}
|
||||
void
|
||||
copy(const DiagonalBlock &b)
|
||||
{
|
||||
jbar = b.jbar;
|
||||
real = b.real;
|
||||
alpha = b.alpha;
|
||||
beta1 = b.beta1;
|
||||
beta2 = b.beta2;
|
||||
}
|
||||
|
||||
public:
|
||||
DiagonalBlock() {}
|
||||
DiagonalBlock(int jb, bool r, double* a1, double* a2,
|
||||
double* b1, double* b2)
|
||||
: alpha(a1, a2)
|
||||
{
|
||||
jbar = jb;
|
||||
real = r;
|
||||
beta1 = b1;
|
||||
beta2 = b2;
|
||||
}
|
||||
// construct complex block
|
||||
DiagonalBlock(int jb, double* a1, double* a2)
|
||||
: alpha(a1, a2)
|
||||
{
|
||||
jbar = jb;
|
||||
real = false;
|
||||
beta1 = a2 - 1;
|
||||
beta2 = a1 + 1;
|
||||
}
|
||||
// construct real block
|
||||
DiagonalBlock(int jb, double* a1)
|
||||
: alpha(a1, a1)
|
||||
{
|
||||
jbar = jb;
|
||||
real = true;
|
||||
beta1 = 0;
|
||||
beta2 = 0;
|
||||
}
|
||||
DiagonalBlock(const DiagonalBlock& b)
|
||||
{copy(b);}
|
||||
const DiagonalBlock& operator=(const DiagonalBlock& b)
|
||||
{copy(b); return *this;}
|
||||
int getIndex() const
|
||||
{return jbar;}
|
||||
bool isReal() const
|
||||
{return real;}
|
||||
const DiagPair& getAlpha() const
|
||||
{return alpha;}
|
||||
DiagPair& getAlpha()
|
||||
{return alpha;}
|
||||
double& getBeta1() const
|
||||
{return *beta1;}
|
||||
double& getBeta2() const
|
||||
{return *beta2;}
|
||||
double getDeterminant() const;
|
||||
double getSBeta() const;
|
||||
double getSize() const;
|
||||
void setReal();
|
||||
// for debugging
|
||||
void checkBlock(const double* d, int d_size);
|
||||
friend class Diagonal;
|
||||
DiagonalBlock()
|
||||
{
|
||||
}
|
||||
DiagonalBlock(int jb, bool r, double *a1, double *a2,
|
||||
double *b1, double *b2)
|
||||
: alpha(a1, a2)
|
||||
{
|
||||
jbar = jb;
|
||||
real = r;
|
||||
beta1 = b1;
|
||||
beta2 = b2;
|
||||
}
|
||||
// construct complex block
|
||||
DiagonalBlock(int jb, double *a1, double *a2)
|
||||
: alpha(a1, a2)
|
||||
{
|
||||
jbar = jb;
|
||||
real = false;
|
||||
beta1 = a2 - 1;
|
||||
beta2 = a1 + 1;
|
||||
}
|
||||
// construct real block
|
||||
DiagonalBlock(int jb, double *a1)
|
||||
: alpha(a1, a1)
|
||||
{
|
||||
jbar = jb;
|
||||
real = true;
|
||||
beta1 = 0;
|
||||
beta2 = 0;
|
||||
}
|
||||
DiagonalBlock(const DiagonalBlock &b)
|
||||
{
|
||||
copy(b);
|
||||
}
|
||||
const DiagonalBlock &
|
||||
operator=(const DiagonalBlock &b)
|
||||
{
|
||||
copy(b); return *this;
|
||||
}
|
||||
int
|
||||
getIndex() const
|
||||
{
|
||||
return jbar;
|
||||
}
|
||||
bool
|
||||
isReal() const
|
||||
{
|
||||
return real;
|
||||
}
|
||||
const DiagPair &
|
||||
getAlpha() const
|
||||
{
|
||||
return alpha;
|
||||
}
|
||||
DiagPair &
|
||||
getAlpha()
|
||||
{
|
||||
return alpha;
|
||||
}
|
||||
double &
|
||||
getBeta1() const
|
||||
{
|
||||
return *beta1;
|
||||
}
|
||||
double &
|
||||
getBeta2() const
|
||||
{
|
||||
return *beta2;
|
||||
}
|
||||
double getDeterminant() const;
|
||||
double getSBeta() const;
|
||||
double getSize() const;
|
||||
void setReal();
|
||||
// for debugging
|
||||
void checkBlock(const double *d, int d_size);
|
||||
friend class Diagonal;
|
||||
};
|
||||
|
||||
template <class _Tdiag, class _Tblock, class _Titer>
|
||||
struct _diag_iter {
|
||||
typedef _diag_iter<_Tdiag, _Tblock, _Titer> _Self;
|
||||
_Tdiag diag;
|
||||
_Titer it;
|
||||
struct _diag_iter
|
||||
{
|
||||
typedef _diag_iter<_Tdiag, _Tblock, _Titer> _Self;
|
||||
_Tdiag diag;
|
||||
_Titer it;
|
||||
public:
|
||||
_diag_iter(_Tdiag d, _Titer iter) : diag(d), it(iter) {}
|
||||
_Tblock operator*() const {return *it;}
|
||||
_Self& operator++() {++it; return *this;}
|
||||
_Self& operator--() {--it; return *this;}
|
||||
bool operator==(const _Self& x) const {return x.it == it;}
|
||||
bool operator!=(const _Self& x) const {return x.it != it;}
|
||||
const _Self& operator=(const _Self& x) {it = x.it; return *this;}
|
||||
_Titer iter() const {return it;}
|
||||
_diag_iter(_Tdiag d, _Titer iter) : diag(d), it(iter)
|
||||
{
|
||||
}
|
||||
_Tblock
|
||||
operator*() const
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
_Self &
|
||||
operator++()
|
||||
{
|
||||
++it; return *this;
|
||||
}
|
||||
_Self &
|
||||
operator--()
|
||||
{
|
||||
--it; return *this;
|
||||
}
|
||||
bool
|
||||
operator==(const _Self &x) const
|
||||
{
|
||||
return x.it == it;
|
||||
}
|
||||
bool
|
||||
operator!=(const _Self &x) const
|
||||
{
|
||||
return x.it != it;
|
||||
}
|
||||
const _Self &
|
||||
operator=(const _Self &x)
|
||||
{
|
||||
it = x.it; return *this;
|
||||
}
|
||||
_Titer
|
||||
iter() const
|
||||
{
|
||||
return it;
|
||||
}
|
||||
};
|
||||
|
||||
class Diagonal {
|
||||
class Diagonal
|
||||
{
|
||||
public:
|
||||
typedef _diag_iter<const Diagonal&, const DiagonalBlock&, list<DiagonalBlock>::const_iterator> const_diag_iter;
|
||||
typedef _diag_iter<Diagonal&, DiagonalBlock&, list<DiagonalBlock>::iterator> diag_iter;
|
||||
typedef _diag_iter<const Diagonal &, const DiagonalBlock &, list<DiagonalBlock>::const_iterator> const_diag_iter;
|
||||
typedef _diag_iter<Diagonal &, DiagonalBlock &, list<DiagonalBlock>::iterator> diag_iter;
|
||||
private:
|
||||
int num_all;
|
||||
list<DiagonalBlock> blocks;
|
||||
int num_real;
|
||||
void copy(const Diagonal&);
|
||||
int num_all;
|
||||
list<DiagonalBlock> blocks;
|
||||
int num_real;
|
||||
void copy(const Diagonal &);
|
||||
public:
|
||||
Diagonal() : num_all(0), num_real(0) {}
|
||||
Diagonal(double* data, int d_size);
|
||||
Diagonal(double* data, const Diagonal& d);
|
||||
Diagonal(const Diagonal& d) {copy(d);}
|
||||
const Diagonal& operator =(const Diagonal& d) {copy(d); return *this;}
|
||||
virtual ~Diagonal() {}
|
||||
Diagonal() : num_all(0), num_real(0)
|
||||
{
|
||||
}
|
||||
Diagonal(double *data, int d_size);
|
||||
Diagonal(double *data, const Diagonal &d);
|
||||
Diagonal(const Diagonal &d)
|
||||
{
|
||||
copy(d);
|
||||
}
|
||||
const Diagonal &
|
||||
operator=(const Diagonal &d)
|
||||
{
|
||||
copy(d); return *this;
|
||||
}
|
||||
virtual ~Diagonal()
|
||||
{
|
||||
}
|
||||
|
||||
int getNumComplex() const {return num_all - num_real;}
|
||||
int getNumReal() const {return num_real;}
|
||||
int getSize() const {return getNumReal() + 2*getNumComplex();}
|
||||
int getNumBlocks() const {return num_all;}
|
||||
void getEigenValues(Vector& eig) const;
|
||||
void swapLogically(diag_iter it);
|
||||
void checkConsistency(diag_iter it);
|
||||
double getAverageSize(diag_iter start, diag_iter end);
|
||||
diag_iter findClosestBlock(diag_iter start, diag_iter end, double a);
|
||||
diag_iter findNextLargerBlock(diag_iter start, diag_iter end, double a);
|
||||
void print() const;
|
||||
int
|
||||
getNumComplex() const
|
||||
{
|
||||
return num_all - num_real;
|
||||
}
|
||||
int
|
||||
getNumReal() const
|
||||
{
|
||||
return num_real;
|
||||
}
|
||||
int
|
||||
getSize() const
|
||||
{
|
||||
return getNumReal() + 2*getNumComplex();
|
||||
}
|
||||
int
|
||||
getNumBlocks() const
|
||||
{
|
||||
return num_all;
|
||||
}
|
||||
void getEigenValues(Vector &eig) const;
|
||||
void swapLogically(diag_iter it);
|
||||
void checkConsistency(diag_iter it);
|
||||
double getAverageSize(diag_iter start, diag_iter end);
|
||||
diag_iter findClosestBlock(diag_iter start, diag_iter end, double a);
|
||||
diag_iter findNextLargerBlock(diag_iter start, diag_iter end, double a);
|
||||
void print() const;
|
||||
|
||||
diag_iter begin()
|
||||
{return diag_iter(*this, blocks.begin());}
|
||||
const_diag_iter begin() const
|
||||
{return const_diag_iter(*this, blocks.begin());}
|
||||
diag_iter end()
|
||||
{return diag_iter(*this, blocks.end());}
|
||||
const_diag_iter end() const
|
||||
{return const_diag_iter(*this, blocks.end());}
|
||||
diag_iter
|
||||
begin()
|
||||
{
|
||||
return diag_iter(*this, blocks.begin());
|
||||
}
|
||||
const_diag_iter
|
||||
begin() const
|
||||
{
|
||||
return const_diag_iter(*this, blocks.begin());
|
||||
}
|
||||
diag_iter
|
||||
end()
|
||||
{
|
||||
return diag_iter(*this, blocks.end());
|
||||
}
|
||||
const_diag_iter
|
||||
end() const
|
||||
{
|
||||
return const_diag_iter(*this, blocks.end());
|
||||
}
|
||||
|
||||
/* redefine pointers as data start at p */
|
||||
void changeBase(double* p);
|
||||
/* redefine pointers as data start at p */
|
||||
void changeBase(double *p);
|
||||
private:
|
||||
static double EPS;
|
||||
static int getNumComplex(const double* data, int d_size);
|
||||
static bool isZero(double p);
|
||||
static double EPS;
|
||||
static int getNumComplex(const double *data, int d_size);
|
||||
static bool isZero(double p);
|
||||
};
|
||||
|
||||
template <class _TRef, class _TPtr>
|
||||
struct _matrix_iter {
|
||||
typedef _matrix_iter<_TRef, _TPtr> _Self;
|
||||
int d_size;
|
||||
bool real;
|
||||
_TPtr ptr;
|
||||
struct _matrix_iter
|
||||
{
|
||||
typedef _matrix_iter<_TRef, _TPtr> _Self;
|
||||
int d_size;
|
||||
bool real;
|
||||
_TPtr ptr;
|
||||
public:
|
||||
_matrix_iter(_TPtr base, int ds, bool r)
|
||||
{ptr = base; d_size = ds; real = r;}
|
||||
virtual ~_matrix_iter() {}
|
||||
const _Self& operator=(const _Self& it)
|
||||
{ptr = it.ptr; d_size = it.d_size; real = it.real; return *this;}
|
||||
bool operator==(const _Self& it) const
|
||||
{return ptr == it.ptr;}
|
||||
bool operator!=(const _Self& it) const
|
||||
{return ptr != it.ptr;}
|
||||
_TRef operator*() const
|
||||
{return *ptr;}
|
||||
_TRef a() const
|
||||
{return *ptr;}
|
||||
virtual _Self& operator++() =0;
|
||||
_matrix_iter(_TPtr base, int ds, bool r)
|
||||
{
|
||||
ptr = base; d_size = ds; real = r;
|
||||
}
|
||||
virtual ~_matrix_iter()
|
||||
{
|
||||
}
|
||||
const _Self &
|
||||
operator=(const _Self &it)
|
||||
{
|
||||
ptr = it.ptr; d_size = it.d_size; real = it.real; return *this;
|
||||
}
|
||||
bool
|
||||
operator==(const _Self &it) const
|
||||
{
|
||||
return ptr == it.ptr;
|
||||
}
|
||||
bool
|
||||
operator!=(const _Self &it) const
|
||||
{
|
||||
return ptr != it.ptr;
|
||||
}
|
||||
_TRef
|
||||
operator*() const
|
||||
{
|
||||
return *ptr;
|
||||
}
|
||||
_TRef
|
||||
a() const
|
||||
{
|
||||
return *ptr;
|
||||
}
|
||||
virtual _Self &operator++() = 0;
|
||||
};
|
||||
|
||||
template <class _TRef, class _TPtr>
|
||||
class _column_iter : public _matrix_iter<_TRef, _TPtr> {
|
||||
typedef _matrix_iter<_TRef, _TPtr> _Tparent;
|
||||
typedef _column_iter<_TRef, _TPtr> _Self;
|
||||
int row;
|
||||
class _column_iter : public _matrix_iter<_TRef, _TPtr>
|
||||
{
|
||||
typedef _matrix_iter<_TRef, _TPtr> _Tparent;
|
||||
typedef _column_iter<_TRef, _TPtr> _Self;
|
||||
int row;
|
||||
public:
|
||||
_column_iter(_TPtr base, int ds, bool r, int rw)
|
||||
: _matrix_iter<_TRef, _TPtr>(base, ds, r), row(rw) {};
|
||||
_Self& operator++()
|
||||
{_Tparent::ptr++; row++; return *this;}
|
||||
_TRef b() const
|
||||
{
|
||||
if (_Tparent::real) {
|
||||
return *(_Tparent::ptr);
|
||||
} else {
|
||||
return *(_Tparent::ptr+_Tparent::d_size);
|
||||
}
|
||||
}
|
||||
int getRow() const {return row;}
|
||||
_column_iter(_TPtr base, int ds, bool r, int rw)
|
||||
: _matrix_iter<_TRef, _TPtr>(base, ds, r), row(rw)
|
||||
{
|
||||
};
|
||||
_Self &
|
||||
operator++()
|
||||
{
|
||||
_Tparent::ptr++; row++; return *this;
|
||||
}
|
||||
_TRef
|
||||
b() const
|
||||
{
|
||||
if (_Tparent::real)
|
||||
{
|
||||
return *(_Tparent::ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
return *(_Tparent::ptr+_Tparent::d_size);
|
||||
}
|
||||
}
|
||||
int
|
||||
getRow() const
|
||||
{
|
||||
return row;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _TRef, class _TPtr>
|
||||
class _row_iter : public _matrix_iter<_TRef, _TPtr> {
|
||||
typedef _matrix_iter<_TRef, _TPtr> _Tparent;
|
||||
typedef _row_iter<_TRef, _TPtr> _Self;
|
||||
int col;
|
||||
class _row_iter : public _matrix_iter<_TRef, _TPtr>
|
||||
{
|
||||
typedef _matrix_iter<_TRef, _TPtr> _Tparent;
|
||||
typedef _row_iter<_TRef, _TPtr> _Self;
|
||||
int col;
|
||||
public:
|
||||
_row_iter(_TPtr base, int ds, bool r, int cl)
|
||||
: _matrix_iter<_TRef, _TPtr>(base, ds, r), col(cl) {};
|
||||
_Self& operator++()
|
||||
{_Tparent::ptr += _Tparent::d_size; col++; return *this;}
|
||||
virtual _TRef b() const
|
||||
{
|
||||
if (_Tparent::real) {
|
||||
return *(_Tparent::ptr);
|
||||
}else {
|
||||
return *(_Tparent::ptr+1);
|
||||
}
|
||||
}
|
||||
int getCol() const {return col;}
|
||||
_row_iter(_TPtr base, int ds, bool r, int cl)
|
||||
: _matrix_iter<_TRef, _TPtr>(base, ds, r), col(cl)
|
||||
{
|
||||
};
|
||||
_Self &
|
||||
operator++()
|
||||
{
|
||||
_Tparent::ptr += _Tparent::d_size; col++; return *this;
|
||||
}
|
||||
virtual _TRef
|
||||
b() const
|
||||
{
|
||||
if (_Tparent::real)
|
||||
{
|
||||
return *(_Tparent::ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
return *(_Tparent::ptr+1);
|
||||
}
|
||||
}
|
||||
int
|
||||
getCol() const
|
||||
{
|
||||
return col;
|
||||
}
|
||||
};
|
||||
|
||||
class SchurDecomp;
|
||||
class SchurDecompZero;
|
||||
|
||||
class QuasiTriangular : public SqSylvMatrix {
|
||||
class QuasiTriangular : public SqSylvMatrix
|
||||
{
|
||||
public:
|
||||
typedef _column_iter<const double&, const double*> const_col_iter;
|
||||
typedef _column_iter<double&, double*> col_iter;
|
||||
typedef _row_iter<const double&, const double*> const_row_iter;
|
||||
typedef _row_iter<double&, double*> row_iter;
|
||||
typedef Diagonal::const_diag_iter const_diag_iter;
|
||||
typedef Diagonal::diag_iter diag_iter;
|
||||
typedef _column_iter<const double &, const double *> const_col_iter;
|
||||
typedef _column_iter<double &, double *> col_iter;
|
||||
typedef _row_iter<const double &, const double *> const_row_iter;
|
||||
typedef _row_iter<double &, double *> row_iter;
|
||||
typedef Diagonal::const_diag_iter const_diag_iter;
|
||||
typedef Diagonal::diag_iter diag_iter;
|
||||
protected:
|
||||
Diagonal diagonal;
|
||||
Diagonal diagonal;
|
||||
public:
|
||||
QuasiTriangular(const double* d, int d_size);
|
||||
QuasiTriangular(double r, const QuasiTriangular& t);
|
||||
QuasiTriangular(double r, const QuasiTriangular& t,
|
||||
double rr, const QuasiTriangular& tt);
|
||||
QuasiTriangular(int p, const QuasiTriangular& t);
|
||||
QuasiTriangular(const SchurDecomp& decomp);
|
||||
QuasiTriangular(const SchurDecompZero& decomp);
|
||||
QuasiTriangular(const QuasiTriangular& t);
|
||||
virtual ~QuasiTriangular();
|
||||
const Diagonal& getDiagonal() const {return diagonal;}
|
||||
int getNumOffdiagonal() const;
|
||||
void swapDiagLogically(diag_iter it);
|
||||
void checkDiagConsistency(diag_iter it);
|
||||
double getAverageDiagSize(diag_iter start, diag_iter end);
|
||||
diag_iter findClosestDiagBlock(diag_iter start, diag_iter end, double a);
|
||||
diag_iter findNextLargerBlock(diag_iter start, diag_iter end, double a);
|
||||
QuasiTriangular(const double *d, int d_size);
|
||||
QuasiTriangular(double r, const QuasiTriangular &t);
|
||||
QuasiTriangular(double r, const QuasiTriangular &t,
|
||||
double rr, const QuasiTriangular &tt);
|
||||
QuasiTriangular(int p, const QuasiTriangular &t);
|
||||
QuasiTriangular(const SchurDecomp &decomp);
|
||||
QuasiTriangular(const SchurDecompZero &decomp);
|
||||
QuasiTriangular(const QuasiTriangular &t);
|
||||
virtual
|
||||
~QuasiTriangular();
|
||||
const Diagonal &
|
||||
getDiagonal() const
|
||||
{
|
||||
return diagonal;
|
||||
}
|
||||
int getNumOffdiagonal() const;
|
||||
void swapDiagLogically(diag_iter it);
|
||||
void checkDiagConsistency(diag_iter it);
|
||||
double getAverageDiagSize(diag_iter start, diag_iter end);
|
||||
diag_iter findClosestDiagBlock(diag_iter start, diag_iter end, double a);
|
||||
diag_iter findNextLargerBlock(diag_iter start, diag_iter end, double a);
|
||||
|
||||
/* (I+T)y = x, y-->x */
|
||||
virtual void solvePre(Vector &x, double &eig_min);
|
||||
/* (I+T')y = x, y-->x */
|
||||
virtual void solvePreTrans(Vector &x, double &eig_min);
|
||||
/* (I+T)x = b */
|
||||
virtual void solve(Vector &x, const ConstVector &b, double &eig_min);
|
||||
/* (I+T')x = b */
|
||||
virtual void solveTrans(Vector &x, const ConstVector &b, double &eig_min);
|
||||
/* x = Tb */
|
||||
virtual void multVec(Vector &x, const ConstVector &b) const;
|
||||
/* x = T'b */
|
||||
virtual void multVecTrans(Vector &x, const ConstVector &b) const;
|
||||
/* x = x + Tb */
|
||||
virtual void multaVec(Vector &x, const ConstVector &b) const;
|
||||
/* x = x + T'b */
|
||||
virtual void multaVecTrans(Vector &x, const ConstVector &b) const;
|
||||
/* x = (T\otimes I)x */
|
||||
virtual void multKron(KronVector &x) const;
|
||||
/* x = (T'\otimes I)x */
|
||||
virtual void multKronTrans(KronVector &x) const;
|
||||
/* A = T*A */
|
||||
virtual void multLeftOther(GeneralMatrix &a) const;
|
||||
/* A = T'*A */
|
||||
virtual void multLeftOtherTrans(GeneralMatrix &a) const;
|
||||
|
||||
/* (I+T)y = x, y-->x */
|
||||
virtual void solvePre(Vector& x, double& eig_min);
|
||||
/* (I+T')y = x, y-->x */
|
||||
virtual void solvePreTrans(Vector& x, double& eig_min);
|
||||
/* (I+T)x = b */
|
||||
virtual void solve(Vector& x, const ConstVector& b, double& eig_min);
|
||||
/* (I+T')x = b */
|
||||
virtual void solveTrans(Vector& x, const ConstVector& b, double& eig_min);
|
||||
/* x = Tb */
|
||||
virtual void multVec(Vector& x, const ConstVector& b) const;
|
||||
/* x = T'b */
|
||||
virtual void multVecTrans(Vector& x, const ConstVector& b) const;
|
||||
/* x = x + Tb */
|
||||
virtual void multaVec(Vector& x, const ConstVector& b) const;
|
||||
/* x = x + T'b */
|
||||
virtual void multaVecTrans(Vector& x, const ConstVector& b) const;
|
||||
/* x = (T\otimes I)x */
|
||||
virtual void multKron(KronVector& x) const;
|
||||
/* x = (T'\otimes I)x */
|
||||
virtual void multKronTrans(KronVector& x) const;
|
||||
/* A = T*A */
|
||||
virtual void multLeftOther(GeneralMatrix& a) const;
|
||||
/* A = T'*A */
|
||||
virtual void multLeftOtherTrans(GeneralMatrix& a) const;
|
||||
const_diag_iter
|
||||
diag_begin() const
|
||||
{
|
||||
return diagonal.begin();
|
||||
}
|
||||
diag_iter
|
||||
diag_begin()
|
||||
{
|
||||
return diagonal.begin();
|
||||
}
|
||||
const_diag_iter
|
||||
diag_end() const
|
||||
{
|
||||
return diagonal.end();
|
||||
}
|
||||
diag_iter
|
||||
diag_end()
|
||||
{
|
||||
return diagonal.end();
|
||||
}
|
||||
|
||||
const_diag_iter diag_begin() const
|
||||
{return diagonal.begin();}
|
||||
diag_iter diag_begin()
|
||||
{return diagonal.begin();}
|
||||
const_diag_iter diag_end() const
|
||||
{return diagonal.end();}
|
||||
diag_iter diag_end()
|
||||
{return diagonal.end();}
|
||||
/* iterators for off diagonal elements */
|
||||
virtual const_col_iter col_begin(const DiagonalBlock &b) const;
|
||||
virtual col_iter col_begin(const DiagonalBlock &b);
|
||||
virtual const_row_iter row_begin(const DiagonalBlock &b) const;
|
||||
virtual row_iter row_begin(const DiagonalBlock &b);
|
||||
virtual const_col_iter col_end(const DiagonalBlock &b) const;
|
||||
virtual col_iter col_end(const DiagonalBlock &b);
|
||||
virtual const_row_iter row_end(const DiagonalBlock &b) const;
|
||||
virtual row_iter row_end(const DiagonalBlock &b);
|
||||
|
||||
/* iterators for off diagonal elements */
|
||||
virtual const_col_iter col_begin(const DiagonalBlock& b) const;
|
||||
virtual col_iter col_begin(const DiagonalBlock& b);
|
||||
virtual const_row_iter row_begin(const DiagonalBlock& b) const;
|
||||
virtual row_iter row_begin(const DiagonalBlock& b);
|
||||
virtual const_col_iter col_end(const DiagonalBlock& b) const;
|
||||
virtual col_iter col_end(const DiagonalBlock& b);
|
||||
virtual const_row_iter row_end(const DiagonalBlock& b) const;
|
||||
virtual row_iter row_end(const DiagonalBlock& b);
|
||||
|
||||
/* clone */
|
||||
virtual QuasiTriangular* clone() const
|
||||
{return new QuasiTriangular(*this);}
|
||||
virtual QuasiTriangular* clone(int p, const QuasiTriangular& t) const
|
||||
{return new QuasiTriangular(p, t);}
|
||||
virtual QuasiTriangular* clone(double r) const
|
||||
{return new QuasiTriangular(r, *this);}
|
||||
virtual QuasiTriangular* clone(double r, double rr, const QuasiTriangular& tt) const
|
||||
{return new QuasiTriangular(r, *this, rr, tt);}
|
||||
/* clone */
|
||||
virtual QuasiTriangular *
|
||||
clone() const
|
||||
{
|
||||
return new QuasiTriangular(*this);
|
||||
}
|
||||
virtual QuasiTriangular *
|
||||
clone(int p, const QuasiTriangular &t) const
|
||||
{
|
||||
return new QuasiTriangular(p, t);
|
||||
}
|
||||
virtual QuasiTriangular *
|
||||
clone(double r) const
|
||||
{
|
||||
return new QuasiTriangular(r, *this);
|
||||
}
|
||||
virtual QuasiTriangular *
|
||||
clone(double r, double rr, const QuasiTriangular &tt) const
|
||||
{
|
||||
return new QuasiTriangular(r, *this, rr, tt);
|
||||
}
|
||||
protected:
|
||||
void setMatrix(double r, const QuasiTriangular& t);
|
||||
void addMatrix(double r, const QuasiTriangular& t);
|
||||
void setMatrix(double r, const QuasiTriangular &t);
|
||||
void addMatrix(double r, const QuasiTriangular &t);
|
||||
private:
|
||||
void addUnit();
|
||||
/* x = x + (T\otimes I)b */
|
||||
void multaKron(KronVector& x, const ConstKronVector& b) const;
|
||||
/* x = x + (T'\otimes I)b */
|
||||
void multaKronTrans(KronVector& x, const ConstKronVector& b) const;
|
||||
/* implementation via iterators, useful for large matrices */
|
||||
void setMatrixViaIter(double r, const QuasiTriangular& t);
|
||||
void addMatrixViaIter(double r, const QuasiTriangular& t);
|
||||
/* hide noneffective implementations of parents */
|
||||
void multsVec(Vector& x, const ConstVector& d) const;
|
||||
void multsVecTrans(Vector& x, const ConstVector& d) const;
|
||||
void addUnit();
|
||||
/* x = x + (T\otimes I)b */
|
||||
void multaKron(KronVector &x, const ConstKronVector &b) const;
|
||||
/* x = x + (T'\otimes I)b */
|
||||
void multaKronTrans(KronVector &x, const ConstKronVector &b) const;
|
||||
/* implementation via iterators, useful for large matrices */
|
||||
void setMatrixViaIter(double r, const QuasiTriangular &t);
|
||||
void addMatrixViaIter(double r, const QuasiTriangular &t);
|
||||
/* hide noneffective implementations of parents */
|
||||
void multsVec(Vector &x, const ConstVector &d) const;
|
||||
void multsVecTrans(Vector &x, const ConstVector &d) const;
|
||||
};
|
||||
|
||||
#endif /* QUASI_TRIANGULAR_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -8,37 +8,50 @@
|
|||
#include "QuasiTriangular.h"
|
||||
#include "GeneralMatrix.h"
|
||||
|
||||
class QuasiTriangularZero : public QuasiTriangular {
|
||||
int nz; // number of zero columns
|
||||
GeneralMatrix ru; // data in right upper part (nz,d_size)
|
||||
class QuasiTriangularZero : public QuasiTriangular
|
||||
{
|
||||
int nz; // number of zero columns
|
||||
GeneralMatrix ru; // data in right upper part (nz,d_size)
|
||||
public:
|
||||
QuasiTriangularZero(int num_zeros, const double* d, int d_size);
|
||||
QuasiTriangularZero(double r, const QuasiTriangularZero& t);
|
||||
QuasiTriangularZero(double r, const QuasiTriangularZero& t,
|
||||
double rr, const QuasiTriangularZero& tt);
|
||||
QuasiTriangularZero(int p, const QuasiTriangularZero& t);
|
||||
QuasiTriangularZero(const QuasiTriangular& t);
|
||||
QuasiTriangularZero(const SchurDecompZero& decomp);
|
||||
~QuasiTriangularZero();
|
||||
void solvePre(Vector& x, double& eig_min);
|
||||
void solvePreTrans(Vector& x, double& eig_min);
|
||||
void multVec(Vector& x, const ConstVector& b) const;
|
||||
void multVecTrans(Vector& x, const ConstVector& b) const;
|
||||
void multaVec(Vector& x, const ConstVector& b) const;
|
||||
void multaVecTrans(Vector& x, const ConstVector& b) const;
|
||||
void multKron(KronVector& x) const;
|
||||
void multKronTrans(KronVector& x) const;
|
||||
void multLeftOther(GeneralMatrix& a) const;
|
||||
/* clone */
|
||||
virtual QuasiTriangular* clone() const
|
||||
{return new QuasiTriangularZero(*this);}
|
||||
virtual QuasiTriangular* clone(int p, const QuasiTriangular& t) const
|
||||
{return new QuasiTriangularZero(p, (const QuasiTriangularZero&)t);}
|
||||
virtual QuasiTriangular* clone(double r) const
|
||||
{return new QuasiTriangularZero(r, *this);}
|
||||
virtual QuasiTriangular* clone(double r, double rr, const QuasiTriangular& tt) const
|
||||
{return new QuasiTriangularZero(r, *this, rr, (const QuasiTriangularZero&)tt);}
|
||||
void print() const;
|
||||
QuasiTriangularZero(int num_zeros, const double *d, int d_size);
|
||||
QuasiTriangularZero(double r, const QuasiTriangularZero &t);
|
||||
QuasiTriangularZero(double r, const QuasiTriangularZero &t,
|
||||
double rr, const QuasiTriangularZero &tt);
|
||||
QuasiTriangularZero(int p, const QuasiTriangularZero &t);
|
||||
QuasiTriangularZero(const QuasiTriangular &t);
|
||||
QuasiTriangularZero(const SchurDecompZero &decomp);
|
||||
~QuasiTriangularZero();
|
||||
void solvePre(Vector &x, double &eig_min);
|
||||
void solvePreTrans(Vector &x, double &eig_min);
|
||||
void multVec(Vector &x, const ConstVector &b) const;
|
||||
void multVecTrans(Vector &x, const ConstVector &b) const;
|
||||
void multaVec(Vector &x, const ConstVector &b) const;
|
||||
void multaVecTrans(Vector &x, const ConstVector &b) const;
|
||||
void multKron(KronVector &x) const;
|
||||
void multKronTrans(KronVector &x) const;
|
||||
void multLeftOther(GeneralMatrix &a) const;
|
||||
/* clone */
|
||||
virtual QuasiTriangular *
|
||||
clone() const
|
||||
{
|
||||
return new QuasiTriangularZero(*this);
|
||||
}
|
||||
virtual QuasiTriangular *
|
||||
clone(int p, const QuasiTriangular &t) const
|
||||
{
|
||||
return new QuasiTriangularZero(p, (const QuasiTriangularZero &) t);
|
||||
}
|
||||
virtual QuasiTriangular *
|
||||
clone(double r) const
|
||||
{
|
||||
return new QuasiTriangularZero(r, *this);
|
||||
}
|
||||
virtual QuasiTriangular *
|
||||
clone(double r, double rr, const QuasiTriangular &tt) const
|
||||
{
|
||||
return new QuasiTriangularZero(r, *this, rr, (const QuasiTriangularZero &) tt);
|
||||
}
|
||||
void print() const;
|
||||
};
|
||||
|
||||
#endif /* QUASI_TRIANGULAR_ZERO_H */
|
||||
|
|
|
@ -9,35 +9,61 @@
|
|||
#include "QuasiTriangular.h"
|
||||
|
||||
class QuasiTriangular;
|
||||
class SchurDecomp {
|
||||
bool q_destroy;
|
||||
SqSylvMatrix* q;
|
||||
bool t_destroy;
|
||||
QuasiTriangular* t;
|
||||
class SchurDecomp
|
||||
{
|
||||
bool q_destroy;
|
||||
SqSylvMatrix *q;
|
||||
bool t_destroy;
|
||||
QuasiTriangular *t;
|
||||
public:
|
||||
SchurDecomp(const SqSylvMatrix& m);
|
||||
SchurDecomp(const QuasiTriangular& tr);
|
||||
SchurDecomp(QuasiTriangular& tr);
|
||||
const SqSylvMatrix& getQ() const {return *q;}
|
||||
const QuasiTriangular& getT() const {return *t;}
|
||||
SqSylvMatrix& getQ() {return *q;}
|
||||
QuasiTriangular& getT() {return *t;}
|
||||
virtual int getDim() const;
|
||||
virtual ~SchurDecomp();
|
||||
SchurDecomp(const SqSylvMatrix &m);
|
||||
SchurDecomp(const QuasiTriangular &tr);
|
||||
SchurDecomp(QuasiTriangular &tr);
|
||||
const SqSylvMatrix &
|
||||
getQ() const
|
||||
{
|
||||
return *q;
|
||||
}
|
||||
const QuasiTriangular &
|
||||
getT() const
|
||||
{
|
||||
return *t;
|
||||
}
|
||||
SqSylvMatrix &
|
||||
getQ()
|
||||
{
|
||||
return *q;
|
||||
}
|
||||
QuasiTriangular &
|
||||
getT()
|
||||
{
|
||||
return *t;
|
||||
}
|
||||
virtual int getDim() const;
|
||||
virtual
|
||||
~SchurDecomp();
|
||||
};
|
||||
|
||||
class SchurDecompZero : public SchurDecomp {
|
||||
GeneralMatrix ru; /* right upper matrix */
|
||||
class SchurDecompZero : public SchurDecomp
|
||||
{
|
||||
GeneralMatrix ru; /* right upper matrix */
|
||||
public:
|
||||
SchurDecompZero(const GeneralMatrix& m);
|
||||
const GeneralMatrix& getRU() const {return ru;}
|
||||
int getDim() const;
|
||||
int getZeroCols() const {return ru.numRows();}
|
||||
SchurDecompZero(const GeneralMatrix &m);
|
||||
const GeneralMatrix &
|
||||
getRU() const
|
||||
{
|
||||
return ru;
|
||||
}
|
||||
int getDim() const;
|
||||
int
|
||||
getZeroCols() const
|
||||
{
|
||||
return ru.numRows();
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* SCHUR_DECOMP_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -10,22 +10,27 @@
|
|||
#include "SchurDecomp.h"
|
||||
#include "QuasiTriangular.h"
|
||||
|
||||
class SchurDecompEig : public SchurDecomp {
|
||||
class SchurDecompEig : public SchurDecomp
|
||||
{
|
||||
public:
|
||||
typedef QuasiTriangular::diag_iter diag_iter;
|
||||
SchurDecompEig(const SqSylvMatrix& m) : SchurDecomp(m) {}
|
||||
SchurDecompEig(const QuasiTriangular& tr) : SchurDecomp(tr) {};
|
||||
SchurDecompEig(QuasiTriangular& tr) : SchurDecomp(tr) {}
|
||||
diag_iter bubbleEigen(diag_iter from, diag_iter to);
|
||||
void orderEigen();
|
||||
typedef QuasiTriangular::diag_iter diag_iter;
|
||||
SchurDecompEig(const SqSylvMatrix &m) : SchurDecomp(m)
|
||||
{
|
||||
}
|
||||
SchurDecompEig(const QuasiTriangular &tr) : SchurDecomp(tr)
|
||||
{
|
||||
};
|
||||
SchurDecompEig(QuasiTriangular &tr) : SchurDecomp(tr)
|
||||
{
|
||||
}
|
||||
diag_iter bubbleEigen(diag_iter from, diag_iter to);
|
||||
void orderEigen();
|
||||
protected:
|
||||
bool tryToSwap(diag_iter& it, diag_iter& itadd);
|
||||
bool tryToSwap(diag_iter &it, diag_iter &itadd);
|
||||
};
|
||||
|
||||
#endif /* SCHUR_DECOMP_EIG_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
||||
|
|
|
@ -9,33 +9,43 @@
|
|||
#include "BlockDiagonal.h"
|
||||
#include "SylvParams.h"
|
||||
|
||||
class SimilarityDecomp {
|
||||
SqSylvMatrix* q;
|
||||
BlockDiagonal* b;
|
||||
SqSylvMatrix* invq;
|
||||
typedef BlockDiagonal::diag_iter diag_iter;
|
||||
class SimilarityDecomp
|
||||
{
|
||||
SqSylvMatrix *q;
|
||||
BlockDiagonal *b;
|
||||
SqSylvMatrix *invq;
|
||||
typedef BlockDiagonal::diag_iter diag_iter;
|
||||
public:
|
||||
SimilarityDecomp(const double* d, int d_size, double log10norm = 3.0);
|
||||
virtual ~SimilarityDecomp();
|
||||
const SqSylvMatrix& getQ() const
|
||||
{return *q;}
|
||||
const SqSylvMatrix& getInvQ() const
|
||||
{return *invq;}
|
||||
const BlockDiagonal& getB() const
|
||||
{return *b;}
|
||||
void check(SylvParams& pars, const GeneralMatrix& m) const;
|
||||
void infoToPars(SylvParams& pars) const;
|
||||
SimilarityDecomp(const double *d, int d_size, double log10norm = 3.0);
|
||||
virtual
|
||||
~SimilarityDecomp();
|
||||
const SqSylvMatrix &
|
||||
getQ() const
|
||||
{
|
||||
return *q;
|
||||
}
|
||||
const SqSylvMatrix &
|
||||
getInvQ() const
|
||||
{
|
||||
return *invq;
|
||||
}
|
||||
const BlockDiagonal &
|
||||
getB() const
|
||||
{
|
||||
return *b;
|
||||
}
|
||||
void check(SylvParams &pars, const GeneralMatrix &m) const;
|
||||
void infoToPars(SylvParams &pars) const;
|
||||
protected:
|
||||
void getXDim(diag_iter start, diag_iter end, int& rows, int& cols) const;
|
||||
bool solveX(diag_iter start, diag_iter end, GeneralMatrix& X, double norm) const;
|
||||
void updateTransform(diag_iter start, diag_iter end, GeneralMatrix& X);
|
||||
void bringGuiltyBlock(diag_iter start, diag_iter& end);
|
||||
void diagonalize(double norm);
|
||||
void getXDim(diag_iter start, diag_iter end, int &rows, int &cols) const;
|
||||
bool solveX(diag_iter start, diag_iter end, GeneralMatrix &X, double norm) const;
|
||||
void updateTransform(diag_iter start, diag_iter end, GeneralMatrix &X);
|
||||
void bringGuiltyBlock(diag_iter start, diag_iter &end);
|
||||
void diagonalize(double norm);
|
||||
};
|
||||
|
||||
#endif /* SIMILARITY_DECOMP_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -7,33 +7,34 @@
|
|||
|
||||
#include "SylvMemory.h"
|
||||
|
||||
|
||||
class SylvException : public MallocAllocator {
|
||||
class SylvException : public MallocAllocator
|
||||
{
|
||||
protected:
|
||||
char file[50];
|
||||
int line;
|
||||
const SylvException* source;
|
||||
char file[50];
|
||||
int line;
|
||||
const SylvException *source;
|
||||
public:
|
||||
SylvException(const char* f, int l, const SylvException* s);
|
||||
virtual ~SylvException();
|
||||
virtual int printMessage(char* str, int maxlen) const;
|
||||
void printMessage() const;
|
||||
SylvException(const char *f, int l, const SylvException *s);
|
||||
virtual
|
||||
~SylvException();
|
||||
virtual int printMessage(char *str, int maxlen) const;
|
||||
void printMessage() const;
|
||||
};
|
||||
|
||||
class SylvExceptionMessage : public SylvException {
|
||||
char message[500];
|
||||
class SylvExceptionMessage : public SylvException
|
||||
{
|
||||
char message[500];
|
||||
public:
|
||||
SylvExceptionMessage(const char* f, int l, const char* mes);
|
||||
virtual int printMessage(char* str, int maxlen) const;
|
||||
SylvExceptionMessage(const char *f, int l, const char *mes);
|
||||
virtual int printMessage(char *str, int maxlen) const;
|
||||
};
|
||||
|
||||
// define macros:
|
||||
#define SYLV_EXCEPTION(exc) (SylvException(__FILE__, __LINE__, exc))
|
||||
#define SYLV_MES_EXCEPTION(mes) (SylvExceptionMessage(__FILE__, __LINE__, mes))
|
||||
#define SYLV_MES_EXCEPTION(mes) (SylvExceptionMessage(__FILE__, __LINE__, mes))
|
||||
|
||||
#endif /* SYLV_EXCEPTION_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -10,72 +10,100 @@
|
|||
|
||||
class SqSylvMatrix;
|
||||
|
||||
class SylvMatrix : public GeneralMatrix {
|
||||
class SylvMatrix : public GeneralMatrix
|
||||
{
|
||||
public:
|
||||
SylvMatrix(int m, int n)
|
||||
: GeneralMatrix(m,n) {}
|
||||
SylvMatrix(const double* d, int m, int n)
|
||||
: GeneralMatrix(d, m, n) {}
|
||||
SylvMatrix(double* d, int m, int n)
|
||||
: GeneralMatrix(d, m, n) {}
|
||||
SylvMatrix(const GeneralMatrix& m)
|
||||
: GeneralMatrix(m) {}
|
||||
SylvMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols)
|
||||
: GeneralMatrix(m, i, j, nrows, ncols) {}
|
||||
SylvMatrix(GeneralMatrix& m, int i, int j, int nrows, int ncols)
|
||||
: GeneralMatrix(m, i, j, nrows, ncols) {}
|
||||
SylvMatrix(const GeneralMatrix& a, const GeneralMatrix& b)
|
||||
: GeneralMatrix(a, b) {}
|
||||
SylvMatrix(int m, int n)
|
||||
: GeneralMatrix(m, n)
|
||||
{
|
||||
}
|
||||
SylvMatrix(const double *d, int m, int n)
|
||||
: GeneralMatrix(d, m, n)
|
||||
{
|
||||
}
|
||||
SylvMatrix(double *d, int m, int n)
|
||||
: GeneralMatrix(d, m, n)
|
||||
{
|
||||
}
|
||||
SylvMatrix(const GeneralMatrix &m)
|
||||
: GeneralMatrix(m)
|
||||
{
|
||||
}
|
||||
SylvMatrix(const GeneralMatrix &m, int i, int j, int nrows, int ncols)
|
||||
: GeneralMatrix(m, i, j, nrows, ncols)
|
||||
{
|
||||
}
|
||||
SylvMatrix(GeneralMatrix &m, int i, int j, int nrows, int ncols)
|
||||
: GeneralMatrix(m, i, j, nrows, ncols)
|
||||
{
|
||||
}
|
||||
SylvMatrix(const GeneralMatrix &a, const GeneralMatrix &b)
|
||||
: GeneralMatrix(a, b)
|
||||
{
|
||||
}
|
||||
|
||||
/* this = |I 0|* this
|
||||
|0 m| */
|
||||
void multLeftI(const SqSylvMatrix& m);
|
||||
/* this = |I 0|* this
|
||||
|0 m'| */
|
||||
void multLeftITrans(const SqSylvMatrix& m);
|
||||
/* this = |0 a|*b, so that |0 a| is square */
|
||||
void multLeft(int zero_cols, const GeneralMatrix& a, const GeneralMatrix& b);
|
||||
/* this = this * (m\otimes m..\otimes m) */
|
||||
void multRightKron(const SqSylvMatrix& m, int order);
|
||||
/* this = this * (m'\otimes m'..\otimes m') */
|
||||
void multRightKronTrans(const SqSylvMatrix& m, int order);
|
||||
/* this = P*this, x = P*x, where P is gauss transformation setting
|
||||
* a given element to zero */
|
||||
void eliminateLeft(int row, int col, Vector& x);
|
||||
/* this = this*P, x = P'*x, where P is gauss transformation setting
|
||||
* a given element to zero */
|
||||
void eliminateRight(int row, int col, Vector& x);
|
||||
/* this = |I 0|* this
|
||||
|0 m| */
|
||||
void multLeftI(const SqSylvMatrix &m);
|
||||
/* this = |I 0|* this
|
||||
|0 m'| */
|
||||
void multLeftITrans(const SqSylvMatrix &m);
|
||||
/* this = |0 a|*b, so that |0 a| is square */
|
||||
void multLeft(int zero_cols, const GeneralMatrix &a, const GeneralMatrix &b);
|
||||
/* this = this * (m\otimes m..\otimes m) */
|
||||
void multRightKron(const SqSylvMatrix &m, int order);
|
||||
/* this = this * (m'\otimes m'..\otimes m') */
|
||||
void multRightKronTrans(const SqSylvMatrix &m, int order);
|
||||
/* this = P*this, x = P*x, where P is gauss transformation setting
|
||||
* a given element to zero */
|
||||
void eliminateLeft(int row, int col, Vector &x);
|
||||
/* this = this*P, x = P'*x, where P is gauss transformation setting
|
||||
* a given element to zero */
|
||||
void eliminateRight(int row, int col, Vector &x);
|
||||
};
|
||||
|
||||
|
||||
class SqSylvMatrix : public SylvMatrix {
|
||||
class SqSylvMatrix : public SylvMatrix
|
||||
{
|
||||
public:
|
||||
SqSylvMatrix(int m) : SylvMatrix(m, m) {}
|
||||
SqSylvMatrix(const double* d, int m) : SylvMatrix(d, m, m) {}
|
||||
SqSylvMatrix(double* d, int m) : SylvMatrix(d, m, m) {}
|
||||
SqSylvMatrix(const SqSylvMatrix& m) : SylvMatrix(m) {}
|
||||
SqSylvMatrix(const GeneralMatrix& m, int i, int j, int nrows)
|
||||
: SylvMatrix(m, i, j, nrows, nrows) {}
|
||||
SqSylvMatrix(GeneralMatrix& m, int i, int j, int nrows)
|
||||
: SylvMatrix(m, i, j, nrows, nrows) {}
|
||||
SqSylvMatrix(const GeneralMatrix& a, const GeneralMatrix& b);
|
||||
const SqSylvMatrix& operator=(const SqSylvMatrix& m)
|
||||
{GeneralMatrix::operator=(m); return *this;}
|
||||
/* x = (this \otimes this..\otimes this)*d */
|
||||
void multVecKron(KronVector& x, const KronVector& d) const;
|
||||
/* x = (this' \otimes this'..\otimes this')*d */
|
||||
void multVecKronTrans(KronVector& x, const KronVector& d) const;
|
||||
/* a = inv(this)*a, b=inv(this)*b */
|
||||
void multInvLeft2(GeneralMatrix& a, GeneralMatrix& b,
|
||||
double& rcond1, double& rcondinf) const;
|
||||
/* this = I */
|
||||
void setUnit();
|
||||
SqSylvMatrix(int m) : SylvMatrix(m, m)
|
||||
{
|
||||
}
|
||||
SqSylvMatrix(const double *d, int m) : SylvMatrix(d, m, m)
|
||||
{
|
||||
}
|
||||
SqSylvMatrix(double *d, int m) : SylvMatrix(d, m, m)
|
||||
{
|
||||
}
|
||||
SqSylvMatrix(const SqSylvMatrix &m) : SylvMatrix(m)
|
||||
{
|
||||
}
|
||||
SqSylvMatrix(const GeneralMatrix &m, int i, int j, int nrows)
|
||||
: SylvMatrix(m, i, j, nrows, nrows)
|
||||
{
|
||||
}
|
||||
SqSylvMatrix(GeneralMatrix &m, int i, int j, int nrows)
|
||||
: SylvMatrix(m, i, j, nrows, nrows)
|
||||
{
|
||||
}
|
||||
SqSylvMatrix(const GeneralMatrix &a, const GeneralMatrix &b);
|
||||
const SqSylvMatrix &
|
||||
operator=(const SqSylvMatrix &m)
|
||||
{
|
||||
GeneralMatrix::operator=(m); return *this;
|
||||
}
|
||||
/* x = (this \otimes this..\otimes this)*d */
|
||||
void multVecKron(KronVector &x, const KronVector &d) const;
|
||||
/* x = (this' \otimes this'..\otimes this')*d */
|
||||
void multVecKronTrans(KronVector &x, const KronVector &d) const;
|
||||
/* a = inv(this)*a, b=inv(this)*b */
|
||||
void multInvLeft2(GeneralMatrix &a, GeneralMatrix &b,
|
||||
double &rcond1, double &rcondinf) const;
|
||||
/* this = I */
|
||||
void setUnit();
|
||||
};
|
||||
|
||||
|
||||
#endif /* SYLV_MATRIX_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -9,55 +9,57 @@
|
|||
|
||||
#include <new>
|
||||
|
||||
class MallocAllocator {
|
||||
class MallocAllocator
|
||||
{
|
||||
#ifdef USE_MEMORY_POOL
|
||||
public:
|
||||
void* operator new(size_t size);
|
||||
void* operator new[](size_t size);
|
||||
void operator delete(void* p);
|
||||
void operator delete[](void* p);
|
||||
void *operator new(size_t size);
|
||||
void *operator new[](size_t size);
|
||||
void operator delete(void *p);
|
||||
void operator delete[](void *p);
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef USE_MEMORY_POOL
|
||||
void* operator new(size_t size);
|
||||
void* operator new[](size_t size);
|
||||
void operator delete(void* p);
|
||||
void operator delete[](void* p);
|
||||
void *operator new(size_t size);
|
||||
void *operator new[](size_t size);
|
||||
void operator delete(void *p);
|
||||
void operator delete[](void *p);
|
||||
#endif
|
||||
|
||||
class SylvMemoryPool {
|
||||
char* base;
|
||||
size_t length;
|
||||
size_t allocated;
|
||||
bool stack_mode;
|
||||
SylvMemoryPool(const SylvMemoryPool&);
|
||||
const SylvMemoryPool& operator=(const SylvMemoryPool&);
|
||||
class SylvMemoryPool
|
||||
{
|
||||
char *base;
|
||||
size_t length;
|
||||
size_t allocated;
|
||||
bool stack_mode;
|
||||
SylvMemoryPool(const SylvMemoryPool &);
|
||||
const SylvMemoryPool &operator=(const SylvMemoryPool &);
|
||||
public:
|
||||
SylvMemoryPool();
|
||||
~SylvMemoryPool();
|
||||
void init(size_t size);
|
||||
void* allocate(size_t size);
|
||||
void free(void* p);
|
||||
void reset();
|
||||
void setStackMode(bool);
|
||||
SylvMemoryPool();
|
||||
~SylvMemoryPool();
|
||||
void init(size_t size);
|
||||
void *allocate(size_t size);
|
||||
void free(void *p);
|
||||
void reset();
|
||||
void setStackMode(bool);
|
||||
};
|
||||
|
||||
class SylvMemoryDriver {
|
||||
SylvMemoryDriver(const SylvMemoryDriver&);
|
||||
const SylvMemoryDriver& operator=(const SylvMemoryDriver&);
|
||||
class SylvMemoryDriver
|
||||
{
|
||||
SylvMemoryDriver(const SylvMemoryDriver &);
|
||||
const SylvMemoryDriver &operator=(const SylvMemoryDriver &);
|
||||
public:
|
||||
SylvMemoryDriver(int num_d, int m, int n, int order);
|
||||
SylvMemoryDriver(const SylvParams& pars, int num_d, int m, int n, int order);
|
||||
static void setStackMode(bool);
|
||||
~SylvMemoryDriver();
|
||||
SylvMemoryDriver(int num_d, int m, int n, int order);
|
||||
SylvMemoryDriver(const SylvParams &pars, int num_d, int m, int n, int order);
|
||||
static void setStackMode(bool);
|
||||
~SylvMemoryDriver();
|
||||
protected:
|
||||
void allocate(int num_d, int m, int n, int order);
|
||||
void allocate(int num_d, int m, int n, int order);
|
||||
};
|
||||
|
||||
#endif /* SYLV_MEMORY_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -15,148 +15,217 @@
|
|||
typedef enum {def, changed, undef} status;
|
||||
|
||||
template <class _Type>
|
||||
struct ParamItem {
|
||||
struct ParamItem
|
||||
{
|
||||
protected:
|
||||
typedef ParamItem<_Type> _Self;
|
||||
status s;
|
||||
_Type value;
|
||||
typedef ParamItem<_Type> _Self;
|
||||
status s;
|
||||
_Type value;
|
||||
public:
|
||||
ParamItem()
|
||||
{s = undef;}
|
||||
ParamItem(_Type val)
|
||||
{value = val; s = def;}
|
||||
ParamItem(const _Self& item)
|
||||
{value = item.value; s = item.s;}
|
||||
const _Self& operator=(const _Self& item)
|
||||
{value = item.value; s = item.s; return *this;}
|
||||
const _Self& operator=(const _Type& val)
|
||||
{value = val; s = changed; return *this;}
|
||||
_Type operator*() const
|
||||
{return value;}
|
||||
status getStatus() const
|
||||
{return s;}
|
||||
void print(FILE* f, const char* prefix, const char* str, const char* fmt) const
|
||||
{
|
||||
if (s == undef)
|
||||
return;
|
||||
char out[1000];
|
||||
strcpy(out, prefix);
|
||||
strcat(out, str);
|
||||
strcat(out, "= ");
|
||||
strcat(out, fmt);
|
||||
if (s == def)
|
||||
strcat(out, " <default>");
|
||||
strcat(out,"\n");
|
||||
fprintf(f, out, value);
|
||||
}
|
||||
ParamItem()
|
||||
{
|
||||
s = undef;
|
||||
}
|
||||
ParamItem(_Type val)
|
||||
{
|
||||
value = val; s = def;
|
||||
}
|
||||
ParamItem(const _Self &item)
|
||||
{
|
||||
value = item.value; s = item.s;
|
||||
}
|
||||
const _Self &
|
||||
operator=(const _Self &item)
|
||||
{
|
||||
value = item.value; s = item.s; return *this;
|
||||
}
|
||||
const _Self &
|
||||
operator=(const _Type &val)
|
||||
{
|
||||
value = val; s = changed; return *this;
|
||||
}
|
||||
_Type
|
||||
operator*() const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
status
|
||||
getStatus() const
|
||||
{
|
||||
return s;
|
||||
}
|
||||
void
|
||||
print(FILE *f, const char *prefix, const char *str, const char *fmt) const
|
||||
{
|
||||
if (s == undef)
|
||||
return;
|
||||
char out[1000];
|
||||
strcpy(out, prefix);
|
||||
strcat(out, str);
|
||||
strcat(out, "= ");
|
||||
strcat(out, fmt);
|
||||
if (s == def)
|
||||
strcat(out, " <default>");
|
||||
strcat(out, "\n");
|
||||
fprintf(f, out, value);
|
||||
}
|
||||
};
|
||||
|
||||
class SylvParams {
|
||||
class SylvParams
|
||||
{
|
||||
public:
|
||||
typedef enum {iter, recurse} solve_method;
|
||||
typedef enum {iter, recurse} solve_method;
|
||||
|
||||
protected:
|
||||
class DoubleParamItem : public ParamItem<double> {
|
||||
public:
|
||||
DoubleParamItem() : ParamItem<double>() {}
|
||||
DoubleParamItem(double val) : ParamItem<double>(val) {}
|
||||
DoubleParamItem(const DoubleParamItem& item) : ParamItem<double>(item) {}
|
||||
const DoubleParamItem& operator=(const double& val)
|
||||
{ParamItem<double>::operator=(val); return *this;}
|
||||
class DoubleParamItem : public ParamItem<double>
|
||||
{
|
||||
public:
|
||||
DoubleParamItem() : ParamItem<double>()
|
||||
{
|
||||
}
|
||||
DoubleParamItem(double val) : ParamItem<double>(val)
|
||||
{
|
||||
}
|
||||
DoubleParamItem(const DoubleParamItem &item) : ParamItem<double>(item)
|
||||
{
|
||||
}
|
||||
const DoubleParamItem &
|
||||
operator=(const double &val)
|
||||
{
|
||||
ParamItem<double>::operator=(val); return *this;
|
||||
}
|
||||
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
||||
mxArray* createMatlabArray() const;
|
||||
mxArray *createMatlabArray() const;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
class IntParamItem : public ParamItem<int> {
|
||||
public:
|
||||
IntParamItem() : ParamItem<int>() {}
|
||||
IntParamItem(int val) : ParamItem<int>(val) {}
|
||||
IntParamItem(const IntParamItem& item) : ParamItem<int>(item) {}
|
||||
const IntParamItem& operator=(const int& val)
|
||||
{ParamItem<int>::operator=(val); return *this;}
|
||||
class IntParamItem : public ParamItem<int>
|
||||
{
|
||||
public:
|
||||
IntParamItem() : ParamItem<int>()
|
||||
{
|
||||
}
|
||||
IntParamItem(int val) : ParamItem<int>(val)
|
||||
{
|
||||
}
|
||||
IntParamItem(const IntParamItem &item) : ParamItem<int>(item)
|
||||
{
|
||||
}
|
||||
const IntParamItem &
|
||||
operator=(const int &val)
|
||||
{
|
||||
ParamItem<int>::operator=(val); return *this;
|
||||
}
|
||||
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
||||
mxArray* createMatlabArray() const;
|
||||
mxArray *createMatlabArray() const;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
class BoolParamItem : public ParamItem<bool> {
|
||||
public:
|
||||
BoolParamItem() : ParamItem<bool>() {}
|
||||
BoolParamItem(bool val) : ParamItem<bool>(val) {}
|
||||
BoolParamItem(const BoolParamItem& item) : ParamItem<bool>(item) {}
|
||||
const BoolParamItem& operator=(const bool& val)
|
||||
{ParamItem<bool>::operator=(val); return *this;}
|
||||
class BoolParamItem : public ParamItem<bool>
|
||||
{
|
||||
public:
|
||||
BoolParamItem() : ParamItem<bool>()
|
||||
{
|
||||
}
|
||||
BoolParamItem(bool val) : ParamItem<bool>(val)
|
||||
{
|
||||
}
|
||||
BoolParamItem(const BoolParamItem &item) : ParamItem<bool>(item)
|
||||
{
|
||||
}
|
||||
const BoolParamItem &
|
||||
operator=(const bool &val)
|
||||
{
|
||||
ParamItem<bool>::operator=(val); return *this;
|
||||
}
|
||||
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
||||
mxArray* createMatlabArray() const;
|
||||
mxArray *createMatlabArray() const;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
class MethodParamItem : public ParamItem<solve_method> {
|
||||
public:
|
||||
MethodParamItem() : ParamItem<solve_method>() {}
|
||||
MethodParamItem(solve_method val) : ParamItem<solve_method>(val) {}
|
||||
MethodParamItem(const MethodParamItem& item) : ParamItem<solve_method>(item) {}
|
||||
const MethodParamItem operator=(const solve_method& val)
|
||||
{ParamItem<solve_method>::operator=(val); return *this;}
|
||||
class MethodParamItem : public ParamItem<solve_method>
|
||||
{
|
||||
public:
|
||||
MethodParamItem() : ParamItem<solve_method>()
|
||||
{
|
||||
}
|
||||
MethodParamItem(solve_method val) : ParamItem<solve_method>(val)
|
||||
{
|
||||
}
|
||||
MethodParamItem(const MethodParamItem &item) : ParamItem<solve_method>(item)
|
||||
{
|
||||
}
|
||||
const MethodParamItem
|
||||
operator=(const solve_method &val)
|
||||
{
|
||||
ParamItem<solve_method>::operator=(val); return *this;
|
||||
}
|
||||
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
||||
mxArray* createMatlabArray() const;
|
||||
mxArray *createMatlabArray() const;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
public:
|
||||
// input parameters
|
||||
MethodParamItem method; // method of solution: iter/recurse
|
||||
DoubleParamItem convergence_tol; // norm for what we consider converged
|
||||
IntParamItem max_num_iter; // max number of iterations
|
||||
DoubleParamItem bs_norm; // Bavely Stewart log10 of norm for diagonalization
|
||||
BoolParamItem want_check; // true => allocate extra space for checks
|
||||
// output parameters
|
||||
BoolParamItem converged; // true if converged
|
||||
DoubleParamItem iter_last_norm; // norm of the last iteration
|
||||
IntParamItem num_iter; // number of iterations
|
||||
DoubleParamItem f_err1; // norm 1 of diagonalization abs. error C-V*F*inv(V)
|
||||
DoubleParamItem f_errI; // norm Inf of diagonalization abs. error C-V*F*inv(V)
|
||||
DoubleParamItem viv_err1; // norm 1 of error I-V*inv(V)
|
||||
DoubleParamItem viv_errI; // norm Inf of error I-V*inv(V)
|
||||
DoubleParamItem ivv_err1; // norm 1 of error I-inv(V)*V
|
||||
DoubleParamItem ivv_errI; // norm Inf of error I-inv(V)*V
|
||||
IntParamItem f_blocks; // number of diagonal blocks of F
|
||||
IntParamItem f_largest; // size of largest diagonal block in F
|
||||
IntParamItem f_zeros; // number of off diagonal zeros in F
|
||||
IntParamItem f_offdiag; // number of all off diagonal elements in F
|
||||
DoubleParamItem rcondA1; // reciprocal cond 1 number of A
|
||||
DoubleParamItem rcondAI; // reciprocal cond Inf number of A
|
||||
DoubleParamItem eig_min; // minimum eigenvalue of the solved system
|
||||
DoubleParamItem mat_err1; // rel. matrix 1 norm of A*X-B*X*kron(C,..,C)-D
|
||||
DoubleParamItem mat_errI; // rel. matrix Inf norm of A*X-B*X*kron(C,..,C)-D
|
||||
DoubleParamItem mat_errF; // rel. matrix Frob. norm of A*X-B*X*kron(C,..,C)-D
|
||||
DoubleParamItem vec_err1; // rel. vector 1 norm of A*X-B*X*kron(C,..,C)-D
|
||||
DoubleParamItem vec_errI; // rel. vector Inf norm of A*X-B*X*kron(C,..,C)-D
|
||||
DoubleParamItem cpu_time; // time of the job in CPU seconds
|
||||
// note: remember to change copy() if adding/removing member
|
||||
// input parameters
|
||||
MethodParamItem method; // method of solution: iter/recurse
|
||||
DoubleParamItem convergence_tol; // norm for what we consider converged
|
||||
IntParamItem max_num_iter; // max number of iterations
|
||||
DoubleParamItem bs_norm; // Bavely Stewart log10 of norm for diagonalization
|
||||
BoolParamItem want_check; // true => allocate extra space for checks
|
||||
// output parameters
|
||||
BoolParamItem converged; // true if converged
|
||||
DoubleParamItem iter_last_norm; // norm of the last iteration
|
||||
IntParamItem num_iter; // number of iterations
|
||||
DoubleParamItem f_err1; // norm 1 of diagonalization abs. error C-V*F*inv(V)
|
||||
DoubleParamItem f_errI; // norm Inf of diagonalization abs. error C-V*F*inv(V)
|
||||
DoubleParamItem viv_err1; // norm 1 of error I-V*inv(V)
|
||||
DoubleParamItem viv_errI; // norm Inf of error I-V*inv(V)
|
||||
DoubleParamItem ivv_err1; // norm 1 of error I-inv(V)*V
|
||||
DoubleParamItem ivv_errI; // norm Inf of error I-inv(V)*V
|
||||
IntParamItem f_blocks; // number of diagonal blocks of F
|
||||
IntParamItem f_largest; // size of largest diagonal block in F
|
||||
IntParamItem f_zeros; // number of off diagonal zeros in F
|
||||
IntParamItem f_offdiag; // number of all off diagonal elements in F
|
||||
DoubleParamItem rcondA1; // reciprocal cond 1 number of A
|
||||
DoubleParamItem rcondAI; // reciprocal cond Inf number of A
|
||||
DoubleParamItem eig_min; // minimum eigenvalue of the solved system
|
||||
DoubleParamItem mat_err1; // rel. matrix 1 norm of A*X-B*X*kron(C,..,C)-D
|
||||
DoubleParamItem mat_errI; // rel. matrix Inf norm of A*X-B*X*kron(C,..,C)-D
|
||||
DoubleParamItem mat_errF; // rel. matrix Frob. norm of A*X-B*X*kron(C,..,C)-D
|
||||
DoubleParamItem vec_err1; // rel. vector 1 norm of A*X-B*X*kron(C,..,C)-D
|
||||
DoubleParamItem vec_errI; // rel. vector Inf norm of A*X-B*X*kron(C,..,C)-D
|
||||
DoubleParamItem cpu_time; // time of the job in CPU seconds
|
||||
// note: remember to change copy() if adding/removing member
|
||||
|
||||
SylvParams(bool wc = false)
|
||||
: method(recurse), convergence_tol(1.e-30), max_num_iter(15),
|
||||
bs_norm(1.3), want_check(wc) {}
|
||||
SylvParams(const SylvParams& p)
|
||||
{copy(p);}
|
||||
const SylvParams& operator=(const SylvParams& p)
|
||||
{copy(p); return *this;}
|
||||
~SylvParams() {}
|
||||
void print(const char* prefix) const;
|
||||
void print(FILE* fdesc, const char* prefix) const;
|
||||
void setArrayNames(int& num, const char** names) const;
|
||||
SylvParams(bool wc = false)
|
||||
: method(recurse), convergence_tol(1.e-30), max_num_iter(15),
|
||||
bs_norm(1.3), want_check(wc)
|
||||
{
|
||||
}
|
||||
SylvParams(const SylvParams &p)
|
||||
{
|
||||
copy(p);
|
||||
}
|
||||
const SylvParams &
|
||||
operator=(const SylvParams &p)
|
||||
{
|
||||
copy(p); return *this;
|
||||
}
|
||||
~SylvParams()
|
||||
{
|
||||
}
|
||||
void print(const char *prefix) const;
|
||||
void print(FILE *fdesc, const char *prefix) const;
|
||||
void setArrayNames(int &num, const char **names) const;
|
||||
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
||||
mxArray* createStructArray() const;
|
||||
mxArray *createStructArray() const;
|
||||
#endif
|
||||
private:
|
||||
void copy(const SylvParams& p);
|
||||
void copy(const SylvParams &p);
|
||||
};
|
||||
|
||||
#endif /* SYLV_PARAMS_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -12,40 +12,47 @@
|
|||
#include "SylvParams.h"
|
||||
#include "SchurDecomp.h"
|
||||
|
||||
class SylvesterSolver {
|
||||
class SylvesterSolver
|
||||
{
|
||||
protected:
|
||||
const QuasiTriangular* const matrixK;
|
||||
const QuasiTriangular* const matrixF;
|
||||
const QuasiTriangular *const matrixK;
|
||||
const QuasiTriangular *const matrixF;
|
||||
private:
|
||||
/* return true when it is more efficient to use QuasiTriangular
|
||||
* than QuasiTriangularZero */
|
||||
static bool zeroPad(const SchurDecompZero& kdecomp) {
|
||||
return ((kdecomp.getZeroCols()*3 < kdecomp.getDim()*2) ||
|
||||
(kdecomp.getZeroCols() < 10));
|
||||
}
|
||||
/* return true when it is more efficient to use QuasiTriangular
|
||||
* than QuasiTriangularZero */
|
||||
static bool
|
||||
zeroPad(const SchurDecompZero &kdecomp)
|
||||
{
|
||||
return ((kdecomp.getZeroCols()*3 < kdecomp.getDim()*2)
|
||||
|| (kdecomp.getZeroCols() < 10));
|
||||
}
|
||||
public:
|
||||
SylvesterSolver(const QuasiTriangular& k, const QuasiTriangular& f)
|
||||
: matrixK(new QuasiTriangular(k)),
|
||||
matrixF(new QuasiTriangular(f))
|
||||
{}
|
||||
SylvesterSolver(const SchurDecompZero& kdecomp, const SchurDecomp& fdecomp)
|
||||
: matrixK((zeroPad(kdecomp)) ?
|
||||
new QuasiTriangular(kdecomp) : new QuasiTriangularZero(kdecomp)),
|
||||
matrixF(new QuasiTriangular(fdecomp))
|
||||
{}
|
||||
SylvesterSolver(const SchurDecompZero& kdecomp, const SimilarityDecomp& fdecomp)
|
||||
: matrixK((zeroPad(kdecomp)) ?
|
||||
new QuasiTriangular(kdecomp) : new QuasiTriangularZero(kdecomp)),
|
||||
matrixF(new BlockDiagonal(fdecomp.getB()))
|
||||
{}
|
||||
virtual ~SylvesterSolver()
|
||||
{delete matrixK; delete matrixF;}
|
||||
virtual void solve(SylvParams& pars, KronVector& x) const = 0;
|
||||
SylvesterSolver(const QuasiTriangular &k, const QuasiTriangular &f)
|
||||
: matrixK(new QuasiTriangular(k)),
|
||||
matrixF(new QuasiTriangular(f))
|
||||
{
|
||||
}
|
||||
SylvesterSolver(const SchurDecompZero &kdecomp, const SchurDecomp &fdecomp)
|
||||
: matrixK((zeroPad(kdecomp)) ?
|
||||
new QuasiTriangular(kdecomp) : new QuasiTriangularZero(kdecomp)),
|
||||
matrixF(new QuasiTriangular(fdecomp))
|
||||
{
|
||||
}
|
||||
SylvesterSolver(const SchurDecompZero &kdecomp, const SimilarityDecomp &fdecomp)
|
||||
: matrixK((zeroPad(kdecomp)) ?
|
||||
new QuasiTriangular(kdecomp) : new QuasiTriangularZero(kdecomp)),
|
||||
matrixF(new BlockDiagonal(fdecomp.getB()))
|
||||
{
|
||||
}
|
||||
virtual ~SylvesterSolver()
|
||||
{
|
||||
delete matrixK; delete matrixF;
|
||||
}
|
||||
virtual void solve(SylvParams &pars, KronVector &x) const = 0;
|
||||
};
|
||||
|
||||
#endif /* SYLVESTER_SOLVER_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -7,35 +7,45 @@
|
|||
|
||||
#include "SylvMatrix.h"
|
||||
|
||||
class SymSchurDecomp {
|
||||
class SymSchurDecomp
|
||||
{
|
||||
protected:
|
||||
Vector lambda;
|
||||
SqSylvMatrix q;
|
||||
Vector lambda;
|
||||
SqSylvMatrix q;
|
||||
public:
|
||||
/** Calculates A = Q*Lambda*Q^T, where A is assummed to be
|
||||
* symmetric and Lambda real diagonal, hence a vector. */
|
||||
SymSchurDecomp(const GeneralMatrix& a);
|
||||
SymSchurDecomp(const SymSchurDecomp& ssd)
|
||||
: lambda(ssd.lambda), q(ssd.q) {}
|
||||
virtual ~SymSchurDecomp() {}
|
||||
const Vector& getLambda() const
|
||||
{return lambda;}
|
||||
const SqSylvMatrix& getQ() const
|
||||
{return q;}
|
||||
/** Return factor F*F^T = A, raises and exception if A is not
|
||||
* positive semidefinite, F must be square. */
|
||||
void getFactor(GeneralMatrix& f) const;
|
||||
/** Returns true if A is positive semidefinite. */
|
||||
bool isPositiveSemidefinite() const;
|
||||
/** Correct definitness. This sets all eigenvalues between minus
|
||||
* tolerance and zero to zero. */
|
||||
void correctDefinitness(double tol);
|
||||
/** Calculates A = Q*Lambda*Q^T, where A is assummed to be
|
||||
* symmetric and Lambda real diagonal, hence a vector. */
|
||||
SymSchurDecomp(const GeneralMatrix &a);
|
||||
SymSchurDecomp(const SymSchurDecomp &ssd)
|
||||
: lambda(ssd.lambda), q(ssd.q)
|
||||
{
|
||||
}
|
||||
virtual ~SymSchurDecomp()
|
||||
{
|
||||
}
|
||||
const Vector &
|
||||
getLambda() const
|
||||
{
|
||||
return lambda;
|
||||
}
|
||||
const SqSylvMatrix &
|
||||
getQ() const
|
||||
{
|
||||
return q;
|
||||
}
|
||||
/** Return factor F*F^T = A, raises and exception if A is not
|
||||
* positive semidefinite, F must be square. */
|
||||
void getFactor(GeneralMatrix &f) const;
|
||||
/** Returns true if A is positive semidefinite. */
|
||||
bool isPositiveSemidefinite() const;
|
||||
/** Correct definitness. This sets all eigenvalues between minus
|
||||
* tolerance and zero to zero. */
|
||||
void correctDefinitness(double tol);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -11,105 +11,112 @@
|
|||
#include "QuasiTriangularZero.h"
|
||||
#include "SimilarityDecomp.h"
|
||||
|
||||
class TriangularSylvester : public SylvesterSolver {
|
||||
const QuasiTriangular* const matrixKK;
|
||||
const QuasiTriangular* const matrixFF;
|
||||
class TriangularSylvester : public SylvesterSolver
|
||||
{
|
||||
const QuasiTriangular *const matrixKK;
|
||||
const QuasiTriangular *const matrixFF;
|
||||
public:
|
||||
TriangularSylvester(const QuasiTriangular& k, const QuasiTriangular& f);
|
||||
TriangularSylvester(const SchurDecompZero& kdecomp, const SchurDecomp& fdecomp);
|
||||
TriangularSylvester(const SchurDecompZero& kdecomp, const SimilarityDecomp& fdecomp);
|
||||
virtual ~TriangularSylvester();
|
||||
void print() const;
|
||||
void solve(SylvParams& pars, KronVector& d) const;
|
||||
TriangularSylvester(const QuasiTriangular &k, const QuasiTriangular &f);
|
||||
TriangularSylvester(const SchurDecompZero &kdecomp, const SchurDecomp &fdecomp);
|
||||
TriangularSylvester(const SchurDecompZero &kdecomp, const SimilarityDecomp &fdecomp);
|
||||
virtual
|
||||
~TriangularSylvester();
|
||||
void print() const;
|
||||
void solve(SylvParams &pars, KronVector &d) const;
|
||||
|
||||
void solvi(double r, KronVector& d, double& eig_min) const;
|
||||
void solvii(double alpha, double beta1, double beta2,
|
||||
KronVector& d1, KronVector& d2,
|
||||
double& eig_min) const;
|
||||
void solviip(double alpha, double betas,
|
||||
KronVector& d, double& eig_min) const;
|
||||
/* evaluates:
|
||||
|x1| |d1| |alpha -beta1| |d1|
|
||||
| | = | |+| |\otimes F'...\otimes K | |
|
||||
|x2| |d2| |beta2 alpha| |d2|
|
||||
*/
|
||||
void linEval(double alpha, double beta1, double beta2,
|
||||
KronVector& x1, KronVector& x2,
|
||||
const ConstKronVector& d1, const ConstKronVector& d2) const;
|
||||
void linEval(double alpha, double beta1, double beta2,
|
||||
KronVector& x1, KronVector& x2,
|
||||
const KronVector& d1, const KronVector& d2) const
|
||||
{linEval(alpha, beta1, beta2, x1, x2,
|
||||
ConstKronVector(d1), ConstKronVector(d2));}
|
||||
void solvi(double r, KronVector &d, double &eig_min) const;
|
||||
void solvii(double alpha, double beta1, double beta2,
|
||||
KronVector &d1, KronVector &d2,
|
||||
double &eig_min) const;
|
||||
void solviip(double alpha, double betas,
|
||||
KronVector &d, double &eig_min) const;
|
||||
/* evaluates:
|
||||
|x1| |d1| |alpha -beta1| |d1|
|
||||
| | = | |+| |\otimes F'...\otimes K | |
|
||||
|x2| |d2| |beta2 alpha| |d2|
|
||||
*/
|
||||
void linEval(double alpha, double beta1, double beta2,
|
||||
KronVector &x1, KronVector &x2,
|
||||
const ConstKronVector &d1, const ConstKronVector &d2) const;
|
||||
void
|
||||
linEval(double alpha, double beta1, double beta2,
|
||||
KronVector &x1, KronVector &x2,
|
||||
const KronVector &d1, const KronVector &d2) const
|
||||
{
|
||||
linEval(alpha, beta1, beta2, x1, x2,
|
||||
ConstKronVector(d1), ConstKronVector(d2));
|
||||
}
|
||||
|
||||
/* evaluates:
|
||||
|x1| |d1| |gamma -delta1| |d1|
|
||||
| | = | | + 2alpha*| |\otimes F'...\otimes K | | +
|
||||
|x2| |d2| |delta2 gamma| |d2|
|
||||
/* evaluates:
|
||||
|x1| |d1| |gamma -delta1| |d1|
|
||||
| | = | | + 2alpha*| |\otimes F'...\otimes K | | +
|
||||
|x2| |d2| |delta2 gamma| |d2|
|
||||
|
||||
|gamma -delta1|^2 |d1|
|
||||
+ (alpha^2+betas)*| |\otimes F'2...\otimes K2 | |
|
||||
|delta2 gamma| |d2|
|
||||
*/
|
||||
void quaEval(double alpha, double betas,
|
||||
double gamma, double delta1, double delta2,
|
||||
KronVector& x1, KronVector& x2,
|
||||
const ConstKronVector& d1, const ConstKronVector& d2) const;
|
||||
void quaEval(double alpha, double betas,
|
||||
double gamma, double delta1, double delta2,
|
||||
KronVector& x1, KronVector& x2,
|
||||
const KronVector& d1, const KronVector& d2) const
|
||||
{quaEval(alpha, betas, gamma, delta1, delta2, x1, x2,
|
||||
ConstKronVector(d1), ConstKronVector(d2));}
|
||||
|gamma -delta1|^2 |d1|
|
||||
+ (alpha^2+betas)*| |\otimes F'2...\otimes K2 | |
|
||||
|delta2 gamma| |d2|
|
||||
*/
|
||||
void quaEval(double alpha, double betas,
|
||||
double gamma, double delta1, double delta2,
|
||||
KronVector &x1, KronVector &x2,
|
||||
const ConstKronVector &d1, const ConstKronVector &d2) const;
|
||||
void
|
||||
quaEval(double alpha, double betas,
|
||||
double gamma, double delta1, double delta2,
|
||||
KronVector &x1, KronVector &x2,
|
||||
const KronVector &d1, const KronVector &d2) const
|
||||
{
|
||||
quaEval(alpha, betas, gamma, delta1, delta2, x1, x2,
|
||||
ConstKronVector(d1), ConstKronVector(d2));
|
||||
}
|
||||
private:
|
||||
/* returns square of size of minimal eigenvalue of the system solved,
|
||||
now obsolete */
|
||||
double getEigSep(int depth) const;
|
||||
/* recursivelly calculates kronecker product of complex vectors (used in getEigSep) */
|
||||
static void multEigVector(KronVector& eig, const Vector& feig, const Vector& keig);
|
||||
/* auxiliary typedefs */
|
||||
typedef QuasiTriangular::const_diag_iter const_diag_iter;
|
||||
typedef QuasiTriangular::const_row_iter const_row_iter;
|
||||
/* called from solvi */
|
||||
void solviRealAndEliminate(double r, const_diag_iter di,
|
||||
KronVector& d, double& eig_min) const;
|
||||
void solviComplexAndEliminate(double r, const_diag_iter di,
|
||||
KronVector& d, double& eig_min) const;
|
||||
/* called from solviip */
|
||||
void solviipRealAndEliminate(double alpha, double betas,
|
||||
const_diag_iter di, const_diag_iter dsi,
|
||||
KronVector& d, double& eig_min) const;
|
||||
void solviipComplexAndEliminate(double alpha, double betas,
|
||||
const_diag_iter di, const_diag_iter dsi,
|
||||
KronVector& d, double& eig_min) const;
|
||||
/* eliminations */
|
||||
void solviEliminateReal(const_diag_iter di, KronVector& d,
|
||||
const KronVector& y, double divisor) const;
|
||||
void solviEliminateComplex(const_diag_iter di, KronVector& d,
|
||||
const KronVector& y1, const KronVector& y2,
|
||||
double divisor) const;
|
||||
void solviipEliminateReal(const_diag_iter di, const_diag_iter dsi,
|
||||
KronVector& d,
|
||||
const KronVector& y1, const KronVector& y2,
|
||||
double divisor, double divisor2) const;
|
||||
void solviipEliminateComplex(const_diag_iter di, const_diag_iter dsi,
|
||||
KronVector& d,
|
||||
const KronVector& y1, const KronVector& y11,
|
||||
const KronVector& y2, const KronVector& y22,
|
||||
double divisor) const;
|
||||
/* Lemma 2 */
|
||||
void solviipComplex(double alpha, double betas, double gamma,
|
||||
double delta1, double delta2,
|
||||
KronVector& d1, KronVector& d2,
|
||||
double& eig_min) const;
|
||||
/* norms for what we consider zero on diagonal of F */
|
||||
static double diag_zero;
|
||||
static double diag_zero_sq; // square of diag_zero
|
||||
/* returns square of size of minimal eigenvalue of the system solved,
|
||||
now obsolete */
|
||||
double getEigSep(int depth) const;
|
||||
/* recursivelly calculates kronecker product of complex vectors (used in getEigSep) */
|
||||
static void multEigVector(KronVector &eig, const Vector &feig, const Vector &keig);
|
||||
/* auxiliary typedefs */
|
||||
typedef QuasiTriangular::const_diag_iter const_diag_iter;
|
||||
typedef QuasiTriangular::const_row_iter const_row_iter;
|
||||
/* called from solvi */
|
||||
void solviRealAndEliminate(double r, const_diag_iter di,
|
||||
KronVector &d, double &eig_min) const;
|
||||
void solviComplexAndEliminate(double r, const_diag_iter di,
|
||||
KronVector &d, double &eig_min) const;
|
||||
/* called from solviip */
|
||||
void solviipRealAndEliminate(double alpha, double betas,
|
||||
const_diag_iter di, const_diag_iter dsi,
|
||||
KronVector &d, double &eig_min) const;
|
||||
void solviipComplexAndEliminate(double alpha, double betas,
|
||||
const_diag_iter di, const_diag_iter dsi,
|
||||
KronVector &d, double &eig_min) const;
|
||||
/* eliminations */
|
||||
void solviEliminateReal(const_diag_iter di, KronVector &d,
|
||||
const KronVector &y, double divisor) const;
|
||||
void solviEliminateComplex(const_diag_iter di, KronVector &d,
|
||||
const KronVector &y1, const KronVector &y2,
|
||||
double divisor) const;
|
||||
void solviipEliminateReal(const_diag_iter di, const_diag_iter dsi,
|
||||
KronVector &d,
|
||||
const KronVector &y1, const KronVector &y2,
|
||||
double divisor, double divisor2) const;
|
||||
void solviipEliminateComplex(const_diag_iter di, const_diag_iter dsi,
|
||||
KronVector &d,
|
||||
const KronVector &y1, const KronVector &y11,
|
||||
const KronVector &y2, const KronVector &y22,
|
||||
double divisor) const;
|
||||
/* Lemma 2 */
|
||||
void solviipComplex(double alpha, double betas, double gamma,
|
||||
double delta1, double delta2,
|
||||
KronVector &d1, KronVector &d2,
|
||||
double &eig_min) const;
|
||||
/* norms for what we consider zero on diagonal of F */
|
||||
static double diag_zero;
|
||||
static double diag_zero_sq; // square of diag_zero
|
||||
};
|
||||
|
||||
#endif /* TRIANGULAR_SYLVESTER_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -7,169 +7,252 @@
|
|||
|
||||
/* NOTE! Vector and ConstVector have not common super class in order
|
||||
* to avoid running virtual method invokation mechanism. Some
|
||||
* members, and methods are thus duplicated */
|
||||
* members, and methods are thus duplicated */
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
class GeneralMatrix;
|
||||
class ConstVector;
|
||||
|
||||
class Vector {
|
||||
class Vector
|
||||
{
|
||||
protected:
|
||||
int len;
|
||||
int s;
|
||||
double* data;
|
||||
bool destroy;
|
||||
int len;
|
||||
int s;
|
||||
double *data;
|
||||
bool destroy;
|
||||
public:
|
||||
Vector() : len(0), s(1), data(0), destroy(false) {}
|
||||
Vector(int l) : len(l), s(1), data(new double[l]), destroy(true) {}
|
||||
Vector(Vector& v) : len(v.length()), s(v.skip()), data(v.base()), destroy(false) {}
|
||||
Vector(const Vector& v);
|
||||
Vector(const ConstVector& v);
|
||||
Vector(const double* d, int l)
|
||||
: len(l), s(1), data(new double[len]), destroy(true)
|
||||
{copy(d, 1);}
|
||||
Vector(double* d, int l)
|
||||
: len(l), s(1), data(d), destroy(false) {}
|
||||
Vector(double* d, int skip, int l)
|
||||
: len(l), s(skip), data(d), destroy(false) {}
|
||||
Vector(Vector& v, int off, int l);
|
||||
Vector(const Vector& v, int off, int l);
|
||||
Vector(GeneralMatrix& m, int col);
|
||||
Vector(int row, GeneralMatrix& m);
|
||||
const Vector& operator=(const Vector& v);
|
||||
const Vector& operator=(const ConstVector& v);
|
||||
double& operator[](int i)
|
||||
{return data[s*i];}
|
||||
const double& operator[](int i) const
|
||||
{return data[s*i];}
|
||||
const double* base() const
|
||||
{return data;}
|
||||
double* base()
|
||||
{return data;}
|
||||
int length() const
|
||||
{return len;}
|
||||
int skip() const
|
||||
{return s;}
|
||||
Vector() : len(0), s(1), data(0), destroy(false)
|
||||
{
|
||||
}
|
||||
Vector(int l) : len(l), s(1), data(new double[l]), destroy(true)
|
||||
{
|
||||
}
|
||||
Vector(Vector &v) : len(v.length()), s(v.skip()), data(v.base()), destroy(false)
|
||||
{
|
||||
}
|
||||
Vector(const Vector &v);
|
||||
Vector(const ConstVector &v);
|
||||
Vector(const double *d, int l)
|
||||
: len(l), s(1), data(new double[len]), destroy(true)
|
||||
{
|
||||
copy(d, 1);
|
||||
}
|
||||
Vector(double *d, int l)
|
||||
: len(l), s(1), data(d), destroy(false)
|
||||
{
|
||||
}
|
||||
Vector(double *d, int skip, int l)
|
||||
: len(l), s(skip), data(d), destroy(false)
|
||||
{
|
||||
}
|
||||
Vector(Vector &v, int off, int l);
|
||||
Vector(const Vector &v, int off, int l);
|
||||
Vector(GeneralMatrix &m, int col);
|
||||
Vector(int row, GeneralMatrix &m);
|
||||
const Vector &operator=(const Vector &v);
|
||||
const Vector &operator=(const ConstVector &v);
|
||||
double &
|
||||
operator[](int i)
|
||||
{
|
||||
return data[s*i];
|
||||
}
|
||||
const double &
|
||||
operator[](int i) const
|
||||
{
|
||||
return data[s*i];
|
||||
}
|
||||
const double *
|
||||
base() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
double *
|
||||
base()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
int
|
||||
length() const
|
||||
{
|
||||
return len;
|
||||
}
|
||||
int
|
||||
skip() const
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
/** Exact equality. */
|
||||
bool operator==(const Vector& y) const;
|
||||
bool operator!=(const Vector& y) const;
|
||||
/** Lexicographic ordering. */
|
||||
bool operator<(const Vector& y) const;
|
||||
bool operator<=(const Vector& y) const;
|
||||
bool operator>(const Vector& y) const;
|
||||
bool operator>=(const Vector& y) const;
|
||||
/** Exact equality. */
|
||||
bool operator==(const Vector &y) const;
|
||||
bool operator!=(const Vector &y) const;
|
||||
/** Lexicographic ordering. */
|
||||
bool operator<(const Vector &y) const;
|
||||
bool operator<=(const Vector &y) const;
|
||||
bool operator>(const Vector &y) const;
|
||||
bool operator>=(const Vector &y) const;
|
||||
|
||||
virtual ~Vector();
|
||||
void zeros();
|
||||
void nans();
|
||||
void infs();
|
||||
bool toBeDestroyed() const {return destroy;}
|
||||
void rotatePair(double alpha, double beta1, double beta2, int i);
|
||||
void add(double r, const Vector& v);
|
||||
void add(double r, const ConstVector& v);
|
||||
void add(const double* z, const Vector& v);
|
||||
void add(const double* z, const ConstVector& v);
|
||||
void mult(double r);
|
||||
double getNorm() const;
|
||||
double getMax() const;
|
||||
double getNorm1() const;
|
||||
double dot(const Vector& y) const;
|
||||
bool isFinite() const;
|
||||
void print() const;
|
||||
virtual
|
||||
~Vector();
|
||||
void zeros();
|
||||
void nans();
|
||||
void infs();
|
||||
bool
|
||||
toBeDestroyed() const
|
||||
{
|
||||
return destroy;
|
||||
}
|
||||
void rotatePair(double alpha, double beta1, double beta2, int i);
|
||||
void add(double r, const Vector &v);
|
||||
void add(double r, const ConstVector &v);
|
||||
void add(const double *z, const Vector &v);
|
||||
void add(const double *z, const ConstVector &v);
|
||||
void mult(double r);
|
||||
double getNorm() const;
|
||||
double getMax() const;
|
||||
double getNorm1() const;
|
||||
double dot(const Vector &y) const;
|
||||
bool isFinite() const;
|
||||
void print() const;
|
||||
|
||||
/* multiplies | alpha -beta1| |b1| |x1|
|
||||
| |\otimes I .| | = | |
|
||||
| -beta2 alpha| |b2| |x2|
|
||||
*/
|
||||
static void mult2(double alpha, double beta1, double beta2,
|
||||
Vector& x1, Vector& x2,
|
||||
const Vector& b1, const Vector& b2);
|
||||
/* same, but adds instead of set */
|
||||
static void mult2a(double alpha, double beta1, double beta2,
|
||||
Vector& x1, Vector& x2,
|
||||
const Vector& b1, const Vector& b2);
|
||||
/* same, but subtracts instead of add */
|
||||
static void mult2s(double alpha, double beta1, double beta2,
|
||||
Vector& x1, Vector& x2,
|
||||
const Vector& b1, const Vector& b2)
|
||||
{mult2a(-alpha, -beta1, -beta2, x1, x2, b1, b2);}
|
||||
/* multiplies | alpha -beta1| |b1| |x1|
|
||||
| |\otimes I .| | = | |
|
||||
| -beta2 alpha| |b2| |x2|
|
||||
*/
|
||||
static void mult2(double alpha, double beta1, double beta2,
|
||||
Vector &x1, Vector &x2,
|
||||
const Vector &b1, const Vector &b2);
|
||||
/* same, but adds instead of set */
|
||||
static void mult2a(double alpha, double beta1, double beta2,
|
||||
Vector &x1, Vector &x2,
|
||||
const Vector &b1, const Vector &b2);
|
||||
/* same, but subtracts instead of add */
|
||||
static void
|
||||
mult2s(double alpha, double beta1, double beta2,
|
||||
Vector &x1, Vector &x2,
|
||||
const Vector &b1, const Vector &b2)
|
||||
{
|
||||
mult2a(-alpha, -beta1, -beta2, x1, x2, b1, b2);
|
||||
}
|
||||
private:
|
||||
void copy(const double* d, int inc);
|
||||
const Vector& operator=(int); // must not be used (not implemented)
|
||||
const Vector& operator=(double); // must not be used (not implemented)
|
||||
void copy(const double *d, int inc);
|
||||
const Vector &operator=(int); // must not be used (not implemented)
|
||||
const Vector &operator=(double); // must not be used (not implemented)
|
||||
};
|
||||
|
||||
|
||||
class BaseConstVector {
|
||||
class BaseConstVector
|
||||
{
|
||||
protected:
|
||||
int len;
|
||||
int s;
|
||||
const double* data;
|
||||
int len;
|
||||
int s;
|
||||
const double *data;
|
||||
public:
|
||||
BaseConstVector(int l, int si, const double* d) : len(l), s(si), data(d) {}
|
||||
BaseConstVector(const BaseConstVector& v) : len(v.len), s(v.s), data(v.data) {}
|
||||
const BaseConstVector& operator=(const BaseConstVector& v)
|
||||
{len = v.len; s = v.s; data = v.data; return *this;}
|
||||
const double& operator[](int i) const
|
||||
{return data[s*i];}
|
||||
const double* base() const
|
||||
{return data;}
|
||||
int length() const
|
||||
{return len;}
|
||||
int skip() const
|
||||
{return s;}
|
||||
BaseConstVector(int l, int si, const double *d) : len(l), s(si), data(d)
|
||||
{
|
||||
}
|
||||
BaseConstVector(const BaseConstVector &v) : len(v.len), s(v.s), data(v.data)
|
||||
{
|
||||
}
|
||||
const BaseConstVector &
|
||||
operator=(const BaseConstVector &v)
|
||||
{
|
||||
len = v.len; s = v.s; data = v.data; return *this;
|
||||
}
|
||||
const double &
|
||||
operator[](int i) const
|
||||
{
|
||||
return data[s*i];
|
||||
}
|
||||
const double *
|
||||
base() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
int
|
||||
length() const
|
||||
{
|
||||
return len;
|
||||
}
|
||||
int
|
||||
skip() const
|
||||
{
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
class ConstGeneralMatrix;
|
||||
|
||||
class ConstVector : public BaseConstVector {
|
||||
class ConstVector : public BaseConstVector
|
||||
{
|
||||
public:
|
||||
ConstVector(const Vector& v) : BaseConstVector(v.length(), v.skip(), v.base()) {}
|
||||
ConstVector(const ConstVector& v) : BaseConstVector(v) {}
|
||||
ConstVector(const double* d, int l) : BaseConstVector(l, 1, d) {}
|
||||
ConstVector(const Vector& v, int off, int l);
|
||||
ConstVector(const ConstVector& v, int off, int l);
|
||||
ConstVector(const double* d, int skip, int l);
|
||||
ConstVector(const ConstGeneralMatrix& m, int col);
|
||||
ConstVector(int row, const ConstGeneralMatrix& m);
|
||||
|
||||
virtual ~ConstVector() {}
|
||||
/** Exact equality. */
|
||||
bool operator==(const ConstVector& y) const;
|
||||
bool operator!=(const ConstVector& y) const
|
||||
{return ! operator==(y);}
|
||||
/** Lexicographic ordering. */
|
||||
bool operator<(const ConstVector& y) const;
|
||||
bool operator<=(const ConstVector& y) const
|
||||
{return operator<(y) || operator==(y);}
|
||||
bool operator>(const ConstVector& y) const
|
||||
{return ! operator<=(y);}
|
||||
bool operator>=(const ConstVector& y) const
|
||||
{return ! operator<(y);}
|
||||
ConstVector(const Vector &v) : BaseConstVector(v.length(), v.skip(), v.base())
|
||||
{
|
||||
}
|
||||
ConstVector(const ConstVector &v) : BaseConstVector(v)
|
||||
{
|
||||
}
|
||||
ConstVector(const double *d, int l) : BaseConstVector(l, 1, d)
|
||||
{
|
||||
}
|
||||
ConstVector(const Vector &v, int off, int l);
|
||||
ConstVector(const ConstVector &v, int off, int l);
|
||||
ConstVector(const double *d, int skip, int l);
|
||||
ConstVector(const ConstGeneralMatrix &m, int col);
|
||||
ConstVector(int row, const ConstGeneralMatrix &m);
|
||||
|
||||
double getNorm() const;
|
||||
double getMax() const;
|
||||
double getNorm1() const;
|
||||
double dot(const ConstVector& y) const;
|
||||
bool isFinite() const;
|
||||
void print() const;
|
||||
virtual ~ConstVector()
|
||||
{
|
||||
}
|
||||
/** Exact equality. */
|
||||
bool operator==(const ConstVector &y) const;
|
||||
bool
|
||||
operator!=(const ConstVector &y) const
|
||||
{
|
||||
return !operator==(y);
|
||||
}
|
||||
/** Lexicographic ordering. */
|
||||
bool operator<(const ConstVector &y) const;
|
||||
bool
|
||||
operator<=(const ConstVector &y) const
|
||||
{
|
||||
return operator<(y) || operator==(y);
|
||||
}
|
||||
bool
|
||||
operator>(const ConstVector &y) const
|
||||
{
|
||||
return !operator<=(y);
|
||||
}
|
||||
bool
|
||||
operator>=(const ConstVector &y) const
|
||||
{
|
||||
return !operator<(y);
|
||||
}
|
||||
|
||||
double getNorm() const;
|
||||
double getMax() const;
|
||||
double getNorm1() const;
|
||||
double dot(const ConstVector &y) const;
|
||||
bool isFinite() const;
|
||||
void print() const;
|
||||
};
|
||||
|
||||
class ZeroPad {
|
||||
class ZeroPad
|
||||
{
|
||||
public:
|
||||
static const int length = 16;
|
||||
static const int length = 16;
|
||||
private:
|
||||
double pad[16];
|
||||
double pad[16];
|
||||
public:
|
||||
ZeroPad();
|
||||
const double* getBase() const {return pad;}
|
||||
ZeroPad();
|
||||
const double *
|
||||
getBase() const
|
||||
{
|
||||
return pad;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* VECTOR_H */
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
||||
|
|
|
@ -12,31 +12,58 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
class MMException : public MallocAllocator {
|
||||
string message;
|
||||
class MMException : public MallocAllocator
|
||||
{
|
||||
string message;
|
||||
public:
|
||||
MMException(string mes) : message(mes) {}
|
||||
MMException(const char* mes) : message(mes) {}
|
||||
const char* getMessage() const {return message.data();}
|
||||
MMException(string mes) : message(mes)
|
||||
{
|
||||
}
|
||||
MMException(const char *mes) : message(mes)
|
||||
{
|
||||
}
|
||||
const char *
|
||||
getMessage() const
|
||||
{
|
||||
return message.data();
|
||||
}
|
||||
};
|
||||
|
||||
class MMMatrixIn : public MallocAllocator {
|
||||
double* data;
|
||||
int rows;
|
||||
int cols;
|
||||
class MMMatrixIn : public MallocAllocator
|
||||
{
|
||||
double *data;
|
||||
int rows;
|
||||
int cols;
|
||||
public:
|
||||
MMMatrixIn(const char* fname);
|
||||
~MMMatrixIn();
|
||||
const double* getData() const {return data;}
|
||||
int size() const {return rows*cols;}
|
||||
int row() const {return rows;}
|
||||
int col() const {return cols;}
|
||||
MMMatrixIn(const char *fname);
|
||||
~MMMatrixIn();
|
||||
const double *
|
||||
getData() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
int
|
||||
size() const
|
||||
{
|
||||
return rows*cols;
|
||||
}
|
||||
int
|
||||
row() const
|
||||
{
|
||||
return rows;
|
||||
}
|
||||
int
|
||||
col() const
|
||||
{
|
||||
return cols;
|
||||
}
|
||||
};
|
||||
|
||||
class MMMatrixOut : public MallocAllocator {
|
||||
class MMMatrixOut : public MallocAllocator
|
||||
{
|
||||
public:
|
||||
static void write(const char* fname, int rows, int cols, const double* data);
|
||||
static void write(const char* fname, const GeneralMatrix& m);
|
||||
static void write(const char *fname, int rows, int cols, const double *data);
|
||||
static void write(const char *fname, const GeneralMatrix &m);
|
||||
};
|
||||
|
||||
#endif /* MM_MATRIX_H */
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* Copyright 2004, Ondra Kamenik */
|
||||
|
||||
#ifndef FACTORY_H
|
||||
#define FACTORY_H
|
||||
#define FACTORY_H
|
||||
|
||||
#include "symmetry.h"
|
||||
#include "int_sequence.h"
|
||||
|
@ -11,67 +11,78 @@
|
|||
#include "rfs_tensor.h"
|
||||
#include "t_container.h"
|
||||
|
||||
class Factory {
|
||||
void init(const Symmetry& s, const IntSequence& nvs);
|
||||
void init(int dim, int nv);
|
||||
void fillMatrix(TwoDMatrix& m) const;
|
||||
class Factory
|
||||
{
|
||||
void init(const Symmetry &s, const IntSequence &nvs);
|
||||
void init(int dim, int nv);
|
||||
void fillMatrix(TwoDMatrix &m) const;
|
||||
public:
|
||||
double get() const;
|
||||
// this can be used with UGSTensor, FGSTensor
|
||||
template <class _Ttype>
|
||||
_Ttype* make(int r, const Symmetry& s, const IntSequence& nvs)
|
||||
{
|
||||
_Ttype* res = new _Ttype(r, TensorDimens(s, nvs));
|
||||
init(s, nvs);
|
||||
fillMatrix(*res);
|
||||
return res;
|
||||
}
|
||||
double get() const;
|
||||
// this can be used with UGSTensor, FGSTensor
|
||||
template <class _Ttype>
|
||||
_Ttype *
|
||||
make(int r, const Symmetry &s, const IntSequence &nvs)
|
||||
{
|
||||
_Ttype *res = new _Ttype(r, TensorDimens(s, nvs));
|
||||
init(s, nvs);
|
||||
fillMatrix(*res);
|
||||
return res;
|
||||
}
|
||||
|
||||
// this can be used with FFSTensor, UFSTensor, FRTensor, URTensor
|
||||
template <class _Ttype>
|
||||
_Ttype* make(int r, int nv, int dim)
|
||||
{
|
||||
_Ttype* res = new _Ttype(r, nv, dim);
|
||||
init(dim, nv);
|
||||
fillMatrix(*res);
|
||||
return res;
|
||||
}
|
||||
// this can be used with FFSTensor, UFSTensor, FRTensor, URTensor
|
||||
template <class _Ttype>
|
||||
_Ttype *
|
||||
make(int r, int nv, int dim)
|
||||
{
|
||||
_Ttype *res = new _Ttype(r, nv, dim);
|
||||
init(dim, nv);
|
||||
fillMatrix(*res);
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class _Ttype, class _Ctype>
|
||||
_Ctype* makeCont(int r, const IntSequence& nvs, int maxdim)
|
||||
{
|
||||
int symnum = nvs.size();
|
||||
_Ctype* res = new _Ctype(symnum);
|
||||
for (int dim = 1; dim <= maxdim; dim++) {
|
||||
if (symnum == 1) {
|
||||
// full symmetry
|
||||
Symmetry sym(dim);
|
||||
_Ttype* t = make<_Ttype>(r, sym, nvs);
|
||||
res->insert(t);
|
||||
} else {
|
||||
// general symmetry
|
||||
for (int i = 0; i <= dim; i++) {
|
||||
Symmetry sym(i, dim-i);
|
||||
_Ttype* t = make<_Ttype>(r, sym, nvs);
|
||||
res->insert(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
template <class _Ttype, class _Ctype>
|
||||
_Ctype *
|
||||
makeCont(int r, const IntSequence &nvs, int maxdim)
|
||||
{
|
||||
int symnum = nvs.size();
|
||||
_Ctype *res = new _Ctype(symnum);
|
||||
for (int dim = 1; dim <= maxdim; dim++)
|
||||
{
|
||||
if (symnum == 1)
|
||||
{
|
||||
// full symmetry
|
||||
Symmetry sym(dim);
|
||||
_Ttype *t = make<_Ttype>(r, sym, nvs);
|
||||
res->insert(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
// general symmetry
|
||||
for (int i = 0; i <= dim; i++)
|
||||
{
|
||||
Symmetry sym(i, dim-i);
|
||||
_Ttype *t = make<_Ttype>(r, sym, nvs);
|
||||
res->insert(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class _Ttype, class _Ptype>
|
||||
_Ptype* makePoly(int r, int nv, int maxdim)
|
||||
{
|
||||
_Ptype* p = new _Ptype(r, nv);
|
||||
for (int d = 1; d <= maxdim; d++) {
|
||||
_Ttype* t = make<_Ttype>(r, nv, d);
|
||||
p->insert(t);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
template <class _Ttype, class _Ptype>
|
||||
_Ptype *
|
||||
makePoly(int r, int nv, int maxdim)
|
||||
{
|
||||
_Ptype *p = new _Ptype(r, nv);
|
||||
for (int d = 1; d <= maxdim; d++)
|
||||
{
|
||||
_Ttype *t = make<_Ttype>(r, nv, d);
|
||||
p->insert(t);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
Vector* makeVector(int n);
|
||||
Vector *makeVector(int n);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,115 +10,121 @@
|
|||
#include "sparse_tensor.h"
|
||||
#include "Vector.h"
|
||||
|
||||
class IntGenerator {
|
||||
int maxim;
|
||||
double probab;
|
||||
class IntGenerator
|
||||
{
|
||||
int maxim;
|
||||
double probab;
|
||||
public:
|
||||
IntGenerator()
|
||||
: maxim(5), probab(0.3) {}
|
||||
void init(int nf, int ny, int nv, int nw, int nu, int mx, double prob);
|
||||
int get() const;
|
||||
IntGenerator()
|
||||
: maxim(5), probab(0.3)
|
||||
{
|
||||
}
|
||||
void init(int nf, int ny, int nv, int nw, int nu, int mx, double prob);
|
||||
int get() const;
|
||||
};
|
||||
|
||||
extern IntGenerator intgen;
|
||||
|
||||
|
||||
class Monom : public IntSequence {
|
||||
class Monom : public IntSequence
|
||||
{
|
||||
public:
|
||||
Monom(int len); // generate a random monom
|
||||
Monom(int len, int item); // generate monom whose items are the given item
|
||||
double deriv(const IntSequence& vars) const;
|
||||
// this = this*m^ex (in monomial sense)
|
||||
void multiplyWith(int ex, const Monom& m);
|
||||
void print() const;
|
||||
Monom(int len); // generate a random monom
|
||||
Monom(int len, int item); // generate monom whose items are the given item
|
||||
double deriv(const IntSequence &vars) const;
|
||||
// this = this*m^ex (in monomial sense)
|
||||
void multiplyWith(int ex, const Monom &m);
|
||||
void print() const;
|
||||
};
|
||||
|
||||
class Monom2Vector;
|
||||
class Monom1Vector {
|
||||
friend class Monom2Vector;
|
||||
int nx;
|
||||
int len;
|
||||
Monom** const x;
|
||||
class Monom1Vector
|
||||
{
|
||||
friend class Monom2Vector;
|
||||
int nx;
|
||||
int len;
|
||||
Monom **const x;
|
||||
public:
|
||||
Monom1Vector(int nxx, int l);
|
||||
~Monom1Vector();
|
||||
void deriv(const IntSequence& c, Vector& out) const;
|
||||
FGSTensor* deriv(int dim) const;
|
||||
void print() const;
|
||||
Monom1Vector(int nxx, int l);
|
||||
~Monom1Vector();
|
||||
void deriv(const IntSequence &c, Vector &out) const;
|
||||
FGSTensor *deriv(int dim) const;
|
||||
void print() const;
|
||||
};
|
||||
|
||||
//class Monom3Vector;
|
||||
class Monom2Vector {
|
||||
int ny;
|
||||
int nu;
|
||||
int len;
|
||||
Monom** const y;
|
||||
Monom** const u;
|
||||
class Monom2Vector
|
||||
{
|
||||
int ny;
|
||||
int nu;
|
||||
int len;
|
||||
Monom **const y;
|
||||
Monom **const u;
|
||||
public:
|
||||
// generate random vector of monom two vector
|
||||
Monom2Vector(int nyy, int nuu, int l);
|
||||
// calculate g(x(y,u))
|
||||
Monom2Vector(const Monom1Vector& g, const Monom2Vector& xmon);
|
||||
~Monom2Vector();
|
||||
void deriv(const Symmetry& s, const IntSequence& c, Vector& out) const;
|
||||
FGSTensor* deriv(const Symmetry& s) const;
|
||||
FGSContainer* deriv(int maxdim) const;
|
||||
void print() const;
|
||||
// generate random vector of monom two vector
|
||||
Monom2Vector(int nyy, int nuu, int l);
|
||||
// calculate g(x(y,u))
|
||||
Monom2Vector(const Monom1Vector &g, const Monom2Vector &xmon);
|
||||
~Monom2Vector();
|
||||
void deriv(const Symmetry &s, const IntSequence &c, Vector &out) const;
|
||||
FGSTensor *deriv(const Symmetry &s) const;
|
||||
FGSContainer *deriv(int maxdim) const;
|
||||
void print() const;
|
||||
};
|
||||
|
||||
class Monom4Vector {
|
||||
int len;
|
||||
int nx1;
|
||||
int nx2;
|
||||
int nx3;
|
||||
int nx4;
|
||||
Monom** const x1;
|
||||
Monom** const x2;
|
||||
Monom** const x3;
|
||||
Monom** const x4;
|
||||
class Monom4Vector
|
||||
{
|
||||
int len;
|
||||
int nx1;
|
||||
int nx2;
|
||||
int nx3;
|
||||
int nx4;
|
||||
Monom **const x1;
|
||||
Monom **const x2;
|
||||
Monom **const x3;
|
||||
Monom **const x4;
|
||||
public:
|
||||
/* random for g(y,u,sigma) */
|
||||
Monom4Vector(int l, int ny, int nu);
|
||||
/* random for G(y,u,u',sigma) */
|
||||
Monom4Vector(int l, int ny, int nu, int nup);
|
||||
/* random for f(y+,y,y-,u) */
|
||||
Monom4Vector(int l, int nbigg, int ng, int ny, int nu);
|
||||
/* substitution f(G(y,u,u',sigma),g(y,u,sigma),y,u) */
|
||||
Monom4Vector(const Monom4Vector& f, const Monom4Vector& bigg,
|
||||
const Monom4Vector& g);
|
||||
~Monom4Vector();
|
||||
FSSparseTensor* deriv(int dim) const;
|
||||
FGSTensor* deriv(const Symmetry& s) const;
|
||||
void deriv(const Symmetry& s, const IntSequence& coor, Vector& out) const;
|
||||
void print() const;
|
||||
/* random for g(y,u,sigma) */
|
||||
Monom4Vector(int l, int ny, int nu);
|
||||
/* random for G(y,u,u',sigma) */
|
||||
Monom4Vector(int l, int ny, int nu, int nup);
|
||||
/* random for f(y+,y,y-,u) */
|
||||
Monom4Vector(int l, int nbigg, int ng, int ny, int nu);
|
||||
/* substitution f(G(y,u,u',sigma),g(y,u,sigma),y,u) */
|
||||
Monom4Vector(const Monom4Vector &f, const Monom4Vector &bigg,
|
||||
const Monom4Vector &g);
|
||||
~Monom4Vector();
|
||||
FSSparseTensor *deriv(int dim) const;
|
||||
FGSTensor *deriv(const Symmetry &s) const;
|
||||
void deriv(const Symmetry &s, const IntSequence &coor, Vector &out) const;
|
||||
void print() const;
|
||||
protected:
|
||||
void init_random();
|
||||
void init_random();
|
||||
};
|
||||
|
||||
|
||||
struct SparseDerivGenerator {
|
||||
int maxdimen;
|
||||
FGSContainer* bigg;
|
||||
FGSContainer* g;
|
||||
FGSContainer* rcont;
|
||||
FSSparseTensor** const ts;
|
||||
SparseDerivGenerator(int nf, int ny, int nu, int nup, int nbigg, int ng,
|
||||
int mx, double prob, int maxdim);
|
||||
~SparseDerivGenerator();
|
||||
struct SparseDerivGenerator
|
||||
{
|
||||
int maxdimen;
|
||||
FGSContainer *bigg;
|
||||
FGSContainer *g;
|
||||
FGSContainer *rcont;
|
||||
FSSparseTensor **const ts;
|
||||
SparseDerivGenerator(int nf, int ny, int nu, int nup, int nbigg, int ng,
|
||||
int mx, double prob, int maxdim);
|
||||
~SparseDerivGenerator();
|
||||
};
|
||||
|
||||
|
||||
struct DenseDerivGenerator {
|
||||
int maxdimen;
|
||||
FGSContainer* xcont;
|
||||
FGSContainer* rcont;
|
||||
FGSTensor** const ts;
|
||||
UGSContainer* uxcont;
|
||||
UGSTensor** const uts;
|
||||
DenseDerivGenerator(int ng, int nx, int ny, int nu,
|
||||
int mx, double prob, int maxdim);
|
||||
void unfold();
|
||||
~DenseDerivGenerator();
|
||||
struct DenseDerivGenerator
|
||||
{
|
||||
int maxdimen;
|
||||
FGSContainer *xcont;
|
||||
FGSContainer *rcont;
|
||||
FGSTensor **const ts;
|
||||
UGSContainer *uxcont;
|
||||
UGSTensor **const uts;
|
||||
DenseDerivGenerator(int ng, int nx, int ny, int nu,
|
||||
int mx, double prob, int maxdim);
|
||||
void unfold();
|
||||
~DenseDerivGenerator();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,41 +11,54 @@
|
|||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
namespace ogu {
|
||||
namespace ogu
|
||||
{
|
||||
|
||||
/** A primitive exception. */
|
||||
class Exception {
|
||||
static const int file_length = 100;
|
||||
static const int mes_length = 500;
|
||||
protected:
|
||||
char file[file_length];
|
||||
int line;
|
||||
char mes[mes_length];
|
||||
public:
|
||||
Exception(const char* f, int l, const char* m)
|
||||
{
|
||||
strncpy(file, f, file_length-1);
|
||||
file[file_length-1] = '\0';
|
||||
line = l;
|
||||
strncpy(mes, m, std::min(mes_length-1,(int)strlen(m)));
|
||||
mes[mes_length-1] = '\0';
|
||||
}
|
||||
Exception(const char* f, int l, const std::string& m)
|
||||
{
|
||||
strncpy(file, f, file_length-1);
|
||||
file[file_length-1] = '\0';
|
||||
line = l;
|
||||
strncpy(mes, m.c_str(), std::min(mes_length-1,(int)m.length()));
|
||||
mes[mes_length-1] = '\0';
|
||||
}
|
||||
virtual ~Exception() {}
|
||||
void print(FILE* fd) const
|
||||
{ fprintf(fd, "%s:%d: %s\n", file, line, mes); }
|
||||
void print() const
|
||||
{ print(stdout); }
|
||||
const char* message() const
|
||||
{ return mes; }
|
||||
};
|
||||
/** A primitive exception. */
|
||||
class Exception
|
||||
{
|
||||
static const int file_length = 100;
|
||||
static const int mes_length = 500;
|
||||
protected:
|
||||
char file[file_length];
|
||||
int line;
|
||||
char mes[mes_length];
|
||||
public:
|
||||
Exception(const char *f, int l, const char *m)
|
||||
{
|
||||
strncpy(file, f, file_length-1);
|
||||
file[file_length-1] = '\0';
|
||||
line = l;
|
||||
strncpy(mes, m, std::min(mes_length-1, (int) strlen(m)));
|
||||
mes[mes_length-1] = '\0';
|
||||
}
|
||||
Exception(const char *f, int l, const std::string &m)
|
||||
{
|
||||
strncpy(file, f, file_length-1);
|
||||
file[file_length-1] = '\0';
|
||||
line = l;
|
||||
strncpy(mes, m.c_str(), std::min(mes_length-1, (int) m.length()));
|
||||
mes[mes_length-1] = '\0';
|
||||
}
|
||||
virtual ~Exception()
|
||||
{
|
||||
}
|
||||
void
|
||||
print(FILE *fd) const
|
||||
{
|
||||
fprintf(fd, "%s:%d: %s\n", file, line, mes);
|
||||
}
|
||||
void
|
||||
print() const
|
||||
{
|
||||
print(stdout);
|
||||
}
|
||||
const char *
|
||||
message() const
|
||||
{
|
||||
return mes;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,51 +5,69 @@
|
|||
#ifndef OGU_MEMORY_FILE
|
||||
#define OGU_MEMORY_FILE
|
||||
|
||||
namespace ogu {
|
||||
/** This function calculates an offset of a given position in a
|
||||
* given string. The position is given by the line number and by
|
||||
* the offset in the line (both starting from 1). */
|
||||
int calc_pos_offset(int length, const char* str, int line, int col);
|
||||
/** This function calculates a line number and column number of a
|
||||
* character given by the offset in the string. It is inverse to
|
||||
* calc_pos_offset. */
|
||||
void calc_pos_line_and_col(int length, const char* str, int offset,
|
||||
int& line, int& col);
|
||||
namespace ogu
|
||||
{
|
||||
/** This function calculates an offset of a given position in a
|
||||
* given string. The position is given by the line number and by
|
||||
* the offset in the line (both starting from 1). */
|
||||
int calc_pos_offset(int length, const char *str, int line, int col);
|
||||
/** This function calculates a line number and column number of a
|
||||
* character given by the offset in the string. It is inverse to
|
||||
* calc_pos_offset. */
|
||||
void calc_pos_line_and_col(int length, const char *str, int offset,
|
||||
int &line, int &col);
|
||||
|
||||
/** This class opens a given file and makes its copy in memory and
|
||||
* appends it with the '\0' character. Since the type of length is
|
||||
* int, it can store files with size at most 4GB. If the file
|
||||
* could be opened for reading, data is NULL and length is -1. If
|
||||
* the file is empty but exists, len is zero and data points to a
|
||||
* newly allocated memory containing '\0' character at the end. */
|
||||
class MemoryFile {
|
||||
protected:
|
||||
int len;
|
||||
char* data;
|
||||
public:
|
||||
MemoryFile(const char* fname);
|
||||
virtual ~MemoryFile()
|
||||
{if (data) delete [] data;}
|
||||
int length() const
|
||||
{return len;}
|
||||
const char* base() const
|
||||
{return data;}
|
||||
bool exists() const
|
||||
{return len != -1;}
|
||||
/** Return the offset of a character in the given line
|
||||
* (starting from 1) with the given offset in the line. */
|
||||
int offset(int line, int lineoff) const
|
||||
{return calc_pos_offset(len, data, line, lineoff);}
|
||||
/** Return the line number and column number of the character
|
||||
* defined by the offset. */
|
||||
void line_and_col(int offset, int& line, int& col) const
|
||||
{calc_pos_line_and_col(len, data, offset, line, col);}
|
||||
};
|
||||
/** This class opens a given file and makes its copy in memory and
|
||||
* appends it with the '\0' character. Since the type of length is
|
||||
* int, it can store files with size at most 4GB. If the file
|
||||
* could be opened for reading, data is NULL and length is -1. If
|
||||
* the file is empty but exists, len is zero and data points to a
|
||||
* newly allocated memory containing '\0' character at the end. */
|
||||
class MemoryFile
|
||||
{
|
||||
protected:
|
||||
int len;
|
||||
char *data;
|
||||
public:
|
||||
MemoryFile(const char *fname);
|
||||
virtual ~MemoryFile()
|
||||
{
|
||||
if (data)
|
||||
delete [] data;
|
||||
}
|
||||
int
|
||||
length() const
|
||||
{
|
||||
return len;
|
||||
}
|
||||
const char *
|
||||
base() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
bool
|
||||
exists() const
|
||||
{
|
||||
return len != -1;
|
||||
}
|
||||
/** Return the offset of a character in the given line
|
||||
* (starting from 1) with the given offset in the line. */
|
||||
int
|
||||
offset(int line, int lineoff) const
|
||||
{
|
||||
return calc_pos_offset(len, data, line, lineoff);
|
||||
}
|
||||
/** Return the line number and column number of the character
|
||||
* defined by the offset. */
|
||||
void
|
||||
line_and_col(int offset, int &line, int &col) const
|
||||
{
|
||||
calc_pos_line_and_col(len, data, offset, line, col);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -7,43 +7,54 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
namespace ogu {
|
||||
namespace ogu
|
||||
{
|
||||
|
||||
using std::vector;
|
||||
using std::vector;
|
||||
|
||||
class PascalRow : public vector<int> {
|
||||
int k;
|
||||
public:
|
||||
PascalRow()
|
||||
: vector<int>(), k(1)
|
||||
{ push_back(2); }
|
||||
void setFromPrevious(const PascalRow& prev);
|
||||
void prolong(const PascalRow& prev);
|
||||
void prolongFirst(int n);
|
||||
void print() const;
|
||||
};
|
||||
class PascalRow : public vector<int>
|
||||
{
|
||||
int k;
|
||||
public:
|
||||
PascalRow()
|
||||
: vector<int>(), k(1)
|
||||
{
|
||||
push_back(2);
|
||||
}
|
||||
void setFromPrevious(const PascalRow &prev);
|
||||
void prolong(const PascalRow &prev);
|
||||
void prolongFirst(int n);
|
||||
void print() const;
|
||||
};
|
||||
|
||||
class PascalTriangle {
|
||||
vector<PascalRow> tr;
|
||||
public:
|
||||
PascalTriangle()
|
||||
{tr.push_back(PascalRow());}
|
||||
PascalTriangle(const PascalTriangle& triang)
|
||||
: tr(triang.tr) {}
|
||||
const PascalTriangle& operator=(const PascalTriangle& triang)
|
||||
{ tr = triang.tr; return *this;}
|
||||
int noverk(int n, int k);
|
||||
void print() const;
|
||||
protected:
|
||||
void ensure(int n, int k);
|
||||
int max_n() const;
|
||||
int max_k() const;
|
||||
};
|
||||
class PascalTriangle
|
||||
{
|
||||
vector<PascalRow> tr;
|
||||
public:
|
||||
PascalTriangle()
|
||||
{
|
||||
tr.push_back(PascalRow());
|
||||
}
|
||||
PascalTriangle(const PascalTriangle &triang)
|
||||
: tr(triang.tr)
|
||||
{
|
||||
}
|
||||
const PascalTriangle &
|
||||
operator=(const PascalTriangle &triang)
|
||||
{
|
||||
tr = triang.tr; return *this;
|
||||
}
|
||||
int noverk(int n, int k);
|
||||
void print() const;
|
||||
protected:
|
||||
void ensure(int n, int k);
|
||||
int max_n() const;
|
||||
int max_k() const;
|
||||
};
|
||||
};
|
||||
|
||||
extern ogu::PascalTriangle ptriang;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -205,7 +205,7 @@ License: permissive
|
|||
Unlimited permission is granted to everyone to use, copy, modify or
|
||||
distribute this software.
|
||||
|
||||
Files: matlab/utilities\graphics\distinguishable_colors.m
|
||||
Files: matlab/utilities/graphics/distinguishable_colors.m
|
||||
Copyright 2010-2011 by Timothy E. Holy
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
@ -228,7 +228,7 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Files: matlab/utilities\graphics\colorspace.m
|
||||
Files: matlab/utilities/graphics/colorspace.m
|
||||
Pascal Getreuer 2005-2010
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
function display(t)
|
||||
|
||||
% Copyright (C) 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
fprintf('%s = <dynTimeIndex: %s>\n', inputname(1), int2str(t.index));
|
|
@ -1,61 +0,0 @@
|
|||
function t = dynTimeIndex() % --*-- Unitary tests --*--
|
||||
|
||||
% t = dynTimeIndex()
|
||||
%
|
||||
% Constructor for the dynTimeIndex class.
|
||||
%
|
||||
% INPUTS:
|
||||
% None.
|
||||
%
|
||||
% OUTPUTS:
|
||||
% * t, dynTimeIndex object.
|
||||
%
|
||||
% DESCRIPTION:
|
||||
% The dynTimeIndex object is used to shift backward or forward dseries objects. For instance, if ts
|
||||
% is a dseries object and t is a dynTimeIndex object then the following expressions are equivalent:
|
||||
%
|
||||
% us = ts.lag()
|
||||
% us = ts.lag(1)
|
||||
% us = lag(ts,1)
|
||||
% us = ts(t-1)
|
||||
%
|
||||
% This class has only one member: t = int8(0) when instantiated.
|
||||
|
||||
% Copyright (C) 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
t = struct();
|
||||
|
||||
t.index = int8(0);
|
||||
|
||||
t = class(t,'dynTimeIndex');
|
||||
|
||||
%@test:1
|
||||
%$ % Instantiate a dynTimeIndex object
|
||||
%$ try
|
||||
%$ u = dynTimeIndex();
|
||||
%$ t(1) = 1;
|
||||
%$ catch
|
||||
%$ t(1) = 0;
|
||||
%$ end
|
||||
%$
|
||||
%$ if t(1)
|
||||
%$ t(2) = isa(u,'dynTimeIndex');
|
||||
%$ end
|
||||
%$
|
||||
%$ T = all(t);
|
||||
%@eof:1
|
|
@ -1,62 +0,0 @@
|
|||
function C = minus(A,B) % --*-- Unitary tests --*--
|
||||
|
||||
% C = minus(A,B)
|
||||
%
|
||||
% Overloads binary minus operator.
|
||||
%
|
||||
% INPUTS:
|
||||
% * A, dynTimeIndex object.
|
||||
% * B, integer scalar.
|
||||
%
|
||||
% OUTPUTS:
|
||||
% * C, dynTimeIndex object.
|
||||
%
|
||||
% EXAMPLE:
|
||||
%
|
||||
% >> t = dynTimeIndex();
|
||||
% >> t.index
|
||||
%
|
||||
% ans =
|
||||
%
|
||||
% 0
|
||||
%
|
||||
% >> s = t-1;
|
||||
% >> s.index
|
||||
%
|
||||
% ans =
|
||||
%
|
||||
% -1
|
||||
%
|
||||
|
||||
% Copyright (C) 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
if ~(isa(A,'dynTimeIndex') || isint(B))
|
||||
error(['dynTimeIndex::plus: Input arguments ''' inputname(1) ''' and ''' inputname(2) ''' must be a dynTimeIndex object and an integer!'])
|
||||
end
|
||||
|
||||
C = struct();
|
||||
C.index = A.index-B;
|
||||
C = class(C,'dynTimeIndex');
|
||||
|
||||
%@test:1
|
||||
%$ a = dynTimeIndex();
|
||||
%$ b = a-1;
|
||||
%$ t(1) = isa(b,'dynTimeIndex');
|
||||
%$ t(2) = isequal(b.index,-int8(1));
|
||||
%$ T = all(t);
|
||||
%@eof:1
|
|
@ -1,74 +0,0 @@
|
|||
function C = mpower(A,B) % --*-- Unitary tests --*--
|
||||
|
||||
% C = mpower(A,B)
|
||||
%
|
||||
% Overloads binary mpower operator (^).
|
||||
%
|
||||
% INPUTS :
|
||||
% * A, dynTimeIndex object.
|
||||
% * B, integer scalar.
|
||||
%
|
||||
% OUTPUTS :
|
||||
% * C, dynTimeIndex object.
|
||||
%
|
||||
% EXAMPLE 1 :
|
||||
%
|
||||
% >> B = dynTimeIndex()-1;
|
||||
% >> B
|
||||
% B = <dynTimeIndex: -1>
|
||||
% >> B^4
|
||||
% ans = <dynTimeIndex: -4>
|
||||
% >>
|
||||
%
|
||||
% EXAMPLE 2 :
|
||||
% This method can be used to apply the lead and lag methods an arbitrary number of times to a dseries object. For instance, if
|
||||
% ts is a dseries object, and if we define
|
||||
%
|
||||
% >> B = dynTimeIndex()-1;
|
||||
% >> F = dynTimeIndex()+1;
|
||||
%
|
||||
% B and F can be used as lag and lead operators and the following syntax:
|
||||
%
|
||||
% >> us = ts(F^2);
|
||||
%
|
||||
% is equivalent to
|
||||
%
|
||||
% >> us = ts.lead(2)
|
||||
%
|
||||
% or
|
||||
%
|
||||
% >> us = ts.lead.lead
|
||||
%
|
||||
|
||||
% Copyright (C) 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
if ~(isa(A,'dynTimeIndex') || isint(B))
|
||||
error(['dynTimeIndex::mpower: Input arguments ''' inputname(1) ''' and ''' inputname(2) ''' must be a dynTimeIndex object and an integer!'])
|
||||
end
|
||||
|
||||
C = struct();
|
||||
C.index = A.index*B;
|
||||
C = class(C,'dynTimeIndex');
|
||||
|
||||
%@test:1
|
||||
%$ a = dynTimeIndex()+1;
|
||||
%$ b = a^2;
|
||||
%$ t(1) = isa(b,'dynTimeIndex');
|
||||
%$ t(2) = isequal(b.index,int8(2));
|
||||
%$ T = all(t);
|
||||
%@eof:1
|
|
@ -1,62 +0,0 @@
|
|||
function C = plus(A,B) % --*-- Unitary tests --*--
|
||||
|
||||
% C = plus(A,B)
|
||||
%
|
||||
% Overloads binary plus operator.
|
||||
%
|
||||
% INPUTS:
|
||||
% * A, dynTimeIndex object.
|
||||
% * B, integer scalar.
|
||||
%
|
||||
% OUTPUTS:
|
||||
% * C, dynTimeIndex object.
|
||||
%
|
||||
% EXAMPLE:
|
||||
%
|
||||
% >> t = dynTimeIndex();
|
||||
% >> t.index
|
||||
%
|
||||
% ans =
|
||||
%
|
||||
% 0
|
||||
%
|
||||
% >> s = t+1;
|
||||
% >> s.index
|
||||
%
|
||||
% ans =
|
||||
%
|
||||
% 1
|
||||
%
|
||||
|
||||
% Copyright (C) 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
if ~(isa(A,'dynTimeIndex') || isint(B))
|
||||
error(['dynTimeIndex::plus: Input arguments ''' inputname(1) ''' and ''' inputname(2) ''' must be a dynTimeIndex object and an integer!'])
|
||||
end
|
||||
|
||||
C = struct();
|
||||
C.index = A.index+B;
|
||||
C = class(C,'dynTimeIndex');
|
||||
|
||||
%@test:1
|
||||
%$ a = dynTimeIndex();
|
||||
%$ b = a+1;
|
||||
%$ t(1) = isa(b,'dynTimeIndex');
|
||||
%$ t(2) = isequal(b.index,int8(1));
|
||||
%$ T = all(t);
|
||||
%@eof:1
|
|
@ -1,20 +0,0 @@
|
|||
function val = subsasgn(val, idx, rhs)
|
||||
|
||||
% Copyright (C) 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
error('dynTimeIndex::subsasgn: Members of dynTimeIndex class are private!')
|
|
@ -1,54 +0,0 @@
|
|||
function B = subsref(A,S) % --*-- Unitary tests --*--
|
||||
|
||||
% B = subsref(A,S)
|
||||
%
|
||||
% Overloads the subsref method for dynTimeIndex class. This method only allows to get
|
||||
% the value of the field `index`.
|
||||
|
||||
% Copyright (C) 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
if length(S)>1
|
||||
error('dynTimeIndex::subsref: Something is wrong in your syntax!')
|
||||
end
|
||||
|
||||
if isequal(S.type,'.')
|
||||
if isequal(S.subs,'index')
|
||||
B = builtin('subsref', A, S(1));
|
||||
else
|
||||
error(['dynTimeIndex::subsref: ' S.subs ' is not a known member!'])
|
||||
end
|
||||
else
|
||||
error('dynTimeIndex::subsref: Something is wrong in your syntax!')
|
||||
end
|
||||
|
||||
%@test:1
|
||||
%$ % Instantiate a dynTimeIndex object
|
||||
%$ u = dynTimeIndex();
|
||||
%$ try
|
||||
%$ v = u.index;
|
||||
%$ t(1) = 1;
|
||||
%$ catch
|
||||
%$ t(1) = 0;
|
||||
%$ end
|
||||
%$
|
||||
%$ if t(1)
|
||||
%$ t(2) = isequal(v,int8(0));
|
||||
%$ end
|
||||
%$
|
||||
%$ T = all(t);
|
||||
%@eof:1
|
|
@ -8,7 +8,7 @@ function [AHess, DLIK, LIK] = AHessian(T,R,Q,H,P,Y,DT,DYss,DOm,DH,DP,start,mf,ka
|
|||
% NOTE: the derivative matrices (DT,DR ...) are 3-dim. arrays with last
|
||||
% dimension equal to the number of structural parameters
|
||||
|
||||
% Copyright (C) 2011-2016 Dynare Team
|
||||
% Copyright (C) 2011-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -26,123 +26,123 @@ function [AHess, DLIK, LIK] = AHessian(T,R,Q,H,P,Y,DT,DYss,DOm,DH,DP,start,mf,ka
|
|||
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
k = size(DT,3); % number of structural parameters
|
||||
smpl = size(Y,2); % Sample size.
|
||||
pp = size(Y,1); % Maximum number of observed variables.
|
||||
mm = size(T,2); % Number of state variables.
|
||||
a = zeros(mm,1); % State vector.
|
||||
Om = R*Q*transpose(R); % Variance of R times the vector of structural innovations.
|
||||
t = 0; % Initialization of the time index.
|
||||
oldK = 0;
|
||||
notsteady = 1; % Steady state flag.
|
||||
F_singular = 1;
|
||||
k = size(DT,3); % number of structural parameters
|
||||
smpl = size(Y,2); % Sample size.
|
||||
pp = size(Y,1); % Maximum number of observed variables.
|
||||
mm = size(T,2); % Number of state variables.
|
||||
a = zeros(mm,1); % State vector.
|
||||
Om = R*Q*transpose(R); % Variance of R times the vector of structural innovations.
|
||||
t = 0; % Initialization of the time index.
|
||||
oldK = 0;
|
||||
notsteady = 1; % Steady state flag.
|
||||
F_singular = 1;
|
||||
|
||||
lik = zeros(smpl,1); % Initialization of the vector gathering the densities.
|
||||
LIK = Inf; % Default value of the log likelihood.
|
||||
if nargout > 1,
|
||||
if nargout > 1
|
||||
DLIK = zeros(k,1); % Initialization of the score.
|
||||
end
|
||||
AHess = zeros(k,k); % Initialization of the Hessian
|
||||
Da = zeros(mm,k); % State vector.
|
||||
Dv = zeros(length(mf),k);
|
||||
|
||||
AHess = zeros(k,k); % Initialization of the Hessian
|
||||
Da = zeros(mm,k); % State vector.
|
||||
Dv = zeros(length(mf),k);
|
||||
|
||||
% for ii = 1:k
|
||||
% DOm = DR(:,:,ii)*Q*transpose(R) + R*DQ(:,:,ii)*transpose(R) + R*Q*transpose(DR(:,:,ii));
|
||||
% DOm = DR(:,:,ii)*Q*transpose(R) + R*DQ(:,:,ii)*transpose(R) + R*Q*transpose(DR(:,:,ii));
|
||||
% end
|
||||
|
||||
while notsteady && t<smpl
|
||||
t = t+1;
|
||||
v = Y(:,t)-a(mf);
|
||||
F = P(mf,mf) + H;
|
||||
if rcond(F) < kalman_tol
|
||||
if ~all(abs(F(:))<kalman_tol)
|
||||
return
|
||||
else
|
||||
a = T*a;
|
||||
P = T*P*transpose(T)+Om;
|
||||
end
|
||||
|
||||
while notsteady && t<smpl
|
||||
t = t+1;
|
||||
v = Y(:,t)-a(mf);
|
||||
F = P(mf,mf) + H;
|
||||
if rcond(F) < kalman_tol
|
||||
if ~all(abs(F(:))<kalman_tol)
|
||||
return
|
||||
else
|
||||
F_singular = 0;
|
||||
iF = inv(F);
|
||||
K = P(:,mf)*iF;
|
||||
lik(t) = log(det(F))+transpose(v)*iF*v;
|
||||
|
||||
[DK,DF,DP1] = computeDKalman(T,DT,DOm,P,DP,DH,mf,iF,K);
|
||||
|
||||
for ii = 1:k
|
||||
Dv(:,ii) = -Da(mf,ii) - DYss(mf,ii);
|
||||
Da(:,ii) = DT(:,:,ii)*(a+K*v) + T*(Da(:,ii)+DK(:,:,ii)*v + K*Dv(:,ii));
|
||||
if t>=start && nargout > 1
|
||||
DLIK(ii,1) = DLIK(ii,1) + trace( iF*DF(:,:,ii) ) + 2*Dv(:,ii)'*iF*v - v'*(iF*DF(:,:,ii)*iF)*v;
|
||||
end
|
||||
end
|
||||
vecDPmf = reshape(DP(mf,mf,:),[],k);
|
||||
% iPmf = inv(P(mf,mf));
|
||||
if t>=start
|
||||
AHess = AHess + Dv'*iF*Dv + .5*(vecDPmf' * kron(iF,iF) * vecDPmf);
|
||||
end
|
||||
a = T*(a+K*v);
|
||||
P = T*(P-K*P(mf,:))*transpose(T)+Om;
|
||||
DP = DP1;
|
||||
a = T*a;
|
||||
P = T*P*transpose(T)+Om;
|
||||
end
|
||||
notsteady = max(max(abs(K-oldK))) > riccati_tol;
|
||||
oldK = K;
|
||||
end
|
||||
else
|
||||
F_singular = 0;
|
||||
iF = inv(F);
|
||||
K = P(:,mf)*iF;
|
||||
lik(t) = log(det(F))+transpose(v)*iF*v;
|
||||
|
||||
if F_singular
|
||||
error('The variance of the forecast error remains singular until the end of the sample')
|
||||
end
|
||||
[DK,DF,DP1] = computeDKalman(T,DT,DOm,P,DP,DH,mf,iF,K);
|
||||
|
||||
|
||||
if t < smpl
|
||||
t0 = t+1;
|
||||
while t < smpl
|
||||
t = t+1;
|
||||
v = Y(:,t)-a(mf);
|
||||
for ii = 1:k
|
||||
Dv(:,ii) = -Da(mf,ii)-DYss(mf,ii);
|
||||
Da(:,ii) = DT(:,:,ii)*(a+K*v) + T*(Da(:,ii)+DK(:,:,ii)*v + K*Dv(:,ii));
|
||||
if t>=start && nargout >1
|
||||
DLIK(ii,1) = DLIK(ii,1) + trace( iF*DF(:,:,ii) ) + 2*Dv(:,ii)'*iF*v - v'*(iF*DF(:,:,ii)*iF)*v;
|
||||
end
|
||||
end
|
||||
if t>=start
|
||||
AHess = AHess + Dv'*iF*Dv;
|
||||
end
|
||||
a = T*(a+K*v);
|
||||
lik(t) = transpose(v)*iF*v;
|
||||
end
|
||||
AHess = AHess + .5*(smpl-t0+1)*(vecDPmf' * kron(iF,iF) * vecDPmf);
|
||||
if nargout > 1
|
||||
for ii = 1:k
|
||||
% DLIK(ii,1) = DLIK(ii,1) + (smpl-t0+1)*trace( iF*DF(:,:,ii) );
|
||||
Dv(:,ii) = -Da(mf,ii) - DYss(mf,ii);
|
||||
Da(:,ii) = DT(:,:,ii)*(a+K*v) + T*(Da(:,ii)+DK(:,:,ii)*v + K*Dv(:,ii));
|
||||
if t>=start && nargout > 1
|
||||
DLIK(ii,1) = DLIK(ii,1) + trace( iF*DF(:,:,ii) ) + 2*Dv(:,ii)'*iF*v - v'*(iF*DF(:,:,ii)*iF)*v;
|
||||
end
|
||||
end
|
||||
vecDPmf = reshape(DP(mf,mf,:),[],k);
|
||||
% iPmf = inv(P(mf,mf));
|
||||
if t>=start
|
||||
AHess = AHess + Dv'*iF*Dv + .5*(vecDPmf' * kron(iF,iF) * vecDPmf);
|
||||
end
|
||||
lik(t0:smpl) = lik(t0:smpl) + log(det(F));
|
||||
% for ii = 1:k;
|
||||
% for jj = 1:ii
|
||||
% H(ii,jj) = trace(iPmf*(.5*DP(mf,mf,ii)*iPmf*DP(mf,mf,jj) + Dv(:,ii)*Dv(:,jj)'));
|
||||
% end
|
||||
% end
|
||||
end
|
||||
|
||||
AHess = -AHess;
|
||||
if nargout > 1,
|
||||
a = T*(a+K*v);
|
||||
P = T*(P-K*P(mf,:))*transpose(T)+Om;
|
||||
DP = DP1;
|
||||
end
|
||||
notsteady = max(max(abs(K-oldK))) > riccati_tol;
|
||||
oldK = K;
|
||||
end
|
||||
|
||||
if F_singular
|
||||
error('The variance of the forecast error remains singular until the end of the sample')
|
||||
end
|
||||
|
||||
|
||||
if t < smpl
|
||||
t0 = t+1;
|
||||
while t < smpl
|
||||
t = t+1;
|
||||
v = Y(:,t)-a(mf);
|
||||
for ii = 1:k
|
||||
Dv(:,ii) = -Da(mf,ii)-DYss(mf,ii);
|
||||
Da(:,ii) = DT(:,:,ii)*(a+K*v) + T*(Da(:,ii)+DK(:,:,ii)*v + K*Dv(:,ii));
|
||||
if t>=start && nargout >1
|
||||
DLIK(ii,1) = DLIK(ii,1) + trace( iF*DF(:,:,ii) ) + 2*Dv(:,ii)'*iF*v - v'*(iF*DF(:,:,ii)*iF)*v;
|
||||
end
|
||||
end
|
||||
if t>=start
|
||||
AHess = AHess + Dv'*iF*Dv;
|
||||
end
|
||||
a = T*(a+K*v);
|
||||
lik(t) = transpose(v)*iF*v;
|
||||
end
|
||||
AHess = AHess + .5*(smpl-t0+1)*(vecDPmf' * kron(iF,iF) * vecDPmf);
|
||||
if nargout > 1
|
||||
for ii = 1:k
|
||||
% DLIK(ii,1) = DLIK(ii,1) + (smpl-t0+1)*trace( iF*DF(:,:,ii) );
|
||||
end
|
||||
end
|
||||
lik(t0:smpl) = lik(t0:smpl) + log(det(F));
|
||||
% for ii = 1:k;
|
||||
% for jj = 1:ii
|
||||
% H(ii,jj) = trace(iPmf*(.5*DP(mf,mf,ii)*iPmf*DP(mf,mf,jj) + Dv(:,ii)*Dv(:,jj)'));
|
||||
% end
|
||||
% end
|
||||
end
|
||||
|
||||
AHess = -AHess;
|
||||
if nargout > 1
|
||||
DLIK = DLIK/2;
|
||||
end
|
||||
% adding log-likelihhod constants
|
||||
lik = (lik + pp*log(2*pi))/2;
|
||||
|
||||
LIK = sum(lik(start:end)); % Minus the log-likelihood.
|
||||
% end of main function
|
||||
|
||||
% end of main function
|
||||
|
||||
function [DK,DF,DP1] = computeDKalman(T,DT,DOm,P,DP,DH,mf,iF,K)
|
||||
|
||||
k = size(DT,3);
|
||||
tmp = P-K*P(mf,:);
|
||||
k = size(DT,3);
|
||||
tmp = P-K*P(mf,:);
|
||||
|
||||
for ii = 1:k
|
||||
DF(:,:,ii) = DP(mf,mf,ii) + DH(:,:,ii);
|
||||
DF(:,:,ii) = DP(mf,mf,ii) + DH(:,:,ii);
|
||||
DiF(:,:,ii) = -iF*DF(:,:,ii)*iF;
|
||||
DK(:,:,ii) = DP(:,mf,ii)*iF + P(:,mf)*DiF(:,:,ii);
|
||||
Dtmp = DP(:,:,ii) - DK(:,:,ii)*P(mf,:) - K*DP(mf,:,ii);
|
||||
|
@ -150,6 +150,3 @@ for ii = 1:k
|
|||
end
|
||||
|
||||
% end of computeDKalman
|
||||
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
function e = SPAimerr(c);
|
||||
function e = SPAimerr(c)
|
||||
% e = aimerr(c);
|
||||
%
|
||||
% Interpret the return codes generated by the aim routines.
|
||||
|
@ -29,7 +29,7 @@ function e = SPAimerr(c);
|
|||
% Journal of Economic Dynamics and Control, 2010, vol. 34, issue 3,
|
||||
% pages 472-489
|
||||
|
||||
if(c==1) e='Aim: unique solution.';
|
||||
if(c==1) e='Aim: unique solution.';
|
||||
elseif(c==2) e='Aim: roots not correctly computed by real_schur.';
|
||||
elseif(c==3) e='Aim: too many big roots.';
|
||||
elseif(c==35) e='Aim: too many big roots, and q(:,right) is singular.';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
function [b,rts,ia,nexact,nnumeric,lgroots,aimcode] = ...
|
||||
SPAmalg(h,neq,nlag,nlead,condn,uprbnd)
|
||||
SPAmalg(h,neq,nlag,nlead,condn,uprbnd)
|
||||
% [b,rts,ia,nexact,nnumeric,lgroots,aimcode] = ...
|
||||
% SPAmalg(h,neq,nlag,nlead,condn,uprbnd)
|
||||
%
|
||||
|
@ -8,9 +8,9 @@ function [b,rts,ia,nexact,nnumeric,lgroots,aimcode] = ...
|
|||
% roots. This procedure will fail if the companion matrix is
|
||||
% defective and does not have a linearly independent set of
|
||||
% eigenvectors associated with the big roots.
|
||||
%
|
||||
%
|
||||
% Input arguments:
|
||||
%
|
||||
%
|
||||
% h Structural coefficient matrix (neq,neq*(nlag+1+nlead)).
|
||||
% neq Number of equations.
|
||||
% nlag Number of lags.
|
||||
|
@ -19,9 +19,9 @@ function [b,rts,ia,nexact,nnumeric,lgroots,aimcode] = ...
|
|||
% by numeric_shift and reduced_form.
|
||||
% uprbnd Inclusive upper bound for the modulus of roots
|
||||
% allowed in the reduced form.
|
||||
%
|
||||
%
|
||||
% Output arguments:
|
||||
%
|
||||
%
|
||||
% b Reduced form coefficient matrix (neq,neq*nlag).
|
||||
% rts Roots returned by eig.
|
||||
% ia Dimension of companion matrix (number of non-trivial
|
||||
|
@ -57,7 +57,7 @@ function [b,rts,ia,nexact,nnumeric,lgroots,aimcode] = ...
|
|||
% pages 472-489
|
||||
|
||||
b=[];rts=[];ia=[];nexact=[];nnumeric=[];lgroots=[];aimcode=[];
|
||||
if(nlag<1 || nlead<1)
|
||||
if(nlag<1 || nlead<1)
|
||||
error('Aim_eig: model must have at least one lag and one lead');
|
||||
end
|
||||
% Initialization.
|
||||
|
@ -66,26 +66,26 @@ bcols=neq*nlag;q=zeros(qrows,qcols);rts=zeros(qcols,1);
|
|||
[h,q,iq,nexact]=SPExact_shift(h,q,iq,qrows,qcols,neq);
|
||||
if (iq>qrows)
|
||||
aimcode = 61;
|
||||
return;
|
||||
return
|
||||
end
|
||||
[h,q,iq,nnumeric]=SPNumeric_shift(h,q,iq,qrows,qcols,neq,condn);
|
||||
if (iq>qrows)
|
||||
aimcode = 62;
|
||||
return;
|
||||
return
|
||||
end
|
||||
[a,ia,js] = SPBuild_a(h,qcols,neq);
|
||||
if (ia ~= 0)
|
||||
if any(any(isnan(a))) || any(any(isinf(a)))
|
||||
if any(any(isnan(a))) || any(any(isinf(a)))
|
||||
disp('A is NAN or INF')
|
||||
aimcode=63;
|
||||
return
|
||||
end
|
||||
aimcode=63;
|
||||
return
|
||||
end
|
||||
[w,rts,lgroots,flag_trouble]=SPEigensystem(a,uprbnd,min(length(js),qrows-iq+1));
|
||||
if flag_trouble==1;
|
||||
disp('Problem in SPEIG');
|
||||
if flag_trouble==1
|
||||
disp('Problem in SPEIG');
|
||||
aimcode=64;
|
||||
return
|
||||
end
|
||||
end
|
||||
q = SPCopy_w(q,w,js,iq,qrows);
|
||||
end
|
||||
test=nexact+nnumeric+lgroots;
|
||||
|
|
|
@ -41,9 +41,9 @@ hs(:,left) = -hs(:,right)\hs(:,left);
|
|||
a = zeros(qcols,qcols);
|
||||
|
||||
if(qcols > neq)
|
||||
eyerows = 1:qcols-neq;
|
||||
eyecols = neq+1:qcols;
|
||||
a(eyerows,eyecols) = eye(qcols-neq);
|
||||
eyerows = 1:qcols-neq;
|
||||
eyecols = neq+1:qcols;
|
||||
a(eyerows,eyecols) = eye(qcols-neq);
|
||||
end
|
||||
hrows = qcols-neq+1:qcols;
|
||||
a(hrows,:) = hs(:,left);
|
||||
|
@ -51,14 +51,14 @@ a(hrows,:) = hs(:,left);
|
|||
% Delete inessential lags and build index array js. js indexes the
|
||||
% columns in the big transition matrix that correspond to the
|
||||
% essential lags in the model. They are the columns of q that will
|
||||
% get the unstable left eigenvectors.
|
||||
% get the unstable left eigenvectors.
|
||||
|
||||
js = 1:qcols;
|
||||
zerocols = sum(abs(a)) == 0;
|
||||
while( any(zerocols) )
|
||||
a(:,zerocols) = [];
|
||||
a(zerocols,:) = [];
|
||||
js(zerocols) = [];
|
||||
zerocols = sum(abs(a)) == 0;
|
||||
a(:,zerocols) = [];
|
||||
a(zerocols,:) = [];
|
||||
js(zerocols) = [];
|
||||
zerocols = sum(abs(a)) == 0;
|
||||
end
|
||||
ia = length(js);
|
||||
|
|
|
@ -2,7 +2,7 @@ function q = SPCopy_w(q,w,js,iq,qrows)
|
|||
% q = SPCopy_w(q,w,js,iq,qrows)
|
||||
%
|
||||
% Copy the eigenvectors corresponding to the largest roots into the
|
||||
% remaining empty rows and columns js of q
|
||||
% remaining empty rows and columns js of q
|
||||
|
||||
% Author: Gary Anderson
|
||||
% Original file downloaded from:
|
||||
|
@ -30,7 +30,7 @@ function q = SPCopy_w(q,w,js,iq,qrows)
|
|||
|
||||
|
||||
if(iq < qrows)
|
||||
lastrows = iq+1:qrows;
|
||||
wrows = 1:length(lastrows);
|
||||
q(lastrows,js) = w(:,wrows)';
|
||||
lastrows = iq+1:qrows;
|
||||
wrows = 1:length(lastrows);
|
||||
q(lastrows,js) = w(:,wrows)';
|
||||
end
|
||||
|
|
|
@ -30,7 +30,7 @@ function [w,rts,lgroots,flag_trouble] = SPEigensystem(a,uprbnd,rowsLeft)
|
|||
% Journal of Economic Dynamics and Control, 2010, vol. 34, issue 3,
|
||||
% pages 472-489
|
||||
|
||||
opts.disp=0;
|
||||
opts.disp=0;
|
||||
% next block is commented out because eigs() intermitently returns different rts
|
||||
%try
|
||||
% [w,d] = eigs(a',rowsLeft,'LM',opts);
|
||||
|
@ -39,24 +39,24 @@ opts.disp=0;
|
|||
% [mag,k] = sort(-mag);
|
||||
% rts = rts(k);
|
||||
%catch
|
||||
%disp('Catch in SPE');
|
||||
%pause(0.5);
|
||||
%aStr=datestr(clock);
|
||||
%eval(['save ' regexprep(aStr,' ','') ' a']);
|
||||
try
|
||||
[w,d]=eig(a');
|
||||
catch
|
||||
lasterr
|
||||
w=[];rts=[];lgroots=[];
|
||||
flag_trouble=1;
|
||||
return
|
||||
end
|
||||
rts = diag(d);
|
||||
mag = abs(rts);
|
||||
[mag,k] = sort(-mag);
|
||||
rts = rts(k);
|
||||
%disp('Catch in SPE');
|
||||
%pause(0.5);
|
||||
%aStr=datestr(clock);
|
||||
%eval(['save ' regexprep(aStr,' ','') ' a']);
|
||||
try
|
||||
[w,d]=eig(a');
|
||||
catch
|
||||
lasterr
|
||||
w=[];rts=[];lgroots=[];
|
||||
flag_trouble=1;
|
||||
return
|
||||
end
|
||||
rts = diag(d);
|
||||
mag = abs(rts);
|
||||
[mag,k] = sort(-mag);
|
||||
rts = rts(k);
|
||||
%end
|
||||
flag_trouble=0;
|
||||
flag_trouble=0;
|
||||
|
||||
%ws=SPSparse(w);
|
||||
ws=sparse(w);
|
||||
|
@ -65,7 +65,7 @@ ws = ws(:,k);
|
|||
% Given a complex conjugate pair of vectors W = [w1,w2], there is a
|
||||
% nonsingular matrix D such that W*D = real(W) + imag(W). That is to
|
||||
% say, W and real(W)+imag(W) span the same subspace, which is all
|
||||
% that aim cares about.
|
||||
% that aim cares about.
|
||||
|
||||
ws = real(ws) + imag(ws);
|
||||
|
||||
|
|
|
@ -36,12 +36,11 @@ right = qcols+1:qcols+neq;
|
|||
zerorows = find( sum(abs( hs(:,right)' ))==0 );
|
||||
|
||||
while( any(zerorows) && iq <= qrows )
|
||||
nz = length(zerorows);
|
||||
q(iq+1:iq+nz,:) = hs(zerorows,left);
|
||||
hs(zerorows,:) = SPShiftright(hs(zerorows,:),neq);
|
||||
iq = iq + nz;
|
||||
nexact = nexact + nz;
|
||||
zerorows = find( sum(abs( hs(:,right)' ))==0 );
|
||||
nz = length(zerorows);
|
||||
q(iq+1:iq+nz,:) = hs(zerorows,left);
|
||||
hs(zerorows,:) = SPShiftright(hs(zerorows,:),neq);
|
||||
iq = iq + nz;
|
||||
nexact = nexact + nz;
|
||||
zerorows = find( sum(abs( hs(:,right)' ))==0 );
|
||||
end
|
||||
h=full(hs);
|
||||
|
||||
|
|
|
@ -37,14 +37,14 @@ right = qcols+1:qcols+neq;
|
|||
zerorows = find( abs(diag(R)) <= condn );
|
||||
|
||||
while( any(zerorows) && iq <= qrows )
|
||||
h=sparse(h);
|
||||
Q=sparse(Q);
|
||||
h = Q'*h;
|
||||
nz = length(zerorows);
|
||||
q(iq+1:iq+nz,:) = h(zerorows,left);
|
||||
h(zerorows,:) = SPShiftright( h(zerorows,:), neq );
|
||||
iq = iq + nz;
|
||||
nnumeric = nnumeric + nz;
|
||||
[Q,R,E] = qr( full(h(:,right)) );
|
||||
zerorows = find( abs(diag(R)) <= condn );
|
||||
h=sparse(h);
|
||||
Q=sparse(Q);
|
||||
h = Q'*h;
|
||||
nz = length(zerorows);
|
||||
q(iq+1:iq+nz,:) = h(zerorows,left);
|
||||
h(zerorows,:) = SPShiftright( h(zerorows,:), neq );
|
||||
iq = iq + nz;
|
||||
nnumeric = nnumeric + nz;
|
||||
[Q,R,E] = qr( full(h(:,right)) );
|
||||
zerorows = find( abs(diag(R)) <= condn );
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ function scof = SPObstruct(cof,cofb,neq,nlag,nlead)
|
|||
% scof = SPObstruct(cof,cofb,neq,nlag,nlead)
|
||||
%
|
||||
% Construct the coefficients in the observable structure.
|
||||
%
|
||||
%
|
||||
% Input arguments:
|
||||
%
|
||||
% cof structural coefficients
|
||||
|
@ -51,17 +51,17 @@ qs=sparse(q);
|
|||
qs(1:rc,1:cc) = sparse(cofb);
|
||||
qcols = neq*(nlag+nlead);
|
||||
|
||||
if( nlead > 1 )
|
||||
for i = 1:nlead-1
|
||||
rows = i*neq + (1:neq);
|
||||
qs(rows,:) = SPShiftright( qs((rows-neq),:), neq );
|
||||
end
|
||||
if( nlead > 1 )
|
||||
for i = 1:nlead-1
|
||||
rows = i*neq + (1:neq);
|
||||
qs(rows,:) = SPShiftright( qs((rows-neq),:), neq );
|
||||
end
|
||||
end
|
||||
|
||||
l = (1: neq*nlag);
|
||||
r = (neq*nlag+1: neq*(nlag+nlead));
|
||||
|
||||
qs(:,l) = - qs(:,r) \ qs(:,l);
|
||||
qs(:,l) = - qs(:,r) \ qs(:,l);
|
||||
|
||||
minus = 1: neq*(nlag+1);
|
||||
plus = neq*(nlag+1)+1: neq*(nlag+1+nlead);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
function [nonsing,b] = SPReduced_form(q,qrows,qcols,bcols,neq,condn);
|
||||
function [nonsing,b] = SPReduced_form(q,qrows,qcols,bcols,neq,condn)
|
||||
% [nonsing,b] = SPReduced_form(q,qrows,qcols,bcols,neq,b,condn);
|
||||
%
|
||||
% Compute reduced-form coefficient matrix, b.
|
||||
|
@ -38,7 +38,7 @@ if(nonsing)
|
|||
b = qs(1:neq,1:bcols);
|
||||
b = full(b);
|
||||
else %rescale by dividing row by maximal qr element
|
||||
%'inverse condition number small, rescaling '
|
||||
%'inverse condition number small, rescaling '
|
||||
themax=max(abs(qs(:,right)),[],2);
|
||||
oneover = diag(1 ./ themax);
|
||||
nonsing = rcond(full(oneover *qs(:,right))) > condn;
|
||||
|
@ -48,4 +48,3 @@ else %rescale by dividing row by maximal qr element
|
|||
b = full(b);
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ function [y] = SPShiftright(x,n)
|
|||
% [y] = shiftright(x,n)
|
||||
%
|
||||
% Shift the rows of x to the right by n columns, leaving zeros in the
|
||||
% first n columns.
|
||||
% first n columns.
|
||||
|
||||
% Original author: Gary Anderson
|
||||
% Original file downloaded from:
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
function [dr,aimcode,rts]=dynAIMsolver1(jacobia_,M_,dr)
|
||||
% function [dr,aimcode]=dynAIMsolver1(jacobia_,M_,dr)
|
||||
% Maps Dynare jacobia to AIM 1st order model solver designed and developed by Gary ANderson
|
||||
% Maps Dynare jacobia to AIM 1st order model solver designed and developed by Gary ANderson
|
||||
% and derives the solution for gy=dr.hgx and gu=dr.hgu from the AIM outputs
|
||||
% AIM System is given as a sum:
|
||||
% i.e. for i=-$...+& SUM(Hi*xt+i)= £*zt, t = 0, . . . ,?
|
||||
% AIM System is given as a sum:
|
||||
% i.e. for i=-$...+& SUM(Hi*xt+i)= £*zt, t = 0, . . . ,?
|
||||
% and its input as single array of matrices: [H-$... Hi ... H+&]
|
||||
% and its solution as xt=SUM( Bi*xt+i) + @*£*zt for i=-$...-1
|
||||
% with the output in form bb=[B-$... Bi ... B-1] and @=inv(Ho+H1*B-1)
|
||||
% Dynare jacobian = [fy'-$... fy'i ... fy'+& fu']
|
||||
% where [fy'-$... fy'i ... fy'+&]=[H-$... Hi ... H+&] and fu'= £
|
||||
% and its solution as xt=SUM( Bi*xt+i) + @*£*zt for i=-$...-1
|
||||
% with the output in form bb=[B-$... Bi ... B-1] and @=inv(Ho+H1*B-1)
|
||||
% Dynare jacobian = [fy'-$... fy'i ... fy'+& fu']
|
||||
% where [fy'-$... fy'i ... fy'+&]=[H-$... Hi ... H+&] and fu'= £
|
||||
%
|
||||
% INPUTS
|
||||
% jacobia_ [matrix] 1st order derivative of the model
|
||||
% jacobia_ [matrix] 1st order derivative of the model
|
||||
% dr [matlab structure] Decision rules for stochastic simulations.
|
||||
% M_ [matlab structure] Definition of the model.
|
||||
%
|
||||
% M_ [matlab structure] Definition of the model.
|
||||
%
|
||||
% OUTPUTS
|
||||
% dr [matlab structure] Decision rules for stochastic simulations.
|
||||
% aimcode [integer] 1: the model defines variables uniquely
|
||||
|
@ -31,22 +31,22 @@ function [dr,aimcode,rts]=dynAIMsolver1(jacobia_,M_,dr)
|
|||
% (c==63) e='Aim: A is NAN or INF.';
|
||||
% (c==64) e='Aim: Problem in SPEIG.';
|
||||
% else e='Aimerr: return code not properly specified';
|
||||
%
|
||||
%
|
||||
% SPECIAL REQUIREMENTS
|
||||
% Dynare use:
|
||||
% Dynare use:
|
||||
% 1) the lognormal block in DR1 is being invoked for some models and changing
|
||||
% values of ghx and ghy. We need to return the AIM output
|
||||
% values before that block and run the block with the current returned values
|
||||
% of gy (i.e. dr.ghx) and gu (dr.ghu) if it is needed even when the AIM is used
|
||||
% of gy (i.e. dr.ghx) and gu (dr.ghu) if it is needed even when the AIM is used
|
||||
% (it does not depend on mjdgges output).
|
||||
%
|
||||
% 2) passing in aa={Q'|1}*jacobia_ can produce ~ one order closer
|
||||
% results to the Dynare solutiion then when if plain jacobia_ is passed,
|
||||
% i.e. diff < e-14 for aa and diff < *e-13 for jacobia_ if Q' is used.
|
||||
%
|
||||
% GP July 2008
|
||||
% 2) passing in aa={Q'|1}*jacobia_ can produce ~ one order closer
|
||||
% results to the Dynare solutiion then when if plain jacobia_ is passed,
|
||||
% i.e. diff < e-14 for aa and diff < *e-13 for jacobia_ if Q' is used.
|
||||
%
|
||||
% GP July 2008
|
||||
|
||||
% Copyright (C) 2008-2012 Dynare Team
|
||||
% Copyright (C) 2008-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -69,8 +69,8 @@ lags=M_.maximum_endo_lag; % no of lags and leads
|
|||
leads=M_.maximum_endo_lead;
|
||||
klen=(leads+lags+1); % total lenght
|
||||
theAIM_H=zeros(neq, neq*klen); % alloc space
|
||||
lli=M_.lead_lag_incidence';
|
||||
% "sparse" the compact jacobia into AIM H aray of matrices
|
||||
lli=M_.lead_lag_incidence';
|
||||
% "sparse" the compact jacobia into AIM H aray of matrices
|
||||
% without exogenous shoc
|
||||
theAIM_H(:,find(lli(:)))=jacobia_(:,nonzeros(lli(:)));
|
||||
condn = 1.e-10;%SPAmalg uses this in zero tests
|
||||
|
@ -102,7 +102,7 @@ if aimcode==1 %if OK
|
|||
col_order=[((i-1)*neq)+dr.order_var' col_order];
|
||||
end
|
||||
bb_ord= bb(dr.order_var,col_order); % derive ordered gy
|
||||
|
||||
|
||||
% variables are present in the state space at the lag at which they
|
||||
% appear and at all smaller lags. The are ordered from smaller to
|
||||
% higher lag (reversed order of M_.lead_lag_incidence rows for lagged
|
||||
|
@ -117,7 +117,7 @@ if aimcode==1 %if OK
|
|||
%theH0= theAIM_H (:,lags*neq+1: (lags+1)*neq);
|
||||
% theHP= theAIM_H (:,(M_.maximum_endo_lag+1)*neq+1: (M_.maximum_endo_lag+2)*neq);
|
||||
%theHP= theAIM_H (:,(lags+1)*neq+1: (lags+2)*neq);
|
||||
theAIM_Psi= - jacobia_(:, size(nonzeros(lli(:)))+1:end);%
|
||||
theAIM_Psi= - jacobia_(:, size(nonzeros(lli(:)))+1:end);%
|
||||
%? = inv(H0 + H1B1)
|
||||
%phi= (theH0+theHP*sparse(bb(:,(lags-1)*neq+1:end)))\eye( neq);
|
||||
%AIM_ghu=phi*theAIM_Psi;
|
||||
|
@ -137,8 +137,8 @@ else
|
|||
if aimcode < 1 || aimcode > 5 % too big exception, use mjdgges
|
||||
error('Error in AIM: aimcode=%d ; %s', aimcode, err);
|
||||
end
|
||||
% if aimcode > 5
|
||||
% if aimcode > 5
|
||||
% disp(['Error in AIM: aimcode=' sprintf('%d : %s',aimcode, err)]);
|
||||
% aimcode=5;
|
||||
% end
|
||||
% end
|
||||
end
|
||||
|
|
|
@ -51,7 +51,7 @@ function [dr,info]=AIM_first_order_solver(jacobia,M,dr,qz_criterium)
|
|||
%! @end deftypefn
|
||||
%@eod:
|
||||
|
||||
% Copyright (C) 2001-2016 Dynare Team
|
||||
% Copyright (C) 2001-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -67,35 +67,34 @@ function [dr,info]=AIM_first_order_solver(jacobia,M,dr,qz_criterium)
|
|||
%
|
||||
% You should have received a copy of the GNU General Public License
|
||||
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
info = 0;
|
||||
|
||||
[dr,aimcode]=dynAIMsolver1(jacobia,M,dr);
|
||||
|
||||
if aimcode ~=1
|
||||
info(1) = convertAimCodeToInfo(aimCode); %convert to be in the 100 range
|
||||
info(2) = 1.0e+8;
|
||||
return
|
||||
info = 0;
|
||||
|
||||
[dr,aimcode]=dynAIMsolver1(jacobia,M,dr);
|
||||
|
||||
if aimcode ~=1
|
||||
info(1) = convertAimCodeToInfo(aimCode); %convert to be in the 100 range
|
||||
info(2) = 1.0e+8;
|
||||
return
|
||||
end
|
||||
A = kalman_transition_matrix(dr,M.nstatic+(1:M.nspred), 1:M.nspred,...
|
||||
M.exo_nbr);
|
||||
dr.eigval = eig(A);
|
||||
disp(dr.eigval)
|
||||
nd = size(dr.kstate,1);
|
||||
nba = nd-sum( abs(dr.eigval) < qz_criterium );
|
||||
|
||||
nsfwrd = M.nsfwrd;
|
||||
|
||||
if nba ~= nsfwrd
|
||||
temp = sort(abs(dr.eigval));
|
||||
if nba > nsfwrd
|
||||
temp = temp(nd-nba+1:nd-nsfwrd)-1-qz_criterium;
|
||||
info(1) = 3;
|
||||
elseif nba < nsfwrd
|
||||
temp = temp(nd-nsfwrd+1:nd-nba)-1-qz_criterium;
|
||||
info(1) = 4;
|
||||
end
|
||||
A = kalman_transition_matrix(dr,M.nstatic+(1:M.nspred), 1:M.nspred,...
|
||||
M.exo_nbr);
|
||||
dr.eigval = eig(A);
|
||||
disp(dr.eigval)
|
||||
nd = size(dr.kstate,1);
|
||||
nba = nd-sum( abs(dr.eigval) < qz_criterium );
|
||||
|
||||
nsfwrd = M.nsfwrd;
|
||||
|
||||
if nba ~= nsfwrd
|
||||
temp = sort(abs(dr.eigval));
|
||||
if nba > nsfwrd
|
||||
temp = temp(nd-nba+1:nd-nsfwrd)-1-qz_criterium;
|
||||
info(1) = 3;
|
||||
elseif nba < nsfwrd;
|
||||
temp = temp(nd-nsfwrd+1:nd-nba)-1-qz_criterium;
|
||||
info(1) = 4;
|
||||
end
|
||||
info(2) = temp'*temp;
|
||||
return
|
||||
end
|
||||
|
||||
info(2) = temp'*temp;
|
||||
return
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ function [DirectoryName, info] = CheckPath(type,dname)
|
|||
% Creates the subfolder "./M_.dname/type" if it does not exist yet.
|
||||
%
|
||||
% INPUTS
|
||||
% type [string] Name of the subfolder.
|
||||
% type [string] Name of the subfolder.
|
||||
% dname [string] Name of the directory
|
||||
%
|
||||
% OUTPUTS
|
||||
|
@ -12,7 +12,7 @@ function [DirectoryName, info] = CheckPath(type,dname)
|
|||
% SPECIAL REQUIREMENTS
|
||||
% none
|
||||
|
||||
% Copyright (C) 2005-2013 Dynare Team
|
||||
% Copyright (C) 2005-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
|
|
@ -16,7 +16,7 @@ function CutSample(M_, options_, estim_params_)
|
|||
% SPECIAL REQUIREMENTS
|
||||
% none
|
||||
|
||||
% Copyright (C) 2005-2015 Dynare Team
|
||||
% Copyright (C) 2005-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -66,7 +66,7 @@ if (TotalNumberOfMhFiles-1)-(FirstMhFile+1)+1 > 0
|
|||
elseif TotalNumberOfMhFiles == 1
|
||||
record.KeepedDraws.Distribution = [];
|
||||
elseif TotalNumberOfMhFiles == 2 && FirstMhFile > 1
|
||||
record.KeepedDraws.Distribution = [MAX_nruns-FirstLine+1 ; record.MhDraws(end,3)];
|
||||
record.KeepedDraws.Distribution = [MAX_nruns-FirstLine+1 ; record.MhDraws(end,3)];
|
||||
end
|
||||
|
||||
% Save updated mh-history file.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
function [alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T,R,P,PK,decomp,trend_addition,state_uncertainty,M_,oo_,options_,bayestopt_] = DsgeSmoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_)
|
||||
% Estimation of the smoothed variables and innovations.
|
||||
%
|
||||
% INPUTS
|
||||
% o xparam1 [double] (p*1) vector of (estimated) parameters.
|
||||
% Estimation of the smoothed variables and innovations.
|
||||
%
|
||||
% INPUTS
|
||||
% o xparam1 [double] (p*1) vector of (estimated) parameters.
|
||||
% o gend [integer] scalar specifying the number of observations ==> varargin{1}.
|
||||
% o data [double] (n*T) matrix of data.
|
||||
% o data_index [cell] 1*smpl cell of column vectors of indices.
|
||||
|
@ -12,7 +12,7 @@ function [alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T,R,P,PK,de
|
|||
% o options_ [structure] describing the options
|
||||
% o bayestopt_ [structure] describing the priors
|
||||
% o estim_params_ [structure] characterizing parameters to be estimated
|
||||
%
|
||||
%
|
||||
% OUTPUTS
|
||||
% o alphahat [double] (m*T) matrix, smoothed endogenous variables (a_{t|T}) (decision-rule order)
|
||||
% o etahat [double] (r*T) matrix, smoothed structural shocks (r>=n is the number of shocks).
|
||||
|
@ -29,36 +29,36 @@ function [alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T,R,P,PK,de
|
|||
% matrices (meaningless for periods 1:d) (decision-rule order)
|
||||
% o decomp (K*m*r*(T+K)) 4D array of shock decomposition of k-step ahead
|
||||
% filtered variables (decision-rule order)
|
||||
% o trend_addition [double] (n*T) pure trend component; stored in options_.varobs order
|
||||
% o trend_addition [double] (n*T) pure trend component; stored in options_.varobs order
|
||||
% o state_uncertainty [double] (K,K,T) array, storing the uncertainty
|
||||
% about the smoothed state (decision-rule order)
|
||||
% o M_ [structure] decribing the model
|
||||
% o oo_ [structure] storing the results
|
||||
% o options_ [structure] describing the options
|
||||
% o bayestopt_ [structure] describing the priors
|
||||
%
|
||||
%
|
||||
% Notes:
|
||||
% m: number of endogenous variables (M_.endo_nbr)
|
||||
% T: number of Time periods (options_.nobs)
|
||||
% r: number of strucural shocks (M_.exo_nbr)
|
||||
% n: number of observables (length(options_.varobs))
|
||||
% K: maximum forecast horizon (max(options_.nk))
|
||||
%
|
||||
%
|
||||
% To get variables that are stored in decision rule order in order of declaration
|
||||
% as in M_.endo_names, ones needs code along the lines of:
|
||||
% variables_declaration_order(dr.order_var,:) = alphahat
|
||||
%
|
||||
% Defines bayestopt_.mf = bayestopt_.smoother_mf (positions of observed variables
|
||||
% and requested smoothed variables in decision rules (decision rule order)) and
|
||||
%
|
||||
% Defines bayestopt_.mf = bayestopt_.smoother_mf (positions of observed variables
|
||||
% and requested smoothed variables in decision rules (decision rule order)) and
|
||||
% passes it back via global variable
|
||||
%
|
||||
% ALGORITHM
|
||||
% Diffuse Kalman filter (Durbin and Koopman)
|
||||
%
|
||||
% ALGORITHM
|
||||
% Diffuse Kalman filter (Durbin and Koopman)
|
||||
%
|
||||
% SPECIAL REQUIREMENTS
|
||||
% None
|
||||
|
||||
% Copyright (C) 2006-2016 Dynare Team
|
||||
% Copyright (C) 2006-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -97,7 +97,7 @@ end
|
|||
%------------------------------------------------------------------------------
|
||||
% 2. call model setup & reduction program
|
||||
%------------------------------------------------------------------------------
|
||||
oldoo.restrict_var_list = oo_.dr.restrict_var_list;
|
||||
oldoo.restrict_var_list = oo_.dr.restrict_var_list;
|
||||
oldoo.restrict_columns = oo_.dr.restrict_columns;
|
||||
oo_.dr.restrict_var_list = bayestopt_.smoother_var_list;
|
||||
oo_.dr.restrict_columns = bayestopt_.smoother_restrict_columns;
|
||||
|
@ -133,8 +133,8 @@ mf = bayestopt_.mf;
|
|||
% ------------------------------------------------------------------------------
|
||||
% 3. Initial condition of the Kalman filter
|
||||
% ------------------------------------------------------------------------------
|
||||
%
|
||||
% Here, Pinf and Pstar are determined. If the model is stationary, determine
|
||||
%
|
||||
% Here, Pinf and Pstar are determined. If the model is stationary, determine
|
||||
% Pstar as the solution of the Lyapunov equation and set Pinf=[] (Notation follows
|
||||
% Koopman/Durbin (2003), Journal of Time Series Analysis 24(1))
|
||||
%
|
||||
|
@ -169,7 +169,7 @@ elseif options_.lik_init == 3 % Diffuse Kalman filter
|
|||
kalman_algo = 3;
|
||||
else
|
||||
if ~all(all(abs(H-diag(diag(H)))<1e-14))% ie, the covariance matrix is diagonal...
|
||||
%Augment state vector (follows Section 6.4.3 of DK (2012))
|
||||
%Augment state vector (follows Section 6.4.3 of DK (2012))
|
||||
expanded_state_vector_for_univariate_filter=1;
|
||||
T = blkdiag(T,zeros(vobs));
|
||||
np = size(T,1);
|
||||
|
@ -240,32 +240,32 @@ if kalman_algo == 1 || kalman_algo == 3
|
|||
end
|
||||
|
||||
if kalman_algo == 2 || kalman_algo == 4
|
||||
if ~all(all(abs(H-diag(diag(H)))<1e-14))% ie, the covariance matrix is diagonal...
|
||||
if ~expanded_state_vector_for_univariate_filter
|
||||
%Augment state vector (follows Section 6.4.3 of DK (2012))
|
||||
expanded_state_vector_for_univariate_filter=1;
|
||||
Z = [Z, eye(vobs)];
|
||||
ST = blkdiag(ST,zeros(vobs));
|
||||
np = size(ST,1);
|
||||
Q = blkdiag(Q,H);
|
||||
R1 = blkdiag(R,eye(vobs));
|
||||
if kalman_algo == 4
|
||||
%recompute Schur state space transformation with
|
||||
%expanded state space
|
||||
[Pstar,Pinf] = compute_Pinf_Pstar(mf,ST,R1,Q,options_.qz_criterium);
|
||||
else
|
||||
Pstar = blkdiag(Pstar,H);
|
||||
if ~isempty(Pinf)
|
||||
Pinf = blkdiag(Pinf,zeros(vobs));
|
||||
end
|
||||
end
|
||||
%now reset H to 0
|
||||
H = zeros(vobs,vobs);
|
||||
if ~all(all(abs(H-diag(diag(H)))<1e-14))% ie, the covariance matrix is diagonal...
|
||||
if ~expanded_state_vector_for_univariate_filter
|
||||
%Augment state vector (follows Section 6.4.3 of DK (2012))
|
||||
expanded_state_vector_for_univariate_filter=1;
|
||||
Z = [Z, eye(vobs)];
|
||||
ST = blkdiag(ST,zeros(vobs));
|
||||
np = size(ST,1);
|
||||
Q = blkdiag(Q,H);
|
||||
R1 = blkdiag(R,eye(vobs));
|
||||
if kalman_algo == 4
|
||||
%recompute Schur state space transformation with
|
||||
%expanded state space
|
||||
[Pstar,Pinf] = compute_Pinf_Pstar(mf,ST,R1,Q,options_.qz_criterium);
|
||||
else
|
||||
%do nothing, state vector was already expanded
|
||||
Pstar = blkdiag(Pstar,H);
|
||||
if ~isempty(Pinf)
|
||||
Pinf = blkdiag(Pinf,zeros(vobs));
|
||||
end
|
||||
end
|
||||
%now reset H to 0
|
||||
H = zeros(vobs,vobs);
|
||||
else
|
||||
%do nothing, state vector was already expanded
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
[alphahat,epsilonhat,etahat,ahat,P,aK,PK,decomp,state_uncertainty] = missing_DiffuseKalmanSmootherH3_Z(ST, ...
|
||||
Z,R1,Q,diag(H), ...
|
||||
Pinf,Pstar,data1,vobs,np,smpl,data_index, ...
|
||||
|
@ -282,7 +282,7 @@ if expanded_state_vector_for_univariate_filter && (kalman_algo == 2 || kalman_al
|
|||
ahat = ahat(k,:);
|
||||
aK = aK(:,k,:,:);
|
||||
epsilonhat=etahat(end-vobs+1:end,:);
|
||||
etahat=etahat(1:end-vobs,:);
|
||||
etahat=etahat(1:end-vobs,:);
|
||||
if ~isempty(PK)
|
||||
PK = PK(:,k,k,:);
|
||||
end
|
||||
|
|
|
@ -5,18 +5,18 @@ function Draws = GetAllPosteriorDraws(column, FirstMhFile, FirstLine, TotalNumbe
|
|||
%
|
||||
% INPUTS
|
||||
% column: column
|
||||
% FirstMhFile: first mh file
|
||||
% FirstMhFile: first mh file
|
||||
% FirstLine: first line
|
||||
% TotalNumberOfMhFile: total number of mh file
|
||||
% TotalNumberOfMhFile: total number of mh file
|
||||
% NumberOfDraws: number of draws
|
||||
|
||||
% OUTPUTS
|
||||
% Draws: draws from posterior distribution
|
||||
%
|
||||
%
|
||||
% SPECIAL REQUIREMENTS
|
||||
% none
|
||||
|
||||
% Copyright (C) 2005-2011 Dynare Team
|
||||
% Copyright (C) 2005-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -55,7 +55,7 @@ if nblck>1 && nargin<6
|
|||
iline = 1;
|
||||
end
|
||||
end
|
||||
else
|
||||
else
|
||||
for blck = 1:nblck
|
||||
iline=iline0;
|
||||
for file = FirstMhFile:TotalNumberOfMhFile
|
||||
|
|
|
@ -5,15 +5,15 @@ function [xparams, logpost] = GetOneDraw(type)
|
|||
% INPUTS
|
||||
% type: [string] 'posterior': draw from MCMC draws
|
||||
% 'prior': draw from prior
|
||||
%
|
||||
%
|
||||
% OUTPUTS
|
||||
% xparams: vector of estimated parameters (drawn from posterior or prior distribution)
|
||||
% logpost: log of the posterior density of this parameter vector
|
||||
%
|
||||
%
|
||||
% SPECIAL REQUIREMENTS
|
||||
% none
|
||||
|
||||
% Copyright (C) 2005-2015 Dynare Team
|
||||
% Copyright (C) 2005-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
function [mean,variance] = GetPosteriorMeanVariance(M,drop)
|
||||
|
||||
% Copyright (C) 2012-2016 Dynare Team
|
||||
% Copyright (C) 2012-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -16,38 +16,38 @@ function [mean,variance] = GetPosteriorMeanVariance(M,drop)
|
|||
%
|
||||
% You should have received a copy of the GNU General Public License
|
||||
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
MetropolisFolder = CheckPath('metropolis',M.dname);
|
||||
FileName = M.fname;
|
||||
BaseName = [MetropolisFolder filesep FileName];
|
||||
load_last_mh_history_file(MetropolisFolder, FileName);
|
||||
NbrDraws = sum(record.MhDraws(:,1));
|
||||
NbrFiles = sum(record.MhDraws(:,2));
|
||||
NbrBlocks = record.Nblck;
|
||||
mean = 0;
|
||||
variance = 0;
|
||||
|
||||
NbrKeptDraws = 0;
|
||||
for i=1:NbrBlocks
|
||||
NbrDrawsCurrentBlock = 0;
|
||||
for j=1:NbrFiles
|
||||
o = load([BaseName '_mh' int2str(j) '_blck' int2str(i),'.mat']);
|
||||
NbrDrawsCurrentFile = size(o.x2,1);
|
||||
if NbrDrawsCurrentBlock + NbrDrawsCurrentFile <= drop*NbrDraws
|
||||
NbrDrawsCurrentBlock = NbrDrawsCurrentBlock + NbrDrawsCurrentFile;
|
||||
continue
|
||||
elseif NbrDrawsCurrentBlock < drop*NbrDraws
|
||||
FirstDraw = ceil(drop*NbrDraws - NbrDrawsCurrentBlock + 1);
|
||||
x2 = o.x2(FirstDraw:end,:);
|
||||
else
|
||||
x2 = o.x2;
|
||||
end
|
||||
NbrKeptDrawsCurrentFile = size(x2,1);
|
||||
%recursively compute mean and variance
|
||||
mean = (NbrKeptDraws*mean + sum(x2)')/(NbrKeptDraws+NbrKeptDrawsCurrentFile);
|
||||
x2Demeaned = bsxfun(@minus,x2,mean');
|
||||
variance = (NbrKeptDraws*variance + x2Demeaned'*x2Demeaned)/(NbrKeptDraws+NbrKeptDrawsCurrentFile);
|
||||
|
||||
MetropolisFolder = CheckPath('metropolis',M.dname);
|
||||
FileName = M.fname;
|
||||
BaseName = [MetropolisFolder filesep FileName];
|
||||
load_last_mh_history_file(MetropolisFolder, FileName);
|
||||
NbrDraws = sum(record.MhDraws(:,1));
|
||||
NbrFiles = sum(record.MhDraws(:,2));
|
||||
NbrBlocks = record.Nblck;
|
||||
mean = 0;
|
||||
variance = 0;
|
||||
|
||||
NbrKeptDraws = 0;
|
||||
for i=1:NbrBlocks
|
||||
NbrDrawsCurrentBlock = 0;
|
||||
for j=1:NbrFiles
|
||||
o = load([BaseName '_mh' int2str(j) '_blck' int2str(i),'.mat']);
|
||||
NbrDrawsCurrentFile = size(o.x2,1);
|
||||
if NbrDrawsCurrentBlock + NbrDrawsCurrentFile <= drop*NbrDraws
|
||||
NbrDrawsCurrentBlock = NbrDrawsCurrentBlock + NbrDrawsCurrentFile;
|
||||
NbrKeptDraws = NbrKeptDraws + NbrKeptDrawsCurrentFile;
|
||||
continue
|
||||
elseif NbrDrawsCurrentBlock < drop*NbrDraws
|
||||
FirstDraw = ceil(drop*NbrDraws - NbrDrawsCurrentBlock + 1);
|
||||
x2 = o.x2(FirstDraw:end,:);
|
||||
else
|
||||
x2 = o.x2;
|
||||
end
|
||||
NbrKeptDrawsCurrentFile = size(x2,1);
|
||||
%recursively compute mean and variance
|
||||
mean = (NbrKeptDraws*mean + sum(x2)')/(NbrKeptDraws+NbrKeptDrawsCurrentFile);
|
||||
x2Demeaned = bsxfun(@minus,x2,mean');
|
||||
variance = (NbrKeptDraws*variance + x2Demeaned'*x2Demeaned)/(NbrKeptDraws+NbrKeptDrawsCurrentFile);
|
||||
NbrDrawsCurrentBlock = NbrDrawsCurrentBlock + NbrDrawsCurrentFile;
|
||||
NbrKeptDraws = NbrKeptDraws + NbrKeptDrawsCurrentFile;
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
function oo_ = GetPosteriorParametersStatistics(estim_params_, M_, options_, bayestopt_, oo_, pnames)
|
||||
% This function prints and saves posterior estimates after the mcmc
|
||||
% (+updates of oo_ & TeX output).
|
||||
%
|
||||
% INPUTS
|
||||
% estim_params_ [structure]
|
||||
% (+updates of oo_ & TeX output).
|
||||
%
|
||||
% INPUTS
|
||||
% estim_params_ [structure]
|
||||
% M_ [structure]
|
||||
% options_ [structure]
|
||||
% bayestopt_ [structure]
|
||||
% oo_ [structure]
|
||||
% pnames [char] Array of char, names of the prior shapes available
|
||||
%
|
||||
% OUTPUTS
|
||||
% oo_ [structure]
|
||||
%
|
||||
% OUTPUTS
|
||||
% oo_ [structure]
|
||||
%
|
||||
% SPECIAL REQUIREMENTS
|
||||
% None.
|
||||
|
||||
% Copyright (C) 2006-2016 Dynare Team
|
||||
% Copyright (C) 2006-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -34,7 +34,7 @@ function oo_ = GetPosteriorParametersStatistics(estim_params_, M_, options_, bay
|
|||
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
%if ~options_.mh_replic && options_.load_mh_file
|
||||
% load([M_.fname '_results.mat'],'oo_');
|
||||
% load([M_.fname '_results.mat'],'oo_');
|
||||
%end
|
||||
|
||||
TeX = options_.TeX;
|
||||
|
@ -48,7 +48,7 @@ nx = nvx+nvn+ncx+ncn+np;
|
|||
|
||||
MetropolisFolder = CheckPath('metropolis',M_.dname);
|
||||
OutputFolder = CheckPath('Output',M_.dname);
|
||||
FileName = M_.fname;
|
||||
FileName = M_.fname;
|
||||
|
||||
load_last_mh_history_file(MetropolisFolder,FileName);
|
||||
|
||||
|
@ -108,14 +108,14 @@ if np
|
|||
[post_mean, post_median, post_var, hpd_interval, post_deciles, ...
|
||||
density] = posterior_moments(Draws,1,options_.mh_conf_sig);
|
||||
name = bayestopt_.name{ip};
|
||||
oo_ = Filloo(oo_,name,type,post_mean,hpd_interval,post_median,post_var,post_deciles,density);
|
||||
oo_ = Filloo(oo_,name,type,post_mean,hpd_interval,post_median,post_var,post_deciles,density);
|
||||
end
|
||||
end
|
||||
disp(sprintf(pformat,header_width,name,bayestopt_.p1(ip),...
|
||||
post_mean, ...
|
||||
hpd_interval, ...
|
||||
pnames(bayestopt_.pshape(ip)+1,:), ...
|
||||
bayestopt_.p2(ip)));
|
||||
bayestopt_.p2(ip)));
|
||||
if TeX
|
||||
k = estim_params_.param_vals(i,1);
|
||||
name = deblank(M_.param_names_tex(k,:));
|
||||
|
@ -163,7 +163,7 @@ if nvx
|
|||
end
|
||||
disp(sprintf(pformat,header_width,name,bayestopt_.p1(ip),post_mean,hpd_interval,...
|
||||
pnames(bayestopt_.pshape(ip)+1,:),bayestopt_.p2(ip)));
|
||||
if TeX,
|
||||
if TeX
|
||||
name = deblank(M_.exo_names_tex(k,:));
|
||||
TeXCore(fid,name,deblank(pnames(bayestopt_.pshape(ip)+1,:)),bayestopt_.p1(ip),...
|
||||
bayestopt_.p2(ip),post_mean,sqrt(post_var),hpd_interval);
|
||||
|
@ -171,7 +171,7 @@ if nvx
|
|||
ip = ip+1;
|
||||
end
|
||||
if TeX
|
||||
TeXEnd(fid,2,'standard deviation of structural shocks');
|
||||
TeXEnd(fid,2,'standard deviation of structural shocks');
|
||||
end
|
||||
end
|
||||
if nvn
|
||||
|
@ -213,7 +213,7 @@ if nvn
|
|||
ip = ip+1;
|
||||
end
|
||||
if TeX
|
||||
TeXEnd(fid,3,'standard deviation of measurement errors');
|
||||
TeXEnd(fid,3,'standard deviation of measurement errors');
|
||||
end
|
||||
end
|
||||
if ncx
|
||||
|
@ -311,15 +311,15 @@ if ncn
|
|||
end
|
||||
disp(sprintf(pformat, header_width,name,bayestopt_.p1(ip),post_mean,hpd_interval, ...
|
||||
pnames(bayestopt_.pshape(ip)+1,:),bayestopt_.p2(ip)));
|
||||
if TeX,
|
||||
if TeX
|
||||
name = ['(',deblank(M_.endo_names_tex(k1,:)) ',' deblank(M_.endo_names_tex(k2,:)),')'];
|
||||
TeXCore(fid,name,deblank(pnames(bayestopt_.pshape(ip)+1,:)),bayestopt_.p1(ip),...
|
||||
bayestopt_.p2(ip),post_mean,sqrt(post_var),hpd_interval);
|
||||
bayestopt_.p2(ip),post_mean,sqrt(post_var),hpd_interval);
|
||||
end
|
||||
ip = ip+1;
|
||||
end
|
||||
if TeX
|
||||
TeXEnd(fid,5,'correlation of measurement errors');
|
||||
TeXEnd(fid,5,'correlation of measurement errors');
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -359,7 +359,7 @@ fid = fidTeX;
|
|||
|
||||
|
||||
function TeXCore(fid,name,shape,priormean,priorstd,postmean,poststd,hpd)
|
||||
fprintf(fid,['$%s$ & %s & %7.3f & %6.4f & %7.3f& %6.4f & %7.4f & %7.4f \\\\ \n'],...
|
||||
fprintf(fid,['$%s$ & %s & %7.3f & %6.4f & %7.3f& %6.4f & %7.4f & %7.4f \\\\ \n'],...
|
||||
name,...
|
||||
shape,...
|
||||
priormean,...
|
||||
|
@ -371,7 +371,7 @@ fprintf(fid,['$%s$ & %s & %7.3f & %6.4f & %7.3f& %6.4f & %7.4f & %7.4f \\\\ \n']
|
|||
|
||||
|
||||
function TeXEnd(fid,fnum,title)
|
||||
fprintf(fid,'\\end{longtable}\n ');
|
||||
fprintf(fid,'\\end{longtable}\n ');
|
||||
fprintf(fid,'\\end{center}\n');
|
||||
fprintf(fid,'%% End of TeX file.\n');
|
||||
fclose(fid);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
function MakeAllFigures(NumberOfPlots,Caption,FigureProperties,Info)
|
||||
|
||||
% Copyright (C) 2005-2009 Dynare Team
|
||||
% Copyright (C) 2005-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -19,11 +19,11 @@ function MakeAllFigures(NumberOfPlots,Caption,FigureProperties,Info)
|
|||
|
||||
global M_ options_
|
||||
|
||||
FigHandle = figure('Name',FigureProperties.Name);
|
||||
FigHandle = figure('Name',FigureProperties.Name);
|
||||
|
||||
NAMES = cell(NumberOfPlots,1);
|
||||
if options_.TeX
|
||||
TeXNAMES = cell(NumberOfPlots,1);
|
||||
TeXNAMES = cell(NumberOfPlots,1);
|
||||
end
|
||||
|
||||
if NumberOfPlots == 9
|
||||
|
@ -53,7 +53,7 @@ elseif NumberOfPlots == 2
|
|||
elseif NumberOfPlots == 1
|
||||
nr = 1;
|
||||
nc = 1;
|
||||
end
|
||||
end
|
||||
|
||||
for plt = 1:NumberOfPlots
|
||||
eval(['NumberOfCurves = Info.Box' int2str(plt) '.Number;'])
|
||||
|
@ -138,7 +138,7 @@ for plt = 1:NumberOfPlots
|
|||
set(hh,'Color','r','LineStyle','-','LineWidth',2)
|
||||
%
|
||||
%
|
||||
end
|
||||
end
|
||||
end
|
||||
axis([xmin xmax ymin ymax])
|
||||
title(NAMES{plt})
|
||||
|
@ -150,14 +150,14 @@ if Info.SaveFormat.Eps
|
|||
if isempty(Info.SaveFormat.Name)
|
||||
eval(['print -depsc2 ' M_.fname Info.SaveFormat.GenericName int2str(Info.SaveFormat.Number) '.eps']);
|
||||
else
|
||||
eval(['print -depsc2 ' M_.fname Info.SaveFormat.GenericName Info.SaveFormat.Name '.eps']);
|
||||
eval(['print -depsc2 ' M_.fname Info.SaveFormat.GenericName Info.SaveFormat.Name '.eps']);
|
||||
end
|
||||
end
|
||||
if Info.SaveFormat.Pdf && ~isoctave
|
||||
if isempty(Info.SaveFormat.Name)
|
||||
eval(['print -dpdf ' M_.fname Info.SaveFormat.GenericName int2str(Info.SaveFormat.Number)]);
|
||||
else
|
||||
eval(['print -dpdf ' M_.fname Info.SaveFormat.GenericName Info.SaveFormat.Name]);
|
||||
eval(['print -dpdf ' M_.fname Info.SaveFormat.GenericName Info.SaveFormat.Name]);
|
||||
end
|
||||
end
|
||||
if Info.SaveFormat.Fig && ~isoctave
|
||||
|
|
|
@ -4,15 +4,15 @@ function oo_ = PlotPosteriorDistributions(estim_params_, M_, options_, bayestopt
|
|||
% plots posterior distributions
|
||||
%
|
||||
% INPUTS
|
||||
% estim_params_ [structure]
|
||||
% estim_params_ [structure]
|
||||
% M_ [structure]
|
||||
% options_ [structure]
|
||||
% options_ [structure]
|
||||
% bayestopt_ [structure]
|
||||
% oo_ [structure]
|
||||
%
|
||||
%
|
||||
% OUTPUTS
|
||||
% oo_ [structure]
|
||||
%
|
||||
% oo_ [structure]
|
||||
%
|
||||
% SPECIAL REQUIREMENTS
|
||||
% none
|
||||
|
||||
|
@ -49,7 +49,7 @@ nn = sqrt(MaxNumberOfPlotPerFigure);
|
|||
|
||||
figurename = 'Priors and posteriors';
|
||||
|
||||
if TeX && any(strcmp('eps',cellstr(options_.graph_format)))
|
||||
if TeX && any(strcmp('eps',cellstr(options_.graph_format)))
|
||||
fidTeX = fopen([OutputDirectoryName '/' M_.fname '_PriorsAndPosteriors.tex'],'w');
|
||||
fprintf(fidTeX,'%% TeX eps-loader file generated by PlotPosteriorDistributions.m (Dynare).\n');
|
||||
fprintf(fidTeX,['%% ' datestr(now,0) '\n']);
|
||||
|
@ -78,9 +78,9 @@ for i=1:npar
|
|||
end
|
||||
end
|
||||
[x2,f2,abscissa,dens,binf2,bsup2] = draw_prior_density(i,bayestopt_);
|
||||
top2 = max(f2);
|
||||
top2 = max(f2);
|
||||
if i <= nvx
|
||||
name = deblank(M_.exo_names(estim_params_.var_exo(i,1),:));
|
||||
name = deblank(M_.exo_names(estim_params_.var_exo(i,1),:));
|
||||
x1 = oo_.posterior_density.shocks_std.(name)(:,1);
|
||||
f1 = oo_.posterior_density.shocks_std.(name)(:,2);
|
||||
oo_.prior_density.shocks_std.(name)(:,1) = x2;
|
||||
|
@ -96,18 +96,18 @@ for i=1:npar
|
|||
oo_.prior_density.measurement_errors_std.(name)(:,2) = f2;
|
||||
if ~options_.mh_posterior_mode_estimation
|
||||
pmod = oo_.posterior_mode.measurement_errors_std.(name);
|
||||
end
|
||||
end
|
||||
elseif i <= nvx+nvn+ncx
|
||||
j = i - (nvx+nvn);
|
||||
k1 = estim_params_.corrx(j,1);
|
||||
k2 = estim_params_.corrx(j,2);
|
||||
name = [deblank(M_.exo_names(k1,:)) '_' deblank(M_.exo_names(k2,:))];
|
||||
name = [deblank(M_.exo_names(k1,:)) '_' deblank(M_.exo_names(k2,:))];
|
||||
x1 = oo_.posterior_density.shocks_corr.(name)(:,1);
|
||||
f1 = oo_.posterior_density.shocks_corr.(name)(:,2);
|
||||
oo_.prior_density.shocks_corr.(name)(:,1) = x2;
|
||||
oo_.prior_density.shocks_corr.(name)(:,2) = f2;
|
||||
if ~options_.mh_posterior_mode_estimation
|
||||
pmod = oo_.posterior_mode.shocks_corr.(name);
|
||||
pmod = oo_.posterior_mode.shocks_corr.(name);
|
||||
end
|
||||
elseif i <= nvx+nvn+ncx+ncn
|
||||
j = i - (nvx+nvn+ncx);
|
||||
|
@ -151,13 +151,13 @@ for i=1:npar
|
|||
title(nam,'Interpreter','none');
|
||||
hold off;
|
||||
drawnow
|
||||
if subplotnum == MaxNumberOfPlotPerFigure || i == npar;
|
||||
if subplotnum == MaxNumberOfPlotPerFigure || i == npar
|
||||
dyn_saveas(hfig,[OutputDirectoryName '/' M_.fname '_PriorsAndPosteriors' int2str(figunumber)],options_.nodisplay,options_.graph_format);
|
||||
if TeX && any(strcmp('eps',cellstr(options_.graph_format)))
|
||||
fprintf(fidTeX,'\\begin{figure}[H]\n');
|
||||
for j = 1:size(NAMES,1)
|
||||
fprintf(fidTeX,'\\psfrag{%s}[1][][0.5][0]{%s}\n',deblank(NAMES(j,:)),deblank(TeXNAMES(j,:)));
|
||||
end
|
||||
end
|
||||
fprintf(fidTeX,'\\centering\n');
|
||||
fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%s/%s_PriorsAndPosteriors%s}\n',options_.figures.textwidth*min(subplotnum/nn,1),OutputDirectoryName,M_.fname,int2str(figunumber));
|
||||
fprintf(fidTeX,'\\caption{Priors and posteriors.}');
|
||||
|
|
|
@ -16,7 +16,7 @@ function PosteriorIRF(type)
|
|||
% functions associated with it(the _core1 and _core2).
|
||||
% See also the comments posterior_sampler.m funtion.
|
||||
|
||||
% Copyright (C) 2006-2016 Dynare Team
|
||||
% Copyright (C) 2006-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -178,7 +178,7 @@ if strcmpi(type,'posterior')
|
|||
end
|
||||
end
|
||||
|
||||
if ~strcmpi(type,'prior'),
|
||||
if ~strcmpi(type,'prior')
|
||||
localVars.x=x;
|
||||
end
|
||||
|
||||
|
@ -202,16 +202,16 @@ localVars.ifil2=ifil2;
|
|||
localVars.MhDirectoryName=MhDirectoryName;
|
||||
|
||||
% Like sequential execution!
|
||||
if isnumeric(options_.parallel),
|
||||
if isnumeric(options_.parallel)
|
||||
[fout] = PosteriorIRF_core1(localVars,1,B,0);
|
||||
nosaddle = fout.nosaddle;
|
||||
else
|
||||
% Parallel execution!
|
||||
[nCPU, totCPU, nBlockPerCPU] = distributeJobs(options_.parallel, 1, B);
|
||||
for j=1:totCPU-1,
|
||||
for j=1:totCPU-1
|
||||
nfiles = ceil(nBlockPerCPU(j)/MAX_nirfs_dsge);
|
||||
NumberOfIRFfiles_dsge(j+1) =NumberOfIRFfiles_dsge(j)+nfiles;
|
||||
if MAX_nirfs_dsgevar,
|
||||
if MAX_nirfs_dsgevar
|
||||
nfiles = ceil(nBlockPerCPU(j)/MAX_nirfs_dsgevar);
|
||||
else
|
||||
nfiles=0;
|
||||
|
@ -236,8 +236,8 @@ else
|
|||
NamFileInput(1,:) = {'',[M_.fname '_static.m']};
|
||||
NamFileInput(2,:) = {'',[M_.fname '_dynamic.m']};
|
||||
NamFileInput(3,:) = {'',[M_.fname '_set_auxiliary_variables.m']};
|
||||
if options_.steadystate_flag,
|
||||
if options_.steadystate_flag == 1,
|
||||
if options_.steadystate_flag
|
||||
if options_.steadystate_flag == 1
|
||||
NamFileInput(length(NamFileInput)+1,:)={'',[M_.fname '_steadystate.m']};
|
||||
else
|
||||
NamFileInput(length(NamFileInput)+1,:)={'',[M_.fname '_steadystate2.m']};
|
||||
|
@ -245,7 +245,7 @@ else
|
|||
end
|
||||
[fout] = masterParallel(options_.parallel, 1, B,NamFileInput,'PosteriorIRF_core1', localVars, globalVars, options_.parallel_info);
|
||||
nosaddle=0;
|
||||
for j=1:length(fout),
|
||||
for j=1:length(fout)
|
||||
nosaddle = nosaddle + fout(j).nosaddle;
|
||||
end
|
||||
|
||||
|
@ -368,101 +368,101 @@ end
|
|||
% PosteriorIRF_core2.m function.
|
||||
|
||||
if ~options_.nograph && ~options_.no_graph.posterior
|
||||
% Save the local variables.
|
||||
localVars=[];
|
||||
% Save the local variables.
|
||||
localVars=[];
|
||||
|
||||
Check=options_.TeX;
|
||||
if (Check)
|
||||
localVars.varlist_TeX=varlist_TeX;
|
||||
end
|
||||
|
||||
|
||||
localVars.nvar=nvar;
|
||||
localVars.MeanIRF=MeanIRF;
|
||||
localVars.tit=tit;
|
||||
localVars.nn=nn;
|
||||
localVars.MAX_nirfs_dsgevar=MAX_nirfs_dsgevar;
|
||||
localVars.HPDIRF=HPDIRF;
|
||||
localVars.varlist=varlist;
|
||||
localVars.MaxNumberOfPlotPerFigure=MaxNumberOfPlotPerFigure;
|
||||
if options_.dsge_var
|
||||
localVars.HPDIRFdsgevar=HPDIRFdsgevar;
|
||||
localVars.MeanIRFdsgevar = MeanIRFdsgevar;
|
||||
end
|
||||
|
||||
% The files .TeX are genereted in sequential way always!
|
||||
|
||||
% The files .TeX are generated in sequential way always!
|
||||
subplotnum = 0;
|
||||
tit_TeX(M_.exo_names_orig_ord,:) = M_.exo_names_tex;
|
||||
if options_.TeX && any(strcmp('eps',cellstr(options_.graph_format)))
|
||||
fidTeX = fopen([DirectoryName filesep M_.fname '_BayesianIRF.tex'],'w');
|
||||
fprintf(fidTeX,'%% TeX eps-loader file generated by PosteriorIRF.m (Dynare).\n');
|
||||
fprintf(fidTeX,['%% ' datestr(now,0) '\n']);
|
||||
fprintf(fidTeX,' \n');
|
||||
titTeX(M_.exo_names_orig_ord,:) = M_.exo_names_tex;
|
||||
|
||||
for ii=irf_shocks_indx
|
||||
figunumber = 0;
|
||||
|
||||
for jj=1:nvar
|
||||
if max(abs(MeanIRF(:,jj,ii))) >= options_.impulse_responses.plot_threshold
|
||||
subplotnum = subplotnum+1;
|
||||
|
||||
if subplotnum == 1
|
||||
fprintf(fidTeX,'\\begin{figure}[H]\n');
|
||||
end
|
||||
name = deblank(varlist(jj,:));
|
||||
texname = deblank(varlist_TeX(jj,:));
|
||||
fprintf(fidTeX,['\\psfrag{%s}[1][][0.5][0]{%s}\n'],name,['$' texname '$']);
|
||||
end
|
||||
if subplotnum == MaxNumberOfPlotPerFigure || (jj == nvar && subplotnum> 0)
|
||||
figunumber = figunumber+1;
|
||||
|
||||
fprintf(fidTeX,'\\centering \n');
|
||||
fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%s/%s_Bayesian_IRF_%s_%d}\n',options_.figures.textwidth*min(subplotnum/nn,1),DirectoryName,M_.fname,deblank(tit(ii,:)),figunumber);
|
||||
if options_.relative_irf
|
||||
fprintf(fidTeX,['\\caption{Bayesian relative IRF.}']);
|
||||
else
|
||||
fprintf(fidTeX,'\\caption{Bayesian IRF: Orthogonalized shock to $%s$.}\n',deblank(tit_TeX(ii,:)));
|
||||
end
|
||||
fprintf(fidTeX,'\\label{Fig:BayesianIRF:%s:%d}\n',deblank(tit(ii,:)),figunumber);
|
||||
fprintf(fidTeX,'\\end{figure}\n');
|
||||
fprintf(fidTeX,' \n');
|
||||
|
||||
subplotnum = 0;
|
||||
end
|
||||
end
|
||||
Check=options_.TeX;
|
||||
if (Check)
|
||||
localVars.varlist_TeX=varlist_TeX;
|
||||
end
|
||||
fprintf(fidTeX,'%% End of TeX file.\n');
|
||||
fclose(fidTeX);
|
||||
end
|
||||
|
||||
% The others file format are generated in parallel by PosteriorIRF_core2!
|
||||
|
||||
|
||||
% Comment for testing!
|
||||
if ~isoctave
|
||||
if isnumeric(options_.parallel) || (M_.exo_nbr*ceil(size(varlist,1)/MaxNumberOfPlotPerFigure))<8,
|
||||
[fout] = PosteriorIRF_core2(localVars,1,M_.exo_nbr,0);
|
||||
else
|
||||
isRemoteOctave = 0;
|
||||
for indPC=1:length(options_.parallel),
|
||||
isRemoteOctave = isRemoteOctave + (findstr(options_.parallel(indPC).MatlabOctavePath, 'octave'));
|
||||
localVars.nvar=nvar;
|
||||
localVars.MeanIRF=MeanIRF;
|
||||
localVars.tit=tit;
|
||||
localVars.nn=nn;
|
||||
localVars.MAX_nirfs_dsgevar=MAX_nirfs_dsgevar;
|
||||
localVars.HPDIRF=HPDIRF;
|
||||
localVars.varlist=varlist;
|
||||
localVars.MaxNumberOfPlotPerFigure=MaxNumberOfPlotPerFigure;
|
||||
if options_.dsge_var
|
||||
localVars.HPDIRFdsgevar=HPDIRFdsgevar;
|
||||
localVars.MeanIRFdsgevar = MeanIRFdsgevar;
|
||||
end
|
||||
|
||||
% The files .TeX are genereted in sequential way always!
|
||||
|
||||
% The files .TeX are generated in sequential way always!
|
||||
subplotnum = 0;
|
||||
tit_TeX(M_.exo_names_orig_ord,:) = M_.exo_names_tex;
|
||||
if options_.TeX && any(strcmp('eps',cellstr(options_.graph_format)))
|
||||
fidTeX = fopen([DirectoryName filesep M_.fname '_BayesianIRF.tex'],'w');
|
||||
fprintf(fidTeX,'%% TeX eps-loader file generated by PosteriorIRF.m (Dynare).\n');
|
||||
fprintf(fidTeX,['%% ' datestr(now,0) '\n']);
|
||||
fprintf(fidTeX,' \n');
|
||||
titTeX(M_.exo_names_orig_ord,:) = M_.exo_names_tex;
|
||||
|
||||
for ii=irf_shocks_indx
|
||||
figunumber = 0;
|
||||
|
||||
for jj=1:nvar
|
||||
if max(abs(MeanIRF(:,jj,ii))) >= options_.impulse_responses.plot_threshold
|
||||
subplotnum = subplotnum+1;
|
||||
|
||||
if subplotnum == 1
|
||||
fprintf(fidTeX,'\\begin{figure}[H]\n');
|
||||
end
|
||||
name = deblank(varlist(jj,:));
|
||||
texname = deblank(varlist_TeX(jj,:));
|
||||
fprintf(fidTeX,['\\psfrag{%s}[1][][0.5][0]{%s}\n'],name,['$' texname '$']);
|
||||
end
|
||||
if subplotnum == MaxNumberOfPlotPerFigure || (jj == nvar && subplotnum> 0)
|
||||
figunumber = figunumber+1;
|
||||
|
||||
fprintf(fidTeX,'\\centering \n');
|
||||
fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%s/%s_Bayesian_IRF_%s_%d}\n',options_.figures.textwidth*min(subplotnum/nn,1),DirectoryName,M_.fname,deblank(tit(ii,:)),figunumber);
|
||||
if options_.relative_irf
|
||||
fprintf(fidTeX,['\\caption{Bayesian relative IRF.}']);
|
||||
else
|
||||
fprintf(fidTeX,'\\caption{Bayesian IRF: Orthogonalized shock to $%s$.}\n',deblank(tit_TeX(ii,:)));
|
||||
end
|
||||
fprintf(fidTeX,'\\label{Fig:BayesianIRF:%s:%d}\n',deblank(tit(ii,:)),figunumber);
|
||||
fprintf(fidTeX,'\\end{figure}\n');
|
||||
fprintf(fidTeX,' \n');
|
||||
|
||||
subplotnum = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
if isRemoteOctave
|
||||
fprintf(fidTeX,'%% End of TeX file.\n');
|
||||
fclose(fidTeX);
|
||||
end
|
||||
|
||||
% The others file format are generated in parallel by PosteriorIRF_core2!
|
||||
|
||||
|
||||
% Comment for testing!
|
||||
if ~isoctave
|
||||
if isnumeric(options_.parallel) || (M_.exo_nbr*ceil(size(varlist,1)/MaxNumberOfPlotPerFigure))<8
|
||||
[fout] = PosteriorIRF_core2(localVars,1,M_.exo_nbr,0);
|
||||
else
|
||||
globalVars = struct('M_',M_, ...
|
||||
'options_', options_);
|
||||
isRemoteOctave = 0;
|
||||
for indPC=1:length(options_.parallel)
|
||||
isRemoteOctave = isRemoteOctave + (findstr(options_.parallel(indPC).MatlabOctavePath, 'octave'));
|
||||
end
|
||||
if isRemoteOctave
|
||||
[fout] = PosteriorIRF_core2(localVars,1,M_.exo_nbr,0);
|
||||
else
|
||||
globalVars = struct('M_',M_, ...
|
||||
'options_', options_);
|
||||
|
||||
[fout] = masterParallel(options_.parallel, 1, M_.exo_nbr,NamFileInput,'PosteriorIRF_core2', localVars, globalVars, options_.parallel_info);
|
||||
[fout] = masterParallel(options_.parallel, 1, M_.exo_nbr,NamFileInput,'PosteriorIRF_core2', localVars, globalVars, options_.parallel_info);
|
||||
end
|
||||
end
|
||||
else
|
||||
[fout] = PosteriorIRF_core2(localVars,1,M_.exo_nbr,0);
|
||||
end
|
||||
else
|
||||
[fout] = PosteriorIRF_core2(localVars,1,M_.exo_nbr,0);
|
||||
end
|
||||
% END parallel code!
|
||||
% END parallel code!
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ function myoutput=PosteriorIRF_core1(myinputs,fpar,B,whoiam, ThisMatlab)
|
|||
% SPECIAL REQUIREMENTS.
|
||||
% None.
|
||||
%
|
||||
% Copyright (C) 2006-2016 Dynare Team
|
||||
% Copyright (C) 2006-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -43,7 +43,7 @@ function myoutput=PosteriorIRF_core1(myinputs,fpar,B,whoiam, ThisMatlab)
|
|||
|
||||
global options_ estim_params_ oo_ M_ bayestopt_ dataset_ dataset_info
|
||||
|
||||
if nargin<4,
|
||||
if nargin<4
|
||||
whoiam=0;
|
||||
end
|
||||
|
||||
|
@ -55,7 +55,7 @@ irun =myinputs.irun;
|
|||
irun2=myinputs.irun2;
|
||||
npar=myinputs.npar;
|
||||
type=myinputs.type;
|
||||
if ~strcmpi(type,'prior'),
|
||||
if ~strcmpi(type,'prior')
|
||||
x=myinputs.x;
|
||||
end
|
||||
|
||||
|
@ -102,7 +102,7 @@ end
|
|||
RemoteFlag = 0;
|
||||
|
||||
if whoiam
|
||||
if Parallel(ThisMatlab).Local==0,
|
||||
if Parallel(ThisMatlab).Local==0
|
||||
RemoteFlag =1;
|
||||
end
|
||||
prct0={0,whoiam,Parallel(ThisMatlab)};
|
||||
|
@ -165,7 +165,7 @@ while fpar<B
|
|||
elseif info(1) == 5
|
||||
errordef = 'Rank condition is not satisfied';
|
||||
end
|
||||
if strcmpi(type,'prior'),
|
||||
if strcmpi(type,'prior')
|
||||
disp(['PosteriorIRF :: Dynare is unable to solve the model (' errordef ')'])
|
||||
continue
|
||||
else
|
||||
|
@ -240,9 +240,9 @@ while fpar<B
|
|||
else
|
||||
stock_irf_bvardsge(:,:,:,IRUN) = reshape(tmp_dsgevar,options_.irf,dataset_.vobs,M_.exo_nbr);
|
||||
instr = [MhDirectoryName '/' M_.fname '_irf_bvardsge' ...
|
||||
int2str(NumberOfIRFfiles_dsgevar) '.mat stock_irf_bvardsge;'];,
|
||||
int2str(NumberOfIRFfiles_dsgevar) '.mat stock_irf_bvardsge;'];
|
||||
eval(['save ' instr]);
|
||||
if RemoteFlag==1,
|
||||
if RemoteFlag==1
|
||||
OutputFileName_bvardsge = [OutputFileName_bvardsge; {[MhDirectoryName filesep], [M_.fname '_irf_bvardsge' int2str(NumberOfIRFfiles_dsgevar) '.mat']}];
|
||||
end
|
||||
NumberOfIRFfiles_dsgevar = NumberOfIRFfiles_dsgevar+1;
|
||||
|
@ -259,14 +259,14 @@ while fpar<B
|
|||
int2str(NumberOfIRFfiles_dsgevar) '.mat stock_irf_bvardsge;'];
|
||||
eval(['save ' instr]);
|
||||
NumberOfIRFfiles_dsgevar = NumberOfIRFfiles_dsgevar+1;
|
||||
if RemoteFlag==1,
|
||||
if RemoteFlag==1
|
||||
OutputFileName_bvardsge = [OutputFileName_bvardsge; {[MhDirectoryName filesep], [M_.fname '_irf_bvardsge' int2str(NumberOfIRFfiles_dsgevar) '.mat']}];
|
||||
end
|
||||
irun = 0;
|
||||
end
|
||||
end
|
||||
save([MhDirectoryName '/' M_.fname '_irf_dsge' int2str(NumberOfIRFfiles_dsge) '.mat'],'stock_irf_dsge');
|
||||
if RemoteFlag==1,
|
||||
if RemoteFlag==1
|
||||
OutputFileName_dsge = [OutputFileName_dsge; {[MhDirectoryName filesep], [M_.fname '_irf_dsge' int2str(NumberOfIRFfiles_dsge) '.mat']}];
|
||||
end
|
||||
NumberOfIRFfiles_dsge = NumberOfIRFfiles_dsge+1;
|
||||
|
@ -278,7 +278,7 @@ while fpar<B
|
|||
end
|
||||
stock = stock_param;
|
||||
save([MhDirectoryName '/' M_.fname '_param_irf' int2str(ifil2) '.mat'],'stock');
|
||||
if RemoteFlag==1,
|
||||
if RemoteFlag==1
|
||||
OutputFileName_param = [OutputFileName_param; {[MhDirectoryName filesep], [M_.fname '_param_irf' int2str(ifil2) '.mat']}];
|
||||
end
|
||||
ifil2 = ifil2 + 1;
|
||||
|
|
|
@ -2,10 +2,10 @@ function myoutput=PosteriorIRF_core2(myinputs,fpar,npar,whoiam,ThisMatlab)
|
|||
% function myoutput=PosteriorIRF_core2(myinputs,fpar,npar,whoiam, ThisMatlab)
|
||||
% Generates the Posterior IRFs plot from the IRFs generated in
|
||||
% PosteriorIRF_core1
|
||||
%
|
||||
%
|
||||
% PARALLEL CONTEXT
|
||||
% Performs in parallel execution a portion of the PosteriorIRF.m code.
|
||||
% For more information, see the comment in posterior_sampler_core.m
|
||||
% For more information, see the comment in posterior_sampler_core.m
|
||||
% function.
|
||||
%
|
||||
% INPUTS
|
||||
|
@ -49,7 +49,7 @@ function myoutput=PosteriorIRF_core2(myinputs,fpar,npar,whoiam,ThisMatlab)
|
|||
|
||||
global options_ M_
|
||||
|
||||
if nargin<4,
|
||||
if nargin<4
|
||||
whoiam=0;
|
||||
end
|
||||
|
||||
|
@ -85,8 +85,8 @@ end
|
|||
DirectoryName = CheckPath('Output',M_.dname);
|
||||
|
||||
RemoteFlag = 0;
|
||||
if whoiam,
|
||||
if Parallel(ThisMatlab).Local==0,
|
||||
if whoiam
|
||||
if Parallel(ThisMatlab).Local==0
|
||||
RemoteFlag =1;
|
||||
end
|
||||
prct0={0,whoiam,Parallel(ThisMatlab)};
|
||||
|
@ -96,7 +96,7 @@ end
|
|||
OutputFileName={};
|
||||
|
||||
subplotnum = 0;
|
||||
for i=fpar:npar,
|
||||
for i=fpar:npar
|
||||
figunumber = 0;
|
||||
|
||||
for j=1:nvar
|
||||
|
@ -135,7 +135,7 @@ for i=fpar:npar,
|
|||
plot(1:options_.irf,HPDIRFdsgevar(:,1,j,i),'--k','linewidth',1)
|
||||
plot(1:options_.irf,HPDIRFdsgevar(:,2,j,i),'--k','linewidth',1)
|
||||
end
|
||||
% plot([1 options_.irf],[0 0],'-r','linewidth',0.5);
|
||||
% plot([1 options_.irf],[0 0],'-r','linewidth',0.5);
|
||||
box on
|
||||
axis tight
|
||||
xlim([1 options_.irf]);
|
||||
|
@ -153,16 +153,16 @@ for i=fpar:npar,
|
|||
if subplotnum == MaxNumberOfPlotPerFigure || (j == nvar && subplotnum> 0)
|
||||
figunumber = figunumber+1;
|
||||
dyn_saveas(hh,[DirectoryName '/' M_.fname '_Bayesian_IRF_' deblank(tit(i,:)) '_' int2str(figunumber)],options_.nodisplay,options_.graph_format);
|
||||
if RemoteFlag==1,
|
||||
if RemoteFlag==1
|
||||
OutputFileName = [OutputFileName; {[DirectoryName,filesep], [M_.fname '_Bayesian_IRF_' deblank(tit(i,:)) '_' int2str(figunumber) '.*']}];
|
||||
end
|
||||
subplotnum = 0;
|
||||
end
|
||||
end% loop over selected endo_var
|
||||
if whoiam,
|
||||
if whoiam
|
||||
fprintf('Done! \n');
|
||||
waitbarString = [ 'Exog. shocks ' int2str(i) '/' int2str(npar) ' done.'];
|
||||
% fMessageStatus((i-fpar+1)/(npar-fpar+1),whoiam,waitbarString, waitbarTitle, Parallel(ThisMatlab));
|
||||
% fMessageStatus((i-fpar+1)/(npar-fpar+1),whoiam,waitbarString, waitbarTitle, Parallel(ThisMatlab));
|
||||
dyn_waitbar((i-fpar+1)/(npar-fpar+1),[],waitbarString);
|
||||
end
|
||||
end% loop over exo_var
|
||||
|
|
|
@ -18,14 +18,14 @@ function ReshapeMatFiles(type, type2)
|
|||
% posterior
|
||||
% gsa
|
||||
% prior
|
||||
%
|
||||
%
|
||||
% OUTPUTS:
|
||||
% none
|
||||
% none
|
||||
%
|
||||
% SPECIAL REQUIREMENTS
|
||||
% none
|
||||
|
||||
% Copyright (C) 2003-2011 Dynare Team
|
||||
% Copyright (C) 2003-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -44,15 +44,15 @@ function ReshapeMatFiles(type, type2)
|
|||
|
||||
global M_ options_
|
||||
|
||||
if nargin==1,
|
||||
if nargin==1
|
||||
MhDirectoryName = [ CheckPath('metropolis',M_.dname) filesep ];
|
||||
else
|
||||
if strcmpi(type2,'posterior')
|
||||
MhDirectoryName = [CheckPath('metropolis',M_.dname) filesep ];
|
||||
elseif strcmpi(type2,'gsa')
|
||||
if options_.opt_gsa.morris==1,
|
||||
if options_.opt_gsa.morris==1
|
||||
MhDirectoryName = [CheckPath('gsa/screen',M_.dname) filesep ];
|
||||
elseif options_.opt_gsa.morris==2,
|
||||
elseif options_.opt_gsa.morris==2
|
||||
MhDirectoryName = [CheckPath('gsa/identif',M_.dname) filesep ];
|
||||
elseif options_.opt_gsa.pprior
|
||||
MhDirectoryName = [CheckPath(['gsa' filesep 'prior'],M_.dname) filesep ];
|
||||
|
@ -61,17 +61,17 @@ else
|
|||
end
|
||||
else
|
||||
MhDirectoryName = [CheckPath('prior',M_.dname) filesep ];
|
||||
end
|
||||
end
|
||||
end
|
||||
switch type
|
||||
case 'irf_dsge'
|
||||
CAPtype = 'IRF_DSGE';
|
||||
TYPEsize = [ options_.irf , size(options_.varlist,1) , M_.exo_nbr ];
|
||||
TYPEarray = 4;
|
||||
TYPEarray = 4;
|
||||
case 'irf_bvardsge'
|
||||
CAPtype = 'IRF_BVARDSGE';
|
||||
TYPEsize = [ options_.irf , length(options_.varobs) , M_.exo_nbr ];
|
||||
TYPEarray = 4;
|
||||
TYPEarray = 4;
|
||||
case 'smooth'
|
||||
CAPtype = 'SMOOTH';
|
||||
TYPEsize = [ M_.endo_nbr , options_.nobs ];
|
||||
|
@ -134,7 +134,7 @@ switch TYPEarray
|
|||
eval(['idx = idx + size(stock_' type ',4);'])
|
||||
end
|
||||
%eval(['STOCK_' CAPtype ' = sort(STOCK_' CAPtype ',4);'])
|
||||
save([MhDirectoryName M_.fname '_' CAPtype 's' int2str(NumberOfTYPEfiles-foffset+1) '.mat'],['STOCK_' CAPtype]);
|
||||
save([MhDirectoryName M_.fname '_' CAPtype 's' int2str(NumberOfTYPEfiles-foffset+1) '.mat'],['STOCK_' CAPtype]);
|
||||
end
|
||||
else
|
||||
load([MhDirectoryName M_.fname '_' type '1.mat']);
|
||||
|
@ -176,7 +176,7 @@ switch TYPEarray
|
|||
load([MhDirectoryName M_.fname '_' type '1.mat']);
|
||||
%eval(['STOCK_' CAPtype ' = sort(stock_' type ',3);'])
|
||||
eval(['STOCK_' CAPtype ' = stock_' type ';'])
|
||||
save([MhDirectoryName M_.fname '_' CAPtype 's' int2str(1) '.mat'],['STOCK_' CAPtype ]);
|
||||
save([MhDirectoryName M_.fname '_' CAPtype 's' int2str(1) '.mat'],['STOCK_' CAPtype ]);
|
||||
end
|
||||
% Original file format may be useful in some cases...
|
||||
% for file = 1:NumberOfTYPEfiles
|
||||
|
|
|
@ -3,15 +3,15 @@ function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff] = TaRB_optimiz
|
|||
% Wrapper function for target function used in TaRB algorithm; reassembles
|
||||
% full parameter vector before calling target function
|
||||
%
|
||||
% INPUTS
|
||||
% o optpar [double] (p_opt*1) vector of subset of parameters to be considered
|
||||
% o par_vector [double] (p*1) full vector of parameters
|
||||
% INPUTS
|
||||
% o optpar [double] (p_opt*1) vector of subset of parameters to be considered
|
||||
% o par_vector [double] (p*1) full vector of parameters
|
||||
% o parameterindices [double] (p_opt*1) index of optpar entries in
|
||||
% par_vector
|
||||
% o TargetFun [char] string specifying the name of the objective
|
||||
% function (posterior kernel).
|
||||
% o varargin [structure] other inputs of target function
|
||||
%
|
||||
%
|
||||
% OUTPUTS
|
||||
% o fval [scalar] value of (minus) the likelihood.
|
||||
% o info [double] (p*2) error code vector
|
||||
|
@ -20,8 +20,9 @@ function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff] = TaRB_optimiz
|
|||
% o Hess [double] (p*p) asymptotic Hessian matrix.
|
||||
% o SteadyState [double] Vector of doubles, steady state level for the endogenous variables.
|
||||
% o trend_coeff [double] Matrix of doubles, coefficients of the deterministic trend in the measurement equation
|
||||
%
|
||||
% Copyright (C) 2015-16 Dynare Team
|
||||
%
|
||||
|
||||
% Copyright (C) 2015-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -40,4 +41,3 @@ function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff] = TaRB_optimiz
|
|||
|
||||
par_vector(parameterindices,:)=optpar; %reassemble parameter
|
||||
[fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff] = feval(TargetFun,par_vector,varargin{:}); %call target function
|
||||
|
||||
|
|
|
@ -2,19 +2,19 @@ function [] = Tracing()
|
|||
% DESCRIPTION
|
||||
% This function is used to test the correct execution of a matlab section
|
||||
% on remote machine.
|
||||
%
|
||||
%
|
||||
% If no error happen the function simply create a file.
|
||||
%
|
||||
% INPUTS
|
||||
% ...
|
||||
%
|
||||
%
|
||||
% OUTPUTS
|
||||
% ...
|
||||
%
|
||||
%
|
||||
% SPECIAL REQUIREMENTS
|
||||
% none
|
||||
|
||||
% Copyright (C) 2010 Dynare Team
|
||||
% Copyright (C) 2010-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
function [oo_] = UnivariateSpectralDensity(M_,oo_,options_,var_list)
|
||||
% This function computes the theoretical spectral density of each
|
||||
% endogenous variable declared in var_list. Results are stored in
|
||||
% oo_.SpectralDensity and may be plotted. Plots are saved into the
|
||||
% graphs-folder.
|
||||
%
|
||||
% endogenous variable declared in var_list. Results are stored in
|
||||
% oo_.SpectralDensity and may be plotted. Plots are saved into the
|
||||
% graphs-folder.
|
||||
%
|
||||
% INPUTS
|
||||
% M_ [structure] Dynare's model structure
|
||||
% oo_ [structure] Dynare's results structure
|
||||
% options_ [structure] Dynare's options structure
|
||||
% var_list [integer] Vector of indices for a subset of variables.
|
||||
%
|
||||
%
|
||||
% OUTPUTS
|
||||
% oo_ [structure] Dynare's results structure,
|
||||
% containing the subfield
|
||||
|
@ -17,7 +17,7 @@ function [oo_] = UnivariateSpectralDensity(M_,oo_,options_,var_list)
|
|||
% and density, which are of size nvar*ngrid.
|
||||
%
|
||||
|
||||
% Adapted from th_autocovariances.m.
|
||||
% Adapted from th_autocovariances.m.
|
||||
|
||||
% Copyright (C) 2006-2017 Dynare Team
|
||||
%
|
||||
|
@ -38,7 +38,7 @@ function [oo_] = UnivariateSpectralDensity(M_,oo_,options_,var_list)
|
|||
|
||||
|
||||
if options_.order > 1
|
||||
disp('UnivariateSpectralDensity :: I Cannot compute the theoretical spectral density')
|
||||
disp('UnivariateSpectralDensity :: I Cannot compute the theoretical spectral density')
|
||||
disp('with a second order approximation of the DSGE model!')
|
||||
disp('Please set order = 1. I abort')
|
||||
return
|
||||
|
@ -102,7 +102,7 @@ if ~isempty(u)
|
|||
ivar = oo_.dr.order_var(iky);
|
||||
end
|
||||
|
||||
iky = iv(ivar);
|
||||
iky = iv(ivar);
|
||||
aa = ghx(iky,:);
|
||||
bb = ghu(iky,:);
|
||||
ngrid = options_.hp_ngrid; %number of grid points
|
||||
|
@ -112,7 +112,7 @@ tneg = exp(-sqrt(-1)*freqs); %negative frequencies
|
|||
if options_.one_sided_hp_filter
|
||||
error('UnivariateSpectralDensity:: spectral density estimate not available with one-sided HP filter')
|
||||
elseif options_.hp_filter == 0 && ~options_.bandpass.indicator %do not filter
|
||||
filter_gain=ones(ngrid,1);
|
||||
filter_gain=ones(ngrid,1);
|
||||
elseif ~(options_.hp_filter == 0 && ~options_.bandpass.indicator) && options_.bandpass.indicator %filter with bandpass
|
||||
filter_gain = zeros(1,ngrid);
|
||||
lowest_periodicity=options_.bandpass.passband(2);
|
||||
|
@ -122,7 +122,7 @@ elseif ~(options_.hp_filter == 0 && ~options_.bandpass.indicator) && options_.ba
|
|||
filter_gain(freqs<=-2*pi/lowest_periodicity+2*pi & freqs>=-2*pi/highest_periodicity+2*pi)=1;
|
||||
elseif ~(options_.hp_filter == 0 && ~options_.bandpass.indicator) && ~options_.bandpass.indicator %filter with HP-filter
|
||||
lambda = options_.hp_filter;
|
||||
filter_gain = 4*lambda*(1 - cos(freqs)).^2 ./ (1 + 4*lambda*(1 - cos(freqs)).^2);
|
||||
filter_gain = 4*lambda*(1 - cos(freqs)).^2 ./ (1 + 4*lambda*(1 - cos(freqs)).^2);
|
||||
end
|
||||
|
||||
mathp_col = NaN(ngrid,length(ivar)^2);
|
||||
|
@ -134,12 +134,12 @@ for ig = 1:ngrid
|
|||
g_omega = [aa*tneg(ig) bb]*f_omega*[aa'*tpos(ig); bb']; % selected variables
|
||||
f_hp = filter_gain(ig)^2*g_omega; % spectral density of selected filtered series
|
||||
mathp_col(ig,:) = (f_hp(:))'; % store as matrix row
|
||||
end;
|
||||
end
|
||||
|
||||
f = zeros(nvar,ngrid);
|
||||
for i=1:nvar
|
||||
f(i,:) = real(mathp_col(:,(i-1)*nvar+i)); %read out spectral density
|
||||
end
|
||||
end
|
||||
|
||||
oo_.SpectralDensity.freqs=freqs;
|
||||
oo_.SpectralDensity.density=f;
|
||||
|
@ -164,7 +164,7 @@ if options_.nograph == 0
|
|||
xlabel('0 \leq \omega \leq \pi')
|
||||
ylabel('f(\omega)')
|
||||
box on
|
||||
axis tight
|
||||
axis tight
|
||||
dyn_saveas(hh,[M_.fname ,filesep,'graphs', filesep, 'SpectralDensity_' deblank(M_.endo_names(ivar(i),:))],options_.nodisplay,options_.graph_format)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
function WriteShockDecomp2Excel(z,shock_names,endo_names,i_var,initial_date,DynareModel,DynareOptions,opts_decomp)
|
||||
%function WriteShockDecomp2Excel(z,shock_names,endo_names,i_var,initial_date,DynareModel,DynareOptions)
|
||||
% Saves the results from the shock_decomposition command to xls
|
||||
%
|
||||
%
|
||||
% Inputs
|
||||
% z [n_var*(nshock+2)*nperiods] shock decomposition array, see shock_decomposition.m for details
|
||||
% shock_names [endo_nbr*string length] shock names from M_.exo_names
|
||||
|
@ -42,14 +42,14 @@ end
|
|||
% number of components equals number of shocks + 1 (initial conditions)
|
||||
comp_nbr = size(z,2)-1;
|
||||
|
||||
if nargin==8 ,
|
||||
if nargin==8
|
||||
if isfield(opts_decomp,'steady_state')
|
||||
SteadyState = opts_decomp.steady_state;
|
||||
end
|
||||
if isfield(opts_decomp,'fig_mode') && ~isempty(opts_decomp.fig_mode)
|
||||
fig_mode = opts_decomp.fig_mode;
|
||||
fig_mode1 = ['_' fig_mode];
|
||||
fig_mode = [fig_mode '_'];
|
||||
fig_mode1 = ['_' fig_mode];
|
||||
fig_mode = [fig_mode '_'];
|
||||
end
|
||||
if isfield(opts_decomp,'screen_shocks')
|
||||
if use_shock_groups
|
||||
|
@ -60,15 +60,15 @@ if nargin==8 ,
|
|||
end
|
||||
if isfield(opts_decomp,'fig_name')
|
||||
fig_name = opts_decomp.fig_name;
|
||||
% fig_name = ['_' fig_name];
|
||||
fig_name1 = [fig_name];
|
||||
fig_name = [fig_name '_'];
|
||||
% fig_name = ['_' fig_name];
|
||||
fig_name1 = [fig_name];
|
||||
fig_name = [fig_name '_'];
|
||||
end
|
||||
if screen_shocks
|
||||
fig_name1 = [fig_name1 '_screen'];
|
||||
fig_name = [fig_name 'screen_'];
|
||||
fig_name1 = [fig_name1 '_screen'];
|
||||
fig_name = [fig_name 'screen_'];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
gend = size(z,3);
|
||||
|
@ -84,7 +84,7 @@ end
|
|||
nvar = length(i_var);
|
||||
|
||||
labels = char(char(shock_names),'Initial values');
|
||||
if ~(screen_shocks && comp_nbr>18),
|
||||
if ~(screen_shocks && comp_nbr>18)
|
||||
screen_shocks=0;
|
||||
end
|
||||
comp_nbr0=comp_nbr;
|
||||
|
@ -92,14 +92,14 @@ comp_nbr0=comp_nbr;
|
|||
for j=1:nvar
|
||||
d0={};
|
||||
z1 = squeeze(z(i_var(j),:,:));
|
||||
if screen_shocks,
|
||||
if screen_shocks
|
||||
[junk, isort] = sort(mean(abs(z1(1:end-2,:)')), 'descend');
|
||||
labels = char(char(shock_names(isort(1:16),:)),'Others', 'Initial values');
|
||||
zres = sum(z1(isort(17:end),:),1);
|
||||
z1 = [z1(isort(1:16),:); zres; z1(comp_nbr0:end,:)];
|
||||
comp_nbr=18;
|
||||
end
|
||||
|
||||
|
||||
d0(1,:)=[{'Decomposition'} cellstr(labels(1:comp_nbr,:))' {'Smoot Var'}];
|
||||
d0=[d0; num2cell([x' z1'])];
|
||||
LastRow=size(d0,1);
|
||||
|
@ -107,12 +107,12 @@ for j=1:nvar
|
|||
d0(LastRow+2,1)={'Legend.'};
|
||||
d0(LastRow+2,2)={'Shocks include:'};
|
||||
d0(LastRow+3:LastRow+3+comp_nbr-1,1)=cellstr(labels(1:comp_nbr,:));
|
||||
for ic=1:comp_nbr,
|
||||
for ic=1:comp_nbr
|
||||
group_members = shock_groups.(shock_ind{ic}).shocks;
|
||||
d0(LastRow+2+ic,2:1+length(group_members))=group_members;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
warning off
|
||||
if ~ismac
|
||||
[STATUS,MESSAGE] = xlswrite([DynareModel.fname,'_shock_decomposition',fig_mode,fig_name1],d0,deblank(endo_names(i_var(j),:)));
|
||||
|
@ -122,6 +122,5 @@ for j=1:nvar
|
|||
warning on
|
||||
|
||||
clear d0
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,7 +1,24 @@
|
|||
function title=add_filter_subtitle(title,options_)
|
||||
|
||||
% Copyright (C) 2015-2017 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
if ~options_.hp_filter && ~options_.one_sided_hp_filter && ~options_.bandpass.indicator %do not filter
|
||||
%nothing to add here
|
||||
%nothing to add here
|
||||
elseif ~options_.hp_filter && ~options_.one_sided_hp_filter && options_.bandpass.indicator
|
||||
title = [title ' (Bandpass filter, (' ...
|
||||
num2str(options_.bandpass.passband(1)),' ',num2str(options_.bandpass.passband(2)), '))'];
|
||||
|
@ -10,6 +27,6 @@ elseif options_.hp_filter && ~options_.one_sided_hp_filter && ~options_.bandpas
|
|||
num2str(options_.hp_filter) ')'];
|
||||
elseif ~options_.hp_filter && options_.one_sided_hp_filter && ~options_.bandpass.indicator
|
||||
title = [title ' (One-sided HP filter, lambda = ' ...
|
||||
num2str(options_.one_sided_hp_filter) ')'];
|
||||
num2str(options_.one_sided_hp_filter) ')'];
|
||||
end
|
||||
end
|
|
@ -1,5 +1,5 @@
|
|||
function mexpath = add_path_to_mex_files(dynareroot, modifypath)
|
||||
|
||||
|
||||
% Copyright (C) 2015-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
|
@ -20,7 +20,7 @@ function mexpath = add_path_to_mex_files(dynareroot, modifypath)
|
|||
if nargin<2
|
||||
modifypath = true;
|
||||
end
|
||||
|
||||
|
||||
if exist('OCTAVE_VERSION')
|
||||
if ispc() && strcmpi(computer(), 'i686-w64-mingw32')
|
||||
mexpath = {[dynareroot '../mex/octave32/']};
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
function [z, endo_names, endo_names_tex, steady_state, i_var, oo_] = annualized_shock_decomposition(oo_, M_, options_, i_var, t0, t1, realtime_, vintage_, steady_state, q2a, cumfix)
|
||||
% function oo_ = annualized_shock_decomposition(oo_,t0,options_.nobs);
|
||||
% Computes annualized shocks contribution to a simulated trajectory. The fields set are
|
||||
% oo_.annualized_shock_decomposition, oo_.annualized_realtime_shock_decomposition,
|
||||
% oo_.annualized_realtime_conditional_shock_decomposition and oo_.annualized_realtime_forecast_shock_decomposition.
|
||||
% oo_.annualized_shock_decomposition, oo_.annualized_realtime_shock_decomposition,
|
||||
% oo_.annualized_realtime_conditional_shock_decomposition and oo_.annualized_realtime_forecast_shock_decomposition.
|
||||
% Subfields are arrays n_var by nshock+2 by nperiods. The
|
||||
% first nshock columns store the respective shock contributions, column n+1
|
||||
% stores the role of the initial conditions, while column n+2 stores the
|
||||
% value of the smoothed variables. Both the variables and shocks are stored
|
||||
% value of the smoothed variables. Both the variables and shocks are stored
|
||||
% in the order of endo_names and M_.exo_names, respectively.
|
||||
%
|
||||
% INPUTS
|
||||
% oo_: [structure] Storage of results
|
||||
% M_: [structure] Storage of model
|
||||
% opts: [structure] options for shock decomp
|
||||
% opts: [structure] options for shock decomp
|
||||
% i_var: [array] index of vars
|
||||
% t0: [integer] first period
|
||||
% t1: [integer] last period
|
||||
% realtime_: [integer]
|
||||
% realtime_: [integer]
|
||||
% vintage_: [integer]
|
||||
% steady_state: [array] steady state value of quarterly (log-) level vars
|
||||
% q2a: [structure] info on q2a
|
||||
%
|
||||
% OUTPUTS
|
||||
% z: [matrix] shock decomp to plot
|
||||
% z: [matrix] shock decomp to plot
|
||||
% endo_names: [char] updated var names
|
||||
% endo_names_tex: [char] updated TeX var names
|
||||
% steady_state: [array] updated stady state of vars
|
||||
|
@ -57,13 +57,13 @@ islog = q2a.islog;
|
|||
aux = q2a.aux;
|
||||
aux0 = aux;
|
||||
cumfix = q2a.cumfix;
|
||||
% usual shock decomp
|
||||
% usual shock decomp
|
||||
if isstruct(oo_)
|
||||
% z = oo_.shock_decomposition;
|
||||
myopts=options_;
|
||||
myopts.plot_shock_decomp.type='qoq';
|
||||
myopts.plot_shock_decomp.realtime=0;
|
||||
[z, junk] = plot_shock_decomposition(M_,oo_,myopts,[]);
|
||||
% z = oo_.shock_decomposition;
|
||||
myopts=options_;
|
||||
myopts.plot_shock_decomp.type='qoq';
|
||||
myopts.plot_shock_decomp.realtime=0;
|
||||
[z, junk] = plot_shock_decomposition(M_,oo_,myopts,[]);
|
||||
else
|
||||
z = oo_;
|
||||
end
|
||||
|
@ -75,7 +75,7 @@ if isfield(q2a,'name')
|
|||
if isfield(q2a,'tex_name')
|
||||
mytex = q2a.tex_name;
|
||||
end
|
||||
if mytype==2,
|
||||
if mytype==2
|
||||
gtxt = ['PHI' mytxt]; % inflation rate
|
||||
gtex = ['{\pi(' mytex ')}'];
|
||||
elseif mytype
|
||||
|
@ -101,7 +101,7 @@ if isstruct(aux)
|
|||
end
|
||||
yaux=aux.y;
|
||||
end
|
||||
if mytype==2,
|
||||
if mytype==2
|
||||
gtxt = 'PHI'; % inflation rate
|
||||
gtex = '\pi';
|
||||
elseif mytype
|
||||
|
@ -115,7 +115,7 @@ nterms = size(z,2);
|
|||
nfrcst = opts.forecast/4;
|
||||
|
||||
for j=1:nvar
|
||||
if j>1,
|
||||
if j>1
|
||||
endo_names = char(endo_names,[deblank(M_.endo_names(i_var(j),:)) '_A']);
|
||||
endo_names_tex = char(endo_names_tex,['{' deblank(M_.endo_names_tex(i_var(j),:)) '}^A']);
|
||||
gendo_names = char(gendo_names,[gtxt endo_names(j,:)]);
|
||||
|
@ -133,15 +133,15 @@ for j=1:nvar
|
|||
gendo_names_tex = [gtex '(' deblank(endo_names_tex(j,:)) ')'];
|
||||
end
|
||||
end
|
||||
for k =1:nterms,
|
||||
if isstruct(aux),
|
||||
for k =1:nterms
|
||||
if isstruct(aux)
|
||||
aux.y = squeeze(yaux(j,k,min((t0-3):-4:1):end));
|
||||
end
|
||||
[za(j,k,:), steady_state_a(j,1), gza(j,k,:), steady_state_ga(j,1)] = ...
|
||||
quarterly2annual(squeeze(z(j,k,min((t0-3):-4:1):end)),steady_state(j),GYTREND0,var_type,islog,aux);
|
||||
end
|
||||
ztmp=squeeze(za(j,:,:));
|
||||
if cumfix==0,
|
||||
if cumfix==0
|
||||
zscale = sum(ztmp(1:end-1,:))./ztmp(end,:);
|
||||
ztmp(1:end-1,:) = ztmp(1:end-1,:)./repmat(zscale,[nterms-1,1]);
|
||||
else
|
||||
|
@ -149,7 +149,7 @@ for j=1:nvar
|
|||
ztmp(end-1,:) = ztmp(end-1,:) + zres;
|
||||
end
|
||||
gztmp=squeeze(gza(j,:,:));
|
||||
if cumfix==0,
|
||||
if cumfix==0
|
||||
gscale = sum(gztmp(1:end-1,:))./ gztmp(end,:);
|
||||
gztmp(1:end-1,:) = gztmp(1:end-1,:)./repmat(gscale,[nterms-1,1]);
|
||||
else
|
||||
|
@ -160,7 +160,7 @@ for j=1:nvar
|
|||
gza(j,:,:) = gztmp;
|
||||
end
|
||||
|
||||
if q2a.plot ==1,
|
||||
if q2a.plot ==1
|
||||
z=gza;
|
||||
endo_names = gendo_names;
|
||||
endo_names_tex = gendo_names_tex;
|
||||
|
@ -176,159 +176,158 @@ end
|
|||
% end
|
||||
|
||||
% realtime
|
||||
if realtime_ && isstruct(oo_) && isfield(oo_, 'realtime_shock_decomposition'),
|
||||
init=1;
|
||||
for i=t0:4:t1,
|
||||
yr=floor(i/4);
|
||||
za=[];
|
||||
gza=[];
|
||||
if realtime_ && isstruct(oo_) && isfield(oo_, 'realtime_shock_decomposition')
|
||||
init=1;
|
||||
for i=t0:4:t1
|
||||
yr=floor(i/4);
|
||||
za=[];
|
||||
gza=[];
|
||||
myopts=options_;
|
||||
myopts.plot_shock_decomp.type='qoq';
|
||||
myopts.plot_shock_decomp.realtime=1;
|
||||
myopts.plot_shock_decomp.vintage=i;
|
||||
[z, steady_state_aux] = plot_shock_decomposition(M_,oo_,myopts,[]);
|
||||
z = z(i_var,:,:);
|
||||
if isstruct(aux)
|
||||
if ischar(aux0.y)
|
||||
[y_aux, steady_state_aux] = plot_shock_decomposition(M_,oo_,myopts,aux0.y);
|
||||
aux.y=y_aux;
|
||||
aux.yss=steady_state_aux;
|
||||
end
|
||||
yaux=aux.y;
|
||||
end
|
||||
nterms = size(z,2);
|
||||
|
||||
% z = oo_.realtime_shock_decomposition.(['time_' int2str(i)]);
|
||||
% z = z(i_var,:,:);
|
||||
|
||||
for j=1:nvar
|
||||
for k =nterms:-1:1,
|
||||
% if k<nterms
|
||||
% ztmp = squeeze(sum(z(j,[1:k-1,k+1:end-1],t0-4:end)));
|
||||
% else
|
||||
ztmp = squeeze(z(j,k,min((t0-3):-4:1):end));
|
||||
% end
|
||||
if isstruct(aux),
|
||||
aux.y = squeeze(yaux(j,k,min((t0-3):-4:1):end));
|
||||
if isstruct(aux)
|
||||
if ischar(aux0.y)
|
||||
[y_aux, steady_state_aux] = plot_shock_decomposition(M_,oo_,myopts,aux0.y);
|
||||
aux.y=y_aux;
|
||||
aux.yss=steady_state_aux;
|
||||
end
|
||||
[za(j,k,:), steady_state_a(j,1), gza(j,k,:), steady_state_ga(j,1)] = ...
|
||||
quarterly2annual(ztmp,steady_state(j),GYTREND0,var_type,islog,aux);
|
||||
% if k<nterms
|
||||
% za(j,k,:) = za(j,end,:) - za(j,k,:);
|
||||
% gza(j,k,:) = gza(j,end,:) - gza(j,k,:);
|
||||
% end
|
||||
|
||||
yaux=aux.y;
|
||||
end
|
||||
|
||||
ztmp=squeeze(za(j,:,:));
|
||||
nterms = size(z,2);
|
||||
|
||||
if cumfix==0,
|
||||
zscale = sum(ztmp(1:end-1,:))./ztmp(end,:);
|
||||
ztmp(1:end-1,:) = ztmp(1:end-1,:)./repmat(zscale,[nterms-1,1]);
|
||||
else
|
||||
zres = ztmp(end,:)-sum(ztmp(1:end-1,:));
|
||||
ztmp(end-1,:) = ztmp(end-1,:) + zres;
|
||||
% z = oo_.realtime_shock_decomposition.(['time_' int2str(i)]);
|
||||
% z = z(i_var,:,:);
|
||||
|
||||
for j=1:nvar
|
||||
for k =nterms:-1:1
|
||||
% if k<nterms
|
||||
% ztmp = squeeze(sum(z(j,[1:k-1,k+1:end-1],t0-4:end)));
|
||||
% else
|
||||
ztmp = squeeze(z(j,k,min((t0-3):-4:1):end));
|
||||
% end
|
||||
if isstruct(aux)
|
||||
aux.y = squeeze(yaux(j,k,min((t0-3):-4:1):end));
|
||||
end
|
||||
[za(j,k,:), steady_state_a(j,1), gza(j,k,:), steady_state_ga(j,1)] = ...
|
||||
quarterly2annual(ztmp,steady_state(j),GYTREND0,var_type,islog,aux);
|
||||
% if k<nterms
|
||||
% za(j,k,:) = za(j,end,:) - za(j,k,:);
|
||||
% gza(j,k,:) = gza(j,end,:) - gza(j,k,:);
|
||||
% end
|
||||
|
||||
end
|
||||
|
||||
ztmp=squeeze(za(j,:,:));
|
||||
|
||||
if cumfix==0
|
||||
zscale = sum(ztmp(1:end-1,:))./ztmp(end,:);
|
||||
ztmp(1:end-1,:) = ztmp(1:end-1,:)./repmat(zscale,[nterms-1,1]);
|
||||
else
|
||||
zres = ztmp(end,:)-sum(ztmp(1:end-1,:));
|
||||
ztmp(end-1,:) = ztmp(end-1,:) + zres;
|
||||
end
|
||||
|
||||
gztmp=squeeze(gza(j,:,:));
|
||||
if cumfix==0
|
||||
gscale = sum(gztmp(1:end-1,:))./ gztmp(end,:);
|
||||
gztmp(1:end-1,:) = gztmp(1:end-1,:)./repmat(gscale,[nterms-1,1]);
|
||||
else
|
||||
gres = gztmp(end,:) - sum(gztmp(1:end-1,:));
|
||||
gztmp(end-1,:) = gztmp(end-1,:)+gres;
|
||||
end
|
||||
|
||||
za(j,:,:) = ztmp;
|
||||
gza(j,:,:) = gztmp;
|
||||
end
|
||||
|
||||
gztmp=squeeze(gza(j,:,:));
|
||||
if cumfix==0,
|
||||
gscale = sum(gztmp(1:end-1,:))./ gztmp(end,:);
|
||||
gztmp(1:end-1,:) = gztmp(1:end-1,:)./repmat(gscale,[nterms-1,1]);
|
||||
|
||||
if q2a.plot ==1
|
||||
z=gza;
|
||||
elseif q2a.plot == 2
|
||||
z=za;
|
||||
else
|
||||
gres = gztmp(end,:) - sum(gztmp(1:end-1,:));
|
||||
gztmp(end-1,:) = gztmp(end-1,:)+gres;
|
||||
z=cat(1,za,gza);
|
||||
end
|
||||
|
||||
za(j,:,:) = ztmp;
|
||||
gza(j,:,:) = gztmp;
|
||||
end
|
||||
|
||||
if q2a.plot ==1,
|
||||
z=gza;
|
||||
elseif q2a.plot == 2
|
||||
z=za;
|
||||
else
|
||||
z=cat(1,za,gza);
|
||||
end
|
||||
|
||||
if init==1,
|
||||
oo_.annualized_realtime_shock_decomposition.pool = z;
|
||||
else
|
||||
oo_.annualized_realtime_shock_decomposition.pool(:,:,yr) = z(:,:,end-nfrcst);
|
||||
end
|
||||
oo_.annualized_realtime_shock_decomposition.(['yr_' int2str(yr)]) = z;
|
||||
|
||||
if opts.forecast
|
||||
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr)]) = z(:,:,end-nfrcst:end);
|
||||
if init>nfrcst
|
||||
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-nfrcst)]) = ...
|
||||
oo_.annualized_realtime_shock_decomposition.pool(:,:,yr-nfrcst:end) - ...
|
||||
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr-nfrcst)]);
|
||||
% fix others
|
||||
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-nfrcst)])(:,end-1,:) = ...
|
||||
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-nfrcst)])(:,end-1,:) + ...
|
||||
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr-nfrcst)])(:,end,:);
|
||||
% fix total
|
||||
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-nfrcst)])(:,end,:) = ...
|
||||
oo_.annualized_realtime_shock_decomposition.pool(:,end,yr-nfrcst:end);
|
||||
if i==t1
|
||||
for my_forecast_=(nfrcst-1):-1:1,
|
||||
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-my_forecast_)]) = ...
|
||||
oo_.annualized_realtime_shock_decomposition.pool(:,:,yr-my_forecast_:yr) - ...
|
||||
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,:,1:my_forecast_+1);
|
||||
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,end-1,:) = ...
|
||||
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,end,1:my_forecast_+1);
|
||||
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,end,:) = ...
|
||||
oo_.annualized_realtime_shock_decomposition.pool(:,end,yr-my_forecast_:yr);
|
||||
|
||||
if init==1
|
||||
oo_.annualized_realtime_shock_decomposition.pool = z;
|
||||
else
|
||||
oo_.annualized_realtime_shock_decomposition.pool(:,:,yr) = z(:,:,end-nfrcst);
|
||||
end
|
||||
oo_.annualized_realtime_shock_decomposition.(['yr_' int2str(yr)]) = z;
|
||||
|
||||
if opts.forecast
|
||||
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr)]) = z(:,:,end-nfrcst:end);
|
||||
if init>nfrcst
|
||||
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-nfrcst)]) = ...
|
||||
oo_.annualized_realtime_shock_decomposition.pool(:,:,yr-nfrcst:end) - ...
|
||||
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr-nfrcst)]);
|
||||
% fix others
|
||||
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-nfrcst)])(:,end-1,:) = ...
|
||||
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-nfrcst)])(:,end-1,:) + ...
|
||||
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr-nfrcst)])(:,end,:);
|
||||
% fix total
|
||||
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-nfrcst)])(:,end,:) = ...
|
||||
oo_.annualized_realtime_shock_decomposition.pool(:,end,yr-nfrcst:end);
|
||||
if i==t1
|
||||
for my_forecast_=(nfrcst-1):-1:1
|
||||
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-my_forecast_)]) = ...
|
||||
oo_.annualized_realtime_shock_decomposition.pool(:,:,yr-my_forecast_:yr) - ...
|
||||
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,:,1:my_forecast_+1);
|
||||
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,end-1,:) = ...
|
||||
oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,end,1:my_forecast_+1);
|
||||
oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,end,:) = ...
|
||||
oo_.annualized_realtime_shock_decomposition.pool(:,end,yr-my_forecast_:yr);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
% ztmp=oo_.realtime_shock_decomposition.pool(:,:,21:29)-oo_.realtime_forecast_shock_decomposition.time_21;
|
||||
|
||||
|
||||
|
||||
init=init+1;
|
||||
end
|
||||
% ztmp=oo_.realtime_shock_decomposition.pool(:,:,21:29)-oo_.realtime_forecast_shock_decomposition.time_21;
|
||||
|
||||
|
||||
switch realtime_
|
||||
|
||||
init=init+1;
|
||||
end
|
||||
|
||||
|
||||
switch realtime_
|
||||
|
||||
case 0
|
||||
case 0
|
||||
z = oo_.annualized_shock_decomposition;
|
||||
|
||||
case 1 % realtime
|
||||
|
||||
case 1 % realtime
|
||||
if vintage_
|
||||
z = oo_.annualized_realtime_shock_decomposition.(['yr_' int2str(floor(vintage_/4))]);
|
||||
else
|
||||
z = oo_.annualized_realtime_shock_decomposition.pool;
|
||||
end
|
||||
|
||||
case 2 % conditional
|
||||
|
||||
case 2 % conditional
|
||||
if vintage_
|
||||
z = oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(floor(vintage_/4))]);
|
||||
else
|
||||
error();
|
||||
end
|
||||
|
||||
case 3 % forecast
|
||||
|
||||
case 3 % forecast
|
||||
if vintage_
|
||||
z = oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(floor(vintage_/4))]);
|
||||
else
|
||||
error()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if q2a.plot ==0,
|
||||
if q2a.plot ==0
|
||||
i_var=1:2*nvar;
|
||||
steady_state = [steady_state_a;steady_state_ga];
|
||||
else
|
||||
i_var=1:nvar;
|
||||
if q2a.plot ==1,
|
||||
if q2a.plot ==1
|
||||
steady_state = steady_state_ga;
|
||||
else
|
||||
steady_state = steady_state_a;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -2,48 +2,48 @@ function [InnovationVariance,AutoregressiveParameters] = autoregressive_process_
|
|||
% This function computes the parameters of an AR(p) process from the variance and the autocorrelation function
|
||||
% (the first p terms) of this process.
|
||||
%
|
||||
% INPUTS
|
||||
% INPUTS
|
||||
% [1] Variance [double] scalar, variance of the variable.
|
||||
% [2] Rho [double] p*1 vector, the autocorelation function: \rho(1), \rho(2), ..., \rho(p).
|
||||
% [3] p [double] scalar, the number of lags in the AR process.
|
||||
%
|
||||
% OUTPUTS
|
||||
% OUTPUTS
|
||||
% [1] InnovationVariance [double] scalar, the variance of the innovation.
|
||||
% [2] AutoregressiveParameters [double] p*1 vector of autoregressive parameters.
|
||||
%
|
||||
% NOTES
|
||||
% NOTES
|
||||
%
|
||||
% The AR(p) model for {y_t} is:
|
||||
%
|
||||
% y_t = \phi_1 * y_{t-1} + \phi_2 * y_{t-2} + ... + \phi_p * y_{t-p} + e_t
|
||||
%
|
||||
% y_t = \phi_1 * y_{t-1} + \phi_2 * y_{t-2} + ... + \phi_p * y_{t-p} + e_t
|
||||
%
|
||||
% Let \gamma(0) and \rho(1), ..., \rho(2) be the variance and the autocorrelation function of {y_t}. This function
|
||||
% compute the variance of {e_t} and the \phi_i (i=1,...,p) from the variance and the autocorrelation function of {y_t}.
|
||||
% compute the variance of {e_t} and the \phi_i (i=1,...,p) from the variance and the autocorrelation function of {y_t}.
|
||||
% We know that:
|
||||
%
|
||||
%
|
||||
% \gamma(0) = \phi_1 \gamma(1) + ... + \phi_p \gamma(p) + \sigma^2
|
||||
%
|
||||
% where \sigma^2 is the variance of {e_t}. Equivalently we have:
|
||||
%
|
||||
% \sigma^2 = \gamma(0) (1-\rho(1)\phi_1 - ... - \rho(p)\phi_p)
|
||||
% \sigma^2 = \gamma(0) (1-\rho(1)\phi_1 - ... - \rho(p)\phi_p)
|
||||
%
|
||||
% We also have for any integer h>0:
|
||||
%
|
||||
%
|
||||
% \rho(h) = \phi_1 \rho(h-1) + ... + \phi_p \rho(h-p)
|
||||
%
|
||||
% We can write the equations for \rho(1), ..., \rho(p) using matrices. Let R be the p*p autocorelation
|
||||
% matrix and v be the p*1 vector gathering the first p terms of the autocorrelation function. We have:
|
||||
% matrix and v be the p*1 vector gathering the first p terms of the autocorrelation function. We have:
|
||||
%
|
||||
% v = R*PHI
|
||||
%
|
||||
%
|
||||
% where PHI is a p*1 vector with the autoregressive parameters of the AR(p) process. We can recover the autoregressive
|
||||
% parameters by inverting the autocorrelation matrix: PHI = inv(R)*v.
|
||||
%
|
||||
%
|
||||
% This function first computes the vector PHI by inverting R and computes the variance of the innovation by evaluating
|
||||
%
|
||||
% \sigma^2 = \gamma(0)*(1-PHI'*v)
|
||||
|
||||
% Copyright (C) 2009 Dynare Team
|
||||
% Copyright (C) 2009-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
function [endogenousvariables, exogenousvariables] = backward_model_inversion(constraints, exogenousvariables, initialconditions, endo_names, exo_names, freeinnovations, DynareModel, DynareOptions, DynareOutput)
|
||||
|
||||
% INPUTS
|
||||
% INPUTS
|
||||
% - constraints [dseries] with N constrained endogenous variables from t1 to t2.
|
||||
% - exogenousvariables [dseries] with Q exogenous variables.
|
||||
% - initialconditions [dseries] with M endogenous variables starting before t1 (M initialcond must contain at least the state variables).
|
||||
|
@ -8,11 +8,11 @@ function [endogenousvariables, exogenousvariables] = backward_model_inversion(co
|
|||
% - exo_names [cell] list of exogenous variable names.
|
||||
% - freeinstruments [cell] list of exogenous variable names used to control the constrained endogenous variables.
|
||||
%
|
||||
% OUTPUTS
|
||||
% OUTPUTS
|
||||
% - endogenous [dseries]
|
||||
% - exogenous [dseries]
|
||||
%
|
||||
% REMARKS
|
||||
% REMARKS
|
||||
|
||||
% Copyright (C) 2017 Dynare Team
|
||||
%
|
||||
|
|
|
@ -14,7 +14,7 @@ function plan = basic_plan(plan, exogenous, expectation_type, date, value)
|
|||
% plan [structure] Returns a structure containing the updated forecast scenario.
|
||||
%
|
||||
%
|
||||
% Copyright (C) 2013-2014 Dynare Team
|
||||
% Copyright (C) 2013-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -31,60 +31,60 @@ function plan = basic_plan(plan, exogenous, expectation_type, date, value)
|
|||
% You should have received a copy of the GNU General Public License
|
||||
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
if ~ischar(expectation_type) || size(expectation_type,1) ~= 1
|
||||
error(['in basic_plan the third argument should be a string containing the simulation type (''perfect_foresight'' or ''surprise'')']);
|
||||
end
|
||||
exogenous = strtrim(exogenous);
|
||||
ix = find(strcmp(exogenous, plan.exo_names));
|
||||
if isempty(ix)
|
||||
error(['in basic_plan the second argument ' exogenous ' is not an exogenous variable']);
|
||||
end;
|
||||
sdate = length(date);
|
||||
if sdate > 1
|
||||
if date(1) < plan.date(1) || date(end) > plan.date(end)
|
||||
error(['in basic_plan the fourth argument (date=' date ') must lay inside the plan.date ' plan.date]);
|
||||
end
|
||||
else
|
||||
if date < plan.date(1) || date > plan.date(end)
|
||||
error(['in basic_plan the fourth argument (date=' date ') must lay iside the plan.date ' plan.date]);
|
||||
end
|
||||
end
|
||||
if length(date) ~= length(value)
|
||||
error(['in basic_plan the number of dates (' int2str(length(date)) ') is not equal to the numbers of shock (' int2str(length(value)) ') for exogenous variable ' exogenous]);
|
||||
end
|
||||
if ~isempty(plan.options_cond_fcst_.controlled_varexo)
|
||||
common_var = find(ix == plan.options_cond_fcst_.controlled_varexo);
|
||||
if ~isempty(common_var)
|
||||
common_date = intersect(date, plan.constrained_date_{common_var});
|
||||
if ~isempty(common_date)
|
||||
[date_, i_date] = setdiff(date, common_date);
|
||||
value = value(i_date);
|
||||
if common_date.length > 1
|
||||
the_dates = [cell2mat(strings(common_date(1))) ':' cell2mat(strings(common_date(end)))];
|
||||
else
|
||||
the_dates = cell2mat(strings(common_date));
|
||||
end
|
||||
warning(['Impossible case: ' plan.exo_names{plan.options_cond_fcst_.controlled_varexo(common_var)} ' is used both as a shock and as an endogenous variable to control the path of ' plan.endo_names{plan.constrained_vars_(common_var)} ' at the dates ' the_dates]);
|
||||
warning('This shock will not be considered');
|
||||
end
|
||||
end
|
||||
end
|
||||
if isempty(plan.shock_vars_)
|
||||
plan.shock_vars_ = ix;
|
||||
if strcmp(expectation_type, 'perfect_foresight')
|
||||
plan.shock_perfect_foresight_ = 1;
|
||||
else
|
||||
plan.shock_perfect_foresight_ = 0;
|
||||
end
|
||||
else
|
||||
plan.shock_vars_ = [plan.shock_vars_ ; ix];
|
||||
if strcmp(expectation_type, 'perfect_foresight')
|
||||
plan.shock_perfect_foresight_ = [plan.shock_perfect_foresight_ ; 1];
|
||||
else
|
||||
plan.shock_perfect_foresight_ = [plan.shock_perfect_foresight_ ; 0];
|
||||
end
|
||||
end
|
||||
plan.shock_date_{length(plan.shock_date_) + 1} = date;
|
||||
plan.shock_str_date_{length(plan.shock_str_date_) + 1} = strings(date);
|
||||
plan.shock_int_date_{length(plan.shock_int_date_) + 1} = date - plan.date(1) + 1;
|
||||
plan.shock_paths_{length(plan.shock_paths_) + 1} = value;
|
||||
if ~ischar(expectation_type) || size(expectation_type,1) ~= 1
|
||||
error(['in basic_plan the third argument should be a string containing the simulation type (''perfect_foresight'' or ''surprise'')']);
|
||||
end
|
||||
exogenous = strtrim(exogenous);
|
||||
ix = find(strcmp(exogenous, plan.exo_names));
|
||||
if isempty(ix)
|
||||
error(['in basic_plan the second argument ' exogenous ' is not an exogenous variable']);
|
||||
end
|
||||
sdate = length(date);
|
||||
if sdate > 1
|
||||
if date(1) < plan.date(1) || date(end) > plan.date(end)
|
||||
error(['in basic_plan the fourth argument (date=' date ') must lay inside the plan.date ' plan.date]);
|
||||
end
|
||||
else
|
||||
if date < plan.date(1) || date > plan.date(end)
|
||||
error(['in basic_plan the fourth argument (date=' date ') must lay iside the plan.date ' plan.date]);
|
||||
end
|
||||
end
|
||||
if length(date) ~= length(value)
|
||||
error(['in basic_plan the number of dates (' int2str(length(date)) ') is not equal to the numbers of shock (' int2str(length(value)) ') for exogenous variable ' exogenous]);
|
||||
end
|
||||
if ~isempty(plan.options_cond_fcst_.controlled_varexo)
|
||||
common_var = find(ix == plan.options_cond_fcst_.controlled_varexo);
|
||||
if ~isempty(common_var)
|
||||
common_date = intersect(date, plan.constrained_date_{common_var});
|
||||
if ~isempty(common_date)
|
||||
[date_, i_date] = setdiff(date, common_date);
|
||||
value = value(i_date);
|
||||
if common_date.length > 1
|
||||
the_dates = [cell2mat(strings(common_date(1))) ':' cell2mat(strings(common_date(end)))];
|
||||
else
|
||||
the_dates = cell2mat(strings(common_date));
|
||||
end
|
||||
warning(['Impossible case: ' plan.exo_names{plan.options_cond_fcst_.controlled_varexo(common_var)} ' is used both as a shock and as an endogenous variable to control the path of ' plan.endo_names{plan.constrained_vars_(common_var)} ' at the dates ' the_dates]);
|
||||
warning('This shock will not be considered');
|
||||
end
|
||||
end
|
||||
end
|
||||
if isempty(plan.shock_vars_)
|
||||
plan.shock_vars_ = ix;
|
||||
if strcmp(expectation_type, 'perfect_foresight')
|
||||
plan.shock_perfect_foresight_ = 1;
|
||||
else
|
||||
plan.shock_perfect_foresight_ = 0;
|
||||
end
|
||||
else
|
||||
plan.shock_vars_ = [plan.shock_vars_ ; ix];
|
||||
if strcmp(expectation_type, 'perfect_foresight')
|
||||
plan.shock_perfect_foresight_ = [plan.shock_perfect_foresight_ ; 1];
|
||||
else
|
||||
plan.shock_perfect_foresight_ = [plan.shock_perfect_foresight_ ; 0];
|
||||
end
|
||||
end
|
||||
plan.shock_date_{length(plan.shock_date_) + 1} = date;
|
||||
plan.shock_str_date_{length(plan.shock_str_date_) + 1} = strings(date);
|
||||
plan.shock_int_date_{length(plan.shock_int_date_) + 1} = date - plan.date(1) + 1;
|
||||
plan.shock_paths_{length(plan.shock_paths_) + 1} = value;
|
||||
|
|
|
@ -4,14 +4,14 @@ function d = bksup0(c,ny,jcf,iyf,icf,periods)
|
|||
% INPUTS
|
||||
% ny: number of endogenous variables
|
||||
% jcf: variables index forward
|
||||
%
|
||||
%
|
||||
% OUTPUTS
|
||||
% d: vector of backsubstitution results
|
||||
%
|
||||
% SPECIAL REQUIREMENTS
|
||||
% none
|
||||
|
||||
% Copyright (C) 2003-2009 Dynare Team
|
||||
% Copyright (C) 2003-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
|
|
@ -5,14 +5,14 @@ function d = bksup1(c,ny,jcf,iyf,periods)
|
|||
% INPUTS
|
||||
% ny: number of endogenous variables
|
||||
% jcf: variables index forward
|
||||
%
|
||||
%
|
||||
% OUTPUTS
|
||||
% d: vector of backsubstitution results
|
||||
%
|
||||
% SPECIAL REQUIREMENTS
|
||||
% none
|
||||
|
||||
% Copyright (C) 2003-2010 Dynare Team
|
||||
% Copyright (C) 2003-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -40,4 +40,3 @@ for i = 2:periods
|
|||
end
|
||||
|
||||
d = c(:,jcf) ;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ function d1 = bksupk(ny,fid,jcf,icc1)
|
|||
% SPECIAL REQUIREMENTS
|
||||
% none
|
||||
|
||||
% Copyright (C) 2003-2011 Dynare Team
|
||||
% Copyright (C) 2003-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -68,7 +68,7 @@ while i <= options_.periods
|
|||
c = fread(fid,[jcf,ny],'float64')' ;
|
||||
|
||||
d1(ir) = c(:,jcf)-c(:,icf)*d1(irf) ;
|
||||
ir = ir-ny ;
|
||||
ir = ir-ny ;
|
||||
irf = irf-ny ;
|
||||
i = i+1;
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
function x = bseastr(s1,s2)
|
||||
|
||||
% Copyright (C) 2001-2009 Dynare Team
|
||||
% Copyright (C) 2001-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -33,16 +33,15 @@ for im = 1:m
|
|||
for i = 1:min(length(key),length(temp))
|
||||
if temp(i) > key(i)
|
||||
h = mid - 1 ;
|
||||
break
|
||||
break
|
||||
else
|
||||
l = mid + 1 ;
|
||||
break
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
x(im) = mid ;
|
||||
break
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ function bvar_density(maxnlags)
|
|||
% none
|
||||
|
||||
% Copyright (C) 2003-2007 Christopher Sims
|
||||
% Copyright (C) 2007-2016 Dynare Team
|
||||
% Copyright (C) 2007-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -37,16 +37,16 @@ for nlags = 1:maxnlags
|
|||
[ny, nx, posterior, prior] = bvar_toolbox(nlags);
|
||||
oo_.bvar.posterior{nlags}=posterior;
|
||||
oo_.bvar.prior{nlags}=prior;
|
||||
|
||||
|
||||
posterior_int = matrictint(posterior.S, posterior.df, posterior.XXi);
|
||||
prior_int = matrictint(prior.S, prior.df, prior.XXi);
|
||||
|
||||
|
||||
lik_nobs = posterior.df - prior.df;
|
||||
|
||||
|
||||
log_dnsty = posterior_int - prior_int - 0.5*ny*lik_nobs*log(2*pi);
|
||||
|
||||
|
||||
oo_.bvar.log_marginal_data_density(nlags)=log_dnsty;
|
||||
|
||||
|
||||
skipline()
|
||||
fprintf('The marginal log density of the BVAR(%g) model is equal to %10.4f\n', ...
|
||||
nlags, log_dnsty);
|
||||
|
@ -61,7 +61,7 @@ function w = matrictint(S, df, XXi)
|
|||
% S: parameter of inverse-Wishart distribution
|
||||
% df: number of degrees of freedom of inverse-Wishart distribution
|
||||
% XXi: first component of VCV matrix of matrix-normal distribution
|
||||
%
|
||||
%
|
||||
% Computes the integral over (Phi, Sigma) of:
|
||||
%
|
||||
% det(Sigma)^(-k/2)*exp(-0.5*Tr((Phi-PhiHat)'*(XXi)^(-1)*(Phi-PhiHat)*Sigma^(-1)))*
|
||||
|
|
|
@ -54,7 +54,7 @@ p = 0;
|
|||
% Loop counter initialization
|
||||
d = 0;
|
||||
while d <= options_.bvar_replic
|
||||
|
||||
|
||||
Sigma = rand_inverse_wishart(ny, posterior.df, S_inv_upper_chol);
|
||||
|
||||
% Option 'lower' of chol() not available in old versions of
|
||||
|
@ -62,15 +62,15 @@ while d <= options_.bvar_replic
|
|||
Sigma_lower_chol = chol(Sigma)';
|
||||
|
||||
Phi = rand_matrix_normal(k, ny, posterior.PhiHat, Sigma_lower_chol, XXi_lower_chol);
|
||||
|
||||
|
||||
% All the eigenvalues of the companion matrix have to be on or inside the unit circle
|
||||
Companion_matrix(1:ny,:) = Phi(1:ny*nlags,:)';
|
||||
Companion_matrix(1:ny,:) = Phi(1:ny*nlags,:)';
|
||||
test = (abs(eig(Companion_matrix)));
|
||||
if any(test>1.0000000000001)
|
||||
p = p+1;
|
||||
end
|
||||
d = d+1;
|
||||
|
||||
|
||||
% Without shocks
|
||||
lags_data = forecast_data.initval;
|
||||
for t = 1:options_.forecast
|
||||
|
@ -80,7 +80,7 @@ while d <= options_.bvar_replic
|
|||
lags_data(end,:) = y;
|
||||
sims_no_shock(t, :, d) = y;
|
||||
end
|
||||
|
||||
|
||||
% With shocks
|
||||
lags_data = forecast_data.initval;
|
||||
for t = 1:options_.forecast
|
||||
|
@ -120,9 +120,9 @@ dyn_graph=dynare_graph_init(sprintf('BVAR forecasts (nlags = %d)', nlags), ny, {
|
|||
|
||||
for i = 1:ny
|
||||
dyn_graph=dynare_graph(dyn_graph,[ sims_no_shock_median(:, i) ...
|
||||
sims_no_shock_up_conf(:, i) sims_no_shock_down_conf(:, i) ...
|
||||
sims_with_shocks_up_conf(:, i) sims_with_shocks_down_conf(:, i) ], ...
|
||||
options_.varobs{i});
|
||||
sims_no_shock_up_conf(:, i) sims_no_shock_down_conf(:, i) ...
|
||||
sims_with_shocks_up_conf(:, i) sims_with_shocks_down_conf(:, i) ], ...
|
||||
options_.varobs{i});
|
||||
end
|
||||
|
||||
dyn_saveas(dyn_graph.fh,[OutputDirectoryName '/' M_.fname '_BVAR_forecast_',num2str(nlags)],options_.nodisplay,options_.graph_format)
|
||||
|
@ -130,9 +130,9 @@ dyn_saveas(dyn_graph.fh,[OutputDirectoryName '/' M_.fname '_BVAR_forecast_',num2
|
|||
% Compute RMSE
|
||||
|
||||
if ~isempty(forecast_data.realized_val)
|
||||
|
||||
|
||||
sq_err_cumul = zeros(1, ny);
|
||||
|
||||
|
||||
lags_data = forecast_data.initval;
|
||||
for t = 1:size(forecast_data.realized_val, 1)
|
||||
X = [ reshape(flipdim(lags_data, 1)', 1, ny*nlags) forecast_data.realized_xdata(t, :) ];
|
||||
|
@ -141,14 +141,14 @@ if ~isempty(forecast_data.realized_val)
|
|||
lags_data(end,:) = y;
|
||||
sq_err_cumul = sq_err_cumul + (y - forecast_data.realized_val(t, :)) .^ 2;
|
||||
end
|
||||
|
||||
|
||||
rmse = sqrt(sq_err_cumul / size(forecast_data.realized_val, 1));
|
||||
|
||||
|
||||
fprintf('RMSE of BVAR(%d):\n', nlags);
|
||||
|
||||
|
||||
for i = 1:length(options_.varobs)
|
||||
fprintf('%s: %10.4f\n', options_.varobs{i}, rmse(i));
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% Store results
|
||||
|
|
|
@ -11,7 +11,7 @@ function bvar_irf(nlags,identification)
|
|||
% SPECIAL REQUIREMENTS
|
||||
% none
|
||||
|
||||
% Copyright (C) 2007-2012 Dynare Team
|
||||
% Copyright (C) 2007-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -54,7 +54,7 @@ p = 0;
|
|||
sampled_irfs = NaN(ny, ny, options_.irf, options_.bvar_replic);
|
||||
|
||||
for draw=1:options_.bvar_replic
|
||||
|
||||
|
||||
% Get a covariance matrix from an inverted Wishart distribution.
|
||||
Sigma = rand_inverse_wishart(ny, posterior.df, S_inv_upper_chol);
|
||||
Sigma_upper_chol = chol(Sigma);
|
||||
|
@ -62,10 +62,10 @@ for draw=1:options_.bvar_replic
|
|||
|
||||
% Get the Autoregressive matrices from a matrix variate distribution.
|
||||
Phi = rand_matrix_normal(k, ny, posterior.PhiHat, Sigma_lower_chol, XXi_lower_chol);
|
||||
|
||||
|
||||
% Form the companion matrix.
|
||||
Companion_matrix(1:ny,:) = transpose(Phi(1:ny*nlags,:));
|
||||
|
||||
Companion_matrix(1:ny,:) = transpose(Phi(1:ny*nlags,:));
|
||||
|
||||
% All the eigenvalues of the companion matrix have to be on or
|
||||
% inside the unit circle to rule out explosive time series.
|
||||
test = (abs(eig(Companion_matrix)));
|
||||
|
@ -78,7 +78,7 @@ for draw=1:options_.bvar_replic
|
|||
elseif strcmpi(identification,'SquareRoot')
|
||||
StructuralMat = sqrtm(Sigma);
|
||||
end
|
||||
|
||||
|
||||
% Build the IRFs...
|
||||
lags_data = zeros(ny,ny*nlags) ;
|
||||
sampled_irfs(:,:,1,draw) = Sigma_lower_chol ;
|
||||
|
@ -88,7 +88,7 @@ for draw=1:options_.bvar_replic
|
|||
lags_data(:,ny+1:end) = lags_data(:,1:end-ny) ;
|
||||
lags_data(:,1:ny) = sampled_irfs(:,:,t,draw) ;
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
if p > 0
|
||||
|
@ -106,7 +106,7 @@ sort_idx = round((0.5 + [-options_.bvar.conf_sig, options_.bvar.conf_sig, .0]/2)
|
|||
|
||||
posterior_down_conf_irfs = sorted_irfs(:,:,:,sort_idx(1));
|
||||
posterior_up_conf_irfs = sorted_irfs(:,:,:,sort_idx(2));
|
||||
posterior_median_irfs = sorted_irfs(:,:,:,sort_idx(3));
|
||||
posterior_median_irfs = sorted_irfs(:,:,:,sort_idx(3));
|
||||
|
||||
number_of_columns = fix(sqrt(ny));
|
||||
number_of_rows = ceil(ny / number_of_columns) ;
|
||||
|
|
|
@ -29,7 +29,7 @@ function [ny, nx, posterior, prior, forecast_data] = bvar_toolbox(nlags)
|
|||
% forecasting, of size options_.forecast*nx (actually only
|
||||
% contains "1" values for the constant term if nx ~= 0)
|
||||
% - realized_val: only non-empty if options_.nobs doesn't point
|
||||
% to the end of sample
|
||||
% to the end of sample
|
||||
% In that case, contains values of endogenous variables after
|
||||
% options_.nobs and up to the end of the sample
|
||||
% - realized_xdata: contains values of exogenous variables after
|
||||
|
@ -42,7 +42,7 @@ function [ny, nx, posterior, prior, forecast_data] = bvar_toolbox(nlags)
|
|||
% - bvar_prior_{tau,decay,lambda,mu,omega,flat,train}
|
||||
|
||||
% Copyright (C) 2003-2007 Christopher Sims
|
||||
% Copyright (C) 2007-2012 Dynare Team
|
||||
% Copyright (C) 2007-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -67,7 +67,7 @@ options_ = set_default_option(options_, 'nobs', size(dataset,1)-options_.first_o
|
|||
|
||||
if (options_.first_obs+options_.nobs-1)> size(dataset,1)
|
||||
fprintf('Incorrect or missing specification of the number of observations. nobs can be at most %4u\n',size(dataset,1)-options_.first_obs+1);
|
||||
error('Inconsistent number of observations.')
|
||||
error('Inconsistent number of observations.')
|
||||
end
|
||||
|
||||
% Parameters for prior
|
||||
|
@ -160,7 +160,7 @@ function [ydum,xdum,breaks]=varprior(nv,nx,lags,mnprior,vprior)
|
|||
%function [ydum,xdum,breaks]=varprior(nv,nx,lags,mnprior,vprior)
|
||||
% ydum, xdum: dummy observation data that implement the prior
|
||||
% breaks: vector of points in the dummy data after which new dummy obs's start
|
||||
% Set breaks=T+[0;breaks], ydata=[ydata;ydum], xdum=[xdata;xdum], where
|
||||
% Set breaks=T+[0;breaks], ydata=[ydata;ydum], xdum=[xdata;xdum], where
|
||||
% actual data matrix has T rows, in preparing input for rfvar3
|
||||
% nv,nx,lags: VAR dimensions
|
||||
% mnprior.tight:Overall tightness of Minnesota prior
|
||||
|
@ -175,8 +175,8 @@ function [ydum,xdum,breaks]=varprior(nv,nx,lags,mnprior,vprior)
|
|||
% taken to include the sum-of-coefficients and co-persistence components
|
||||
% that are implemented directly in rfvar3.m. The diagonal prior on v, combined
|
||||
% with sum-of-coefficients and co-persistence components and with the unit own-first-lag
|
||||
% prior mean generates larger prior variances for own than for cross-effects even in
|
||||
% this formulation, but here there is no way to shrink toward a set of unconstrained
|
||||
% prior mean generates larger prior variances for own than for cross-effects even in
|
||||
% this formulation, but here there is no way to shrink toward a set of unconstrained
|
||||
% univariate AR's.
|
||||
|
||||
% Original file downloaded from:
|
||||
|
@ -228,9 +228,9 @@ function var=rfvar3(ydata,lags,xdata,breaks,lambda,mu)
|
|||
% discontinuities in the data (e.g. war years) and for the possibility of
|
||||
% adding dummy observations to implement a prior. This must be a column vector.
|
||||
% Note that a single dummy observation becomes lags+1 rows of the data matrix,
|
||||
% with a break separating it from the rest of the data. The function treats the
|
||||
% with a break separating it from the rest of the data. The function treats the
|
||||
% first lags observations at the top and after each "break" in ydata and xdata as
|
||||
% initial conditions.
|
||||
% initial conditions.
|
||||
% lambda: weight on "co-persistence" prior dummy observations. This expresses
|
||||
% belief that when data on *all* y's are stable at their initial levels, they will
|
||||
% tend to persist at that level. lambda=5 is a reasonable first try. With lambda<0,
|
||||
|
@ -243,7 +243,7 @@ function var=rfvar3(ydata,lags,xdata,breaks,lambda,mu)
|
|||
% one of these for each variable. A reasonable first guess is mu=2.
|
||||
% The program assumes that the first lags rows of ydata and xdata are real data, not dummies.
|
||||
% Dummy observations should go at the end, if any. If pre-sample x's are not available,
|
||||
% repeating the initial xdata(lags+1,:) row or copying xdata(lags+1:2*lags,:) into
|
||||
% repeating the initial xdata(lags+1,:) row or copying xdata(lags+1:2*lags,:) into
|
||||
% xdata(1:lags,:) are reasonable subsititutes. These values are used in forming the
|
||||
% persistence priors.
|
||||
|
||||
|
@ -280,7 +280,7 @@ for is = 1:length(smpl)
|
|||
end
|
||||
X = [X(:,:) xdata(smpl,:)];
|
||||
y = ydata(smpl,:);
|
||||
% Everything now set up with input data for y=Xb+e
|
||||
% Everything now set up with input data for y=Xb+e
|
||||
|
||||
% Add persistence dummies
|
||||
if lambda ~= 0 || mu > 0
|
||||
|
|
|
@ -5,7 +5,7 @@ function cprod = cartesian_product_of_sets(varargin)
|
|||
%! @deftypefn {Function File} {@var{cprod} =} cartesian_product_of_sets (@var{a},@var{b}, ...)
|
||||
%! @anchor{cartesian_product_of_sets}
|
||||
%! @sp 1
|
||||
%! Computes A_1 * A_2 * .... * A_n with a generic set A_i = {e_1,e_2,e_3,...} where e_i is a string
|
||||
%! Computes A_1 * A_2 * .... * A_n with a generic set A_i = {e_1,e_2,e_3,...} where e_i is a string
|
||||
%! or a number. It is assumed that each element e_i is unique in set A_i.
|
||||
%! @sp 2
|
||||
%! @strong{Inputs}
|
||||
|
@ -31,7 +31,7 @@ function cprod = cartesian_product_of_sets(varargin)
|
|||
%! @end deftypefn
|
||||
%@eod:
|
||||
|
||||
% Copyright (C) 2011-2012 Dynare Team
|
||||
% Copyright (C) 2011-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
|
|
@ -2,14 +2,14 @@ function cellofchar2mfile(fname, c, cname)
|
|||
|
||||
% Write a cell of char in a matlab script.
|
||||
%
|
||||
% INPUTS
|
||||
% INPUTS
|
||||
% - fname [string] name of the file where c is to be saved.
|
||||
% - c [cell] a two dimensional cell of char.
|
||||
%
|
||||
% OUTPUTS
|
||||
% OUTPUTS
|
||||
% None.
|
||||
|
||||
% Copyright (C) 2015 Dynare Team
|
||||
% Copyright (C) 2015-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue