Fixed indentation of c/h/cc/hh files.
parent
2f07c6f1db
commit
b4448937cc
|
@ -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:
|
||||
|
|
|
@ -30,11 +30,11 @@ using namespace std;
|
|||
//#define CUBLAS
|
||||
|
||||
#ifdef CUBLAS
|
||||
#include <cuda_runtime.h>
|
||||
#include <cublas_v2.h>
|
||||
# include <cuda_runtime.h>
|
||||
# include <cublas_v2.h>
|
||||
#endif
|
||||
void
|
||||
mexDisp(mxArray* P)
|
||||
mexDisp(mxArray *P)
|
||||
{
|
||||
unsigned int n = mxGetN(P);
|
||||
unsigned int m = mxGetM(P);
|
||||
|
@ -44,97 +44,95 @@ mexDisp(mxArray* P)
|
|||
for (unsigned int i = 0; i < m; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < n; j++)
|
||||
mexPrintf(" %9.4f",M[i+ j * m]);
|
||||
mexPrintf(" %9.4f", M[i+ j * m]);
|
||||
mexPrintf("\n");
|
||||
}
|
||||
mexEvalString("drawnow;");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mexDisp(double* M, int m, int n)
|
||||
mexDisp(double *M, int m, int n)
|
||||
{
|
||||
mexPrintf("%d x %d\n", m, n);
|
||||
mexEvalString("drawnow;");
|
||||
for (int i = 0; i < m; i++)
|
||||
{
|
||||
for (int j = 0; j < n; j++)
|
||||
mexPrintf(" %9.4f",M[i+ j * m]);
|
||||
mexPrintf(" %9.4f", M[i+ j * m]);
|
||||
mexPrintf("\n");
|
||||
}
|
||||
mexEvalString("drawnow;");
|
||||
}
|
||||
/*if block
|
||||
%nz_state_var = M_.nz_state_var;
|
||||
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)+QQ;
|
||||
end
|
||||
else
|
||||
F_singular = 0;
|
||||
dF = det(F);
|
||||
iF = inv(F);
|
||||
lik(t) = log(dF)+transpose(v)*iF*v;
|
||||
K = P(:,mf)*iF;
|
||||
a = T*(a+K*v);
|
||||
P = block_pred_Vcov_KF(mf, P, K, T, QQ);
|
||||
%P = T*(P-K*P(mf,:))*transpose(T)+QQ;
|
||||
notsteady = max(abs(K(:)-oldK)) > riccati_tol;
|
||||
oldK = K(:);
|
||||
end
|
||||
end;
|
||||
else
|
||||
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)+QQ;
|
||||
end
|
||||
else
|
||||
F_singular = 0;
|
||||
dF = det(F);
|
||||
iF = inv(F);
|
||||
lik(t) = log(dF)+transpose(v)*iF*v;
|
||||
K = P(:,mf)*iF;
|
||||
a = T*(a+K*v);
|
||||
P = T*(P-K*P(mf,:))*transpose(T)+QQ;
|
||||
notsteady = max(abs(K(:)-oldK)) > riccati_tol;
|
||||
oldK = K(:);
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
%nz_state_var = M_.nz_state_var;
|
||||
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)+QQ;
|
||||
end
|
||||
else
|
||||
F_singular = 0;
|
||||
dF = det(F);
|
||||
iF = inv(F);
|
||||
lik(t) = log(dF)+transpose(v)*iF*v;
|
||||
K = P(:,mf)*iF;
|
||||
a = T*(a+K*v);
|
||||
P = block_pred_Vcov_KF(mf, P, K, T, QQ);
|
||||
%P = T*(P-K*P(mf,:))*transpose(T)+QQ;
|
||||
notsteady = max(abs(K(:)-oldK)) > riccati_tol;
|
||||
oldK = K(:);
|
||||
end
|
||||
end;
|
||||
else
|
||||
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)+QQ;
|
||||
end
|
||||
else
|
||||
F_singular = 0;
|
||||
dF = det(F);
|
||||
iF = inv(F);
|
||||
lik(t) = log(dF)+transpose(v)*iF*v;
|
||||
K = P(:,mf)*iF;
|
||||
a = T*(a+K*v);
|
||||
P = T*(P-K*P(mf,:))*transpose(T)+QQ;
|
||||
notsteady = max(abs(K(:)-oldK)) > riccati_tol;
|
||||
oldK = K(:);
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
*/
|
||||
|
||||
bool
|
||||
not_all_abs_F_bellow_crit(double* F, int size, double crit)
|
||||
not_all_abs_F_bellow_crit(double *F, int size, double crit)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < size && abs(F[i])<crit)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
if (i < size)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
int i = 0;
|
||||
while (i < size && abs(F[i]) < crit)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
if (i < size)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
det(double* F, int dim, lapack_int* ipiv)
|
||||
det(double *F, int dim, lapack_int *ipiv)
|
||||
{
|
||||
double det = 1.0;
|
||||
for (int i = 0; i < dim; i++)
|
||||
|
@ -145,27 +143,25 @@ det(double* F, int dim, lapack_int* ipiv)
|
|||
return det;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[], double *P_mf[], double *v_pp[], double *K[], double *v_n[], double *a[], double *K_P[], double *P_t_t1[], double *tmp[], double *P[])
|
||||
{
|
||||
if (nlhs > 3)
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT("block_kalman_filter provides at most 3 output argument.");
|
||||
if (nrhs != 13 && nrhs != 16)
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT("block_kalman_filter requires exactly \n 13 input arguments for standard Kalman filter \nor\n 16 input arguments for missing observations Kalman filter.");
|
||||
if (nrhs == 16)
|
||||
if (nrhs == 16)
|
||||
missing_observations = true;
|
||||
else
|
||||
missing_observations = false;
|
||||
if (missing_observations)
|
||||
{
|
||||
if (! mxIsCell (prhs[0]))
|
||||
if (!mxIsCell(prhs[0]))
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT("the first input argument of block_missing_observations_kalman_filter must be a Cell Array.");
|
||||
pdata_index = prhs[0];
|
||||
if (! mxIsDouble (prhs[1]))
|
||||
if (!mxIsDouble(prhs[1]))
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT("the second input argument of block_missing_observations_kalman_filter must be a scalar.");
|
||||
number_of_observations = ceil(mxGetScalar(prhs[1]));
|
||||
if (! mxIsDouble (prhs[2]))
|
||||
if (!mxIsDouble(prhs[2]))
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT("the third input argument of block_missing_observations_kalman_filter must be a scalar.");
|
||||
no_more_missing_observations = ceil(mxGetScalar(prhs[2]));
|
||||
pT = mxDuplicateArray(prhs[3]);
|
||||
|
@ -175,10 +171,10 @@ BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const
|
|||
pP = mxDuplicateArray(prhs[7]);
|
||||
pY = mxDuplicateArray(prhs[8]);
|
||||
start = mxGetScalar(prhs[9]);
|
||||
mfd = (double*)mxGetData(prhs[10]);
|
||||
mfd = (double *) mxGetData(prhs[10]);
|
||||
kalman_tol = mxGetScalar(prhs[11]);
|
||||
riccati_tol = mxGetScalar(prhs[12]);
|
||||
nz_state_var = (double*)mxGetData(prhs[13]);
|
||||
nz_state_var = (double *) mxGetData(prhs[13]);
|
||||
n_diag = mxGetScalar(prhs[14]);
|
||||
pure_obs = mxGetScalar(prhs[15]);
|
||||
}
|
||||
|
@ -196,10 +192,10 @@ BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const
|
|||
n = mxGetN(pT); // Number of state variables.
|
||||
pp = mxGetM(pY); // Maximum number of observed variables.
|
||||
smpl = mxGetN(pY); // Sample size. ;
|
||||
mfd = (double*)mxGetData(prhs[7]);
|
||||
mfd = (double *) mxGetData(prhs[7]);
|
||||
kalman_tol = mxGetScalar(prhs[8]);
|
||||
riccati_tol = mxGetScalar(prhs[9]);
|
||||
nz_state_var = (double*)mxGetData(prhs[10]);
|
||||
nz_state_var = (double *) mxGetData(prhs[10]);
|
||||
n_diag = mxGetScalar(prhs[11]);
|
||||
pure_obs = mxGetScalar(prhs[12]);
|
||||
}
|
||||
|
@ -209,35 +205,32 @@ BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const
|
|||
H = mxGetPr(pH);
|
||||
*P = mxGetPr(pP);
|
||||
Y = mxGetPr(pY);
|
||||
|
||||
|
||||
n = mxGetN(pT); // Number of state variables.
|
||||
pp = mxGetM(pY); // Maximum number of observed variables.
|
||||
smpl = mxGetN(pY); // Sample size. ;
|
||||
n_state = n - pure_obs;
|
||||
|
||||
|
||||
|
||||
/*mexPrintf("T\n");
|
||||
mexDisp(pT);*/
|
||||
mexDisp(pT);*/
|
||||
|
||||
H_size = mxGetN(pH) * mxGetM(pH);
|
||||
|
||||
|
||||
|
||||
n_shocks = mxGetM(pQ);
|
||||
|
||||
|
||||
if (missing_observations)
|
||||
if (mxGetNumberOfElements(pdata_index) != (unsigned int)smpl)
|
||||
if (mxGetNumberOfElements(pdata_index) != (unsigned int) smpl)
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT("the number of element in the cell array passed to block_missing_observation_kalman_filter as first argument has to be equal to the smpl size");
|
||||
|
||||
i_nz_state_var = (int*)mxMalloc(n*sizeof(int));
|
||||
|
||||
i_nz_state_var = (int *) mxMalloc(n*sizeof(int));
|
||||
for (int i = 0; i < n; i++)
|
||||
i_nz_state_var[i] = nz_state_var[i];
|
||||
|
||||
pa = mxCreateDoubleMatrix(n, 1, mxREAL); // State vector.
|
||||
*a = mxGetPr(pa);
|
||||
tmp_a = (double*)mxMalloc(n * sizeof(double));
|
||||
tmp_a = (double *) mxMalloc(n * sizeof(double));
|
||||
dF = 0.0; // det(F).
|
||||
|
||||
|
||||
p_tmp1 = mxCreateDoubleMatrix(n, n_shocks, mxREAL);
|
||||
tmp1 = mxGetPr(p_tmp1);
|
||||
t = 0; // Initialization of the time index.
|
||||
|
@ -247,13 +240,13 @@ BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const
|
|||
LIK = 0.0; // Default value of the log likelihood.
|
||||
notsteady = true; // Steady state flag.
|
||||
F_singular = true;
|
||||
*v_pp = (double*)mxMalloc(pp * sizeof(double));
|
||||
*v_n = (double*)mxMalloc(n * sizeof(double));
|
||||
mf = (int*)mxMalloc(pp * sizeof(int));
|
||||
*v_pp = (double *) mxMalloc(pp * sizeof(double));
|
||||
*v_n = (double *) mxMalloc(n * sizeof(double));
|
||||
mf = (int *) mxMalloc(pp * sizeof(int));
|
||||
for (int i = 0; i < pp; i++)
|
||||
mf[i] = mfd[i] - 1;
|
||||
pi = atan2((double)0.0,(double)-1.0);
|
||||
|
||||
pi = atan2((double) 0.0, (double) -1.0);
|
||||
|
||||
/*compute QQ = R*Q*transpose(R)*/ // Variance of R times the vector of structural innovations.;
|
||||
// tmp = R * Q;
|
||||
for (int i = 0; i < n; i++)
|
||||
|
@ -277,7 +270,7 @@ BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const
|
|||
QQ[i + j * n] = QQ[j + i * n] = res;
|
||||
}
|
||||
mxDestroyArray(p_tmp1);
|
||||
|
||||
|
||||
pv = mxCreateDoubleMatrix(pp, 1, mxREAL);
|
||||
v = mxGetPr(pv);
|
||||
pF = mxCreateDoubleMatrix(pp, pp, mxREAL);
|
||||
|
@ -285,9 +278,9 @@ BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const
|
|||
piF = mxCreateDoubleMatrix(pp, pp, mxREAL);
|
||||
iF = mxGetPr(piF);
|
||||
lw = pp * 4;
|
||||
w = (double*)mxMalloc(lw * sizeof(double));
|
||||
iw = (lapack_int*)mxMalloc(pp * sizeof(lapack_int));
|
||||
ipiv = (lapack_int*)mxMalloc(pp * sizeof(lapack_int));
|
||||
w = (double *) mxMalloc(lw * sizeof(double));
|
||||
iw = (lapack_int *) mxMalloc(pp * sizeof(lapack_int));
|
||||
ipiv = (lapack_int *) mxMalloc(pp * sizeof(lapack_int));
|
||||
info = 0;
|
||||
#if defined(BLAS) || defined(CUBLAS)
|
||||
p_tmp = mxCreateDoubleMatrix(n, n, mxREAL);
|
||||
|
@ -298,8 +291,8 @@ BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const
|
|||
*K = mxGetPr(pK);
|
||||
p_K_P = mxCreateDoubleMatrix(n, n, mxREAL);
|
||||
*K_P = mxGetPr(p_K_P);
|
||||
oldK = (double*)mxMalloc(n * n * sizeof(double));
|
||||
*P_mf = (double*)mxMalloc(n * n * sizeof(double));
|
||||
oldK = (double *) mxMalloc(n * n * sizeof(double));
|
||||
*P_mf = (double *) mxMalloc(n * n * sizeof(double));
|
||||
for (int i = 0; i < n * n; i++)
|
||||
oldK[i] = Inf;
|
||||
#else
|
||||
|
@ -311,14 +304,14 @@ BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const
|
|||
*K = mxGetPr(pK);
|
||||
p_K_P = mxCreateDoubleMatrix(n_state, n_state, mxREAL);
|
||||
*K_P = mxGetPr(p_K_P);
|
||||
oldK = (double*)mxMalloc(n * pp * sizeof(double));
|
||||
*P_mf = (double*)mxMalloc(n * pp * sizeof(double));
|
||||
oldK = (double *) mxMalloc(n * pp * sizeof(double));
|
||||
*P_mf = (double *) mxMalloc(n * pp * sizeof(double));
|
||||
for (int i = 0; i < n * pp; i++)
|
||||
oldK[i] = Inf;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
BlockKalmanFilter::block_kalman_filter_ss(double *P_mf, double *v_pp, double *K, double *v_n, double *a, double *K_P, double *P_t_t1, double *tmp, double *P)
|
||||
{
|
||||
if (t+1 < smpl)
|
||||
|
@ -328,7 +321,7 @@ BlockKalmanFilter::block_kalman_filter_ss(double *P_mf, double *v_pp, double *K,
|
|||
//v = Y(:,t)-a(mf);
|
||||
for (int i = 0; i < pp; i++)
|
||||
v[i] = Y[i + t * pp] - a[mf[i]];
|
||||
|
||||
|
||||
//a = T*(a+K*v);
|
||||
for (int i = pure_obs; i < n; i++)
|
||||
{
|
||||
|
@ -344,7 +337,7 @@ BlockKalmanFilter::block_kalman_filter_ss(double *P_mf, double *v_pp, double *K,
|
|||
res += T[j * n + i] * v_n[j];
|
||||
a[i] = res;
|
||||
}
|
||||
|
||||
|
||||
//lik(t) = transpose(v)*iF*v;
|
||||
for (int i = 0; i < pp; i++)
|
||||
{
|
||||
|
@ -371,19 +364,19 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
{
|
||||
while (notsteady && t < smpl)
|
||||
{
|
||||
if(missing_observations)
|
||||
if (missing_observations)
|
||||
{
|
||||
|
||||
// retrieve the d_index
|
||||
pd_index = mxGetCell( pdata_index, t);
|
||||
dd_index = (double*)mxGetData(pd_index);
|
||||
pd_index = mxGetCell(pdata_index, t);
|
||||
dd_index = (double *) mxGetData(pd_index);
|
||||
size_d_index = mxGetM(pd_index);
|
||||
d_index.resize(size_d_index);
|
||||
for (int i = 0; i < size_d_index; i++)
|
||||
{
|
||||
d_index[i] = ceil(dd_index[i]) - 1;
|
||||
}
|
||||
|
||||
|
||||
//v = Y(:,t) - a(mf)
|
||||
int i_i = 0;
|
||||
//#pragma omp parallel for shared(v, i_i, d_index) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
|
@ -393,8 +386,7 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
v[i_i] = Y[*i + t * pp] - a[mf[*i]];
|
||||
i_i++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//F = P(mf,mf) + H;
|
||||
i_i = 0;
|
||||
if (H_size == 1)
|
||||
|
@ -417,16 +409,16 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
iF[i_i + j_j * size_d_index] = F[i_i + j_j * size_d_index] = P[mf[*i] + mf[*j] * n] + H[*i + *j * pp];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
size_d_index = pp;
|
||||
|
||||
|
||||
//v = Y(:,t) - a(mf)
|
||||
for (int i = 0; i < pp; i++)
|
||||
v[i] = Y[i + t * pp] - a[mf[i]];
|
||||
|
||||
|
||||
//F = P(mf,mf) + H;
|
||||
if (H_size == 1)
|
||||
{
|
||||
|
@ -441,20 +433,21 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
iF[i + j * pp] = F[i + j * pp] = P[mf[i] + mf[j] * n] + H[i + j * pp];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Computes the norm of iF */
|
||||
double anorm = dlange("1", &size_d_index, &size_d_index, iF, &size_d_index, w);
|
||||
//mexPrintf("anorm = %f\n",anorm);
|
||||
|
||||
/* Modifies F in place with a LU decomposition */
|
||||
dgetrf(&size_d_index, &size_d_index, iF, &size_d_index, ipiv, &info);
|
||||
if (info != 0) mexPrintf("dgetrf failure with error %d\n", (int) info);
|
||||
|
||||
if (info != 0)
|
||||
mexPrintf("dgetrf failure with error %d\n", (int) info);
|
||||
|
||||
/* Computes the reciprocal norm */
|
||||
dgecon("1", &size_d_index, iF, &size_d_index, &anorm, &rcond, w, iw, &info);
|
||||
if (info != 0) mexPrintf("dgecon failure with error %d\n", (int) info);
|
||||
|
||||
if (info != 0)
|
||||
mexPrintf("dgecon failure with error %d\n", (int) info);
|
||||
|
||||
if (rcond < kalman_tol)
|
||||
if (not_all_abs_F_bellow_crit(F, size_d_index * size_d_index, kalman_tol)) //~all(abs(F(:))<kalman_tol)
|
||||
{
|
||||
|
@ -481,55 +474,56 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
res += T[i + j *n] * a[j];
|
||||
tmp_a[i] = res;
|
||||
}
|
||||
memcpy(a, tmp_a, n * sizeof(double));
|
||||
memcpy(a, tmp_a, n * sizeof(double));
|
||||
|
||||
//P = T*P*transpose(T)+QQ;
|
||||
memset(tmp, 0, n * n_state * sizeof(double));
|
||||
//P = T*P*transpose(T)+QQ;
|
||||
memset(tmp, 0, n * n_state * sizeof(double));
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
for (int j = pure_obs; j < n; j++)
|
||||
for (int i = 0; i < n; i++)
|
||||
for (int j = pure_obs; j < n; j++)
|
||||
{
|
||||
int j1 = j - pure_obs;
|
||||
int j1_n_state = j1 * n_state - pure_obs;
|
||||
for (int k = pure_obs; k < i_nz_state_var[i]; k++)
|
||||
tmp[i + j1 * n ] += T[i + k * n] * P[k + j1_n_state];
|
||||
}
|
||||
|
||||
memset(P, 0, n * n * sizeof(double));
|
||||
int n_n_obs = n * pure_obs;
|
||||
for (int i = 0; i < n; i++)
|
||||
for (int j = i; j < n; j++)
|
||||
{
|
||||
for (int k = pure_obs; k < i_nz_state_var[j]; k++)
|
||||
{
|
||||
int k_n = k * n;
|
||||
P[i * n + j] += tmp[i + k_n - n_n_obs] * T[j + k_n];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
int j1 = j - pure_obs;
|
||||
int j1_n_state = j1 * n_state - pure_obs;
|
||||
for (int k = pure_obs; k < i_nz_state_var[i]; k++)
|
||||
tmp[i + j1 * n ] += T[i + k * n] * P[k + j1_n_state];
|
||||
for (int j = i; j < n; j++)
|
||||
P[j + i * n] += QQ[j + i * n];
|
||||
for (int j = i + 1; j < n; j++)
|
||||
P[i + j * n] = P[j + i * n];
|
||||
}
|
||||
|
||||
memset(P, 0, n * n * sizeof(double));
|
||||
int n_n_obs = n * pure_obs;
|
||||
for (int i = 0; i < n; i++)
|
||||
for (int j = i; j < n; j++)
|
||||
{
|
||||
for (int k = pure_obs; k < i_nz_state_var[j]; k++)
|
||||
{
|
||||
int k_n = k * n;
|
||||
P[i * n + j] += tmp[i + k_n - n_n_obs] * T[j + k_n];
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < n; i++)
|
||||
{
|
||||
for ( int j = i ; j < n; j++)
|
||||
P[j + i * n] += QQ[j + i * n];
|
||||
for ( int j = i + 1; j < n; j++)
|
||||
P[i + j * n] = P[j + i * n];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
F_singular = false;
|
||||
|
||||
|
||||
//dF = det(F);
|
||||
dF = det(iF, size_d_index, ipiv);
|
||||
|
||||
//iF = inv(F);
|
||||
//int lwork = 4/*2*/* pp;
|
||||
dgetri(&size_d_index, iF, &size_d_index, ipiv, w, &lw, &info);
|
||||
if (info != 0) mexPrintf("dgetri failure with error %d\n", (int) info);
|
||||
if (info != 0)
|
||||
mexPrintf("dgetri failure with error %d\n", (int) info);
|
||||
|
||||
//lik(t) = log(dF)+transpose(v)*iF*v;
|
||||
#ifdef USE_OMP
|
||||
#pragma omp parallel for shared(v_pp) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
# pragma omp parallel for shared(v_pp) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
#endif
|
||||
for (int i = 0; i < size_d_index; i++)
|
||||
{
|
||||
|
@ -550,7 +544,7 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
{
|
||||
//K = P(:,mf)*iF;
|
||||
#ifdef USE_OMP
|
||||
#pragma omp parallel for shared(P_mf) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
# pragma omp parallel for shared(P_mf) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
#endif
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
|
@ -567,9 +561,9 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
for (int j = 0; j < pp; j++)
|
||||
P_mf[i + j * n] = P[i + mf[j] * n];
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_OMP
|
||||
#pragma omp parallel for shared(K) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
# pragma omp parallel for shared(K) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
#endif
|
||||
for (int i = 0; i < n; i++)
|
||||
for (int j = 0; j < size_d_index; j++)
|
||||
|
@ -580,10 +574,10 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
res += P_mf[i + k * n] * iF[j_pp + k];
|
||||
K[i + j * n] = res;
|
||||
}
|
||||
|
||||
|
||||
//a = T*(a+K*v);
|
||||
#ifdef USE_OMP
|
||||
#pragma omp parallel for shared(v_n) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
# pragma omp parallel for shared(v_n) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
#endif
|
||||
for (int i = pure_obs; i < n; i++)
|
||||
{
|
||||
|
@ -592,9 +586,9 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
res += K[j * n + i] * v[j];
|
||||
v_n[i] = res + a[i];
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_OMP
|
||||
#pragma omp parallel for shared(a) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
# pragma omp parallel for shared(a) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
#endif
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
|
@ -603,7 +597,7 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
res += T[j * n + i] * v_n[j];
|
||||
a[i] = res;
|
||||
}
|
||||
|
||||
|
||||
if (missing_observations)
|
||||
{
|
||||
//P = T*(P-K*P(mf,:))*transpose(T)+QQ;
|
||||
|
@ -617,17 +611,17 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
{
|
||||
//P = T*(P-K*P(mf,:))*transpose(T)+QQ;
|
||||
#ifdef USE_OMP
|
||||
#pragma omp parallel for shared(P_mf) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
# pragma omp parallel for shared(P_mf) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
#endif
|
||||
for (int i = 0; i < pp; i++)
|
||||
for (int j = pure_obs; j < n; j++)
|
||||
P_mf[i + j * pp] = P[mf[i] + j * n];
|
||||
}
|
||||
|
||||
|
||||
#ifdef BLAS
|
||||
#ifdef USE_OMP
|
||||
#pragma omp parallel for shared(K_P) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
#endif
|
||||
# ifdef USE_OMP
|
||||
# pragma omp parallel for shared(K_P) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
# endif
|
||||
for (int i = 0; i < n; i++)
|
||||
for (int j = i; j < n; j++)
|
||||
{
|
||||
|
@ -649,7 +643,7 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
memcpy(P, QQ, n * n *sizeof(double));
|
||||
blas_int n_b = n;
|
||||
/*mexPrintf("sizeof(n_b)=%d, n_b=%d, sizeof(n)=%d, n=%d\n",sizeof(n_b),n_b,sizeof(n),n);
|
||||
mexEvalString("drawnow;");*/
|
||||
mexEvalString("drawnow;");*/
|
||||
dsymm("R", "U", &n_b, &n_b,
|
||||
&one, P_t_t1, &n_b,
|
||||
T, &n_b, &zero,
|
||||
|
@ -659,8 +653,8 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
T, &n_b, &one,
|
||||
P, &n_b);
|
||||
#else
|
||||
#ifdef CUBLAS
|
||||
for (int i = 0; i < n; i++)
|
||||
# ifdef CUBLAS
|
||||
for (int i = 0; i < n; i++)
|
||||
for (int j = i; j < n; j++)
|
||||
{
|
||||
double res = 0.0;
|
||||
|
@ -689,29 +683,29 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
return false;
|
||||
}
|
||||
/*int device;
|
||||
cudaGetDevice(&device);*/
|
||||
cudaGetDevice(&device);*/
|
||||
int n2 = n * n;
|
||||
double* d_A = 0;
|
||||
double* d_B = 0;
|
||||
double* d_C = 0;
|
||||
double* d_D = 0;
|
||||
double *d_A = 0;
|
||||
double *d_B = 0;
|
||||
double *d_C = 0;
|
||||
double *d_D = 0;
|
||||
// Allocate device memory for the matrices
|
||||
if (cudaMalloc((void**)&d_A, n2 * sizeof(double)) != cudaSuccess)
|
||||
if (cudaMalloc((void **) &d_A, n2 * sizeof(double)) != cudaSuccess)
|
||||
{
|
||||
mexPrintf("!!!! device memory allocation error (allocate A)\n");
|
||||
return false;
|
||||
}
|
||||
if (cudaMalloc((void**)&d_B, n2 * sizeof(d_B[0])) != cudaSuccess)
|
||||
if (cudaMalloc((void **) &d_B, n2 * sizeof(d_B[0])) != cudaSuccess)
|
||||
{
|
||||
mexPrintf("!!!! device memory allocation error (allocate B)\n");
|
||||
return false;
|
||||
}
|
||||
if (cudaMalloc((void**)&d_C, n2 * sizeof(d_C[0])) != cudaSuccess)
|
||||
if (cudaMalloc((void **) &d_C, n2 * sizeof(d_C[0])) != cudaSuccess)
|
||||
{
|
||||
mexPrintf("!!!! device memory allocation error (allocate C)\n");
|
||||
return false;
|
||||
}
|
||||
if (cudaMalloc((void**)&d_D, n2 * sizeof(d_D[0])) != cudaSuccess)
|
||||
if (cudaMalloc((void **) &d_D, n2 * sizeof(d_D[0])) != cudaSuccess)
|
||||
{
|
||||
mexPrintf("!!!! device memory allocation error (allocate D)\n");
|
||||
return false;
|
||||
|
@ -734,7 +728,7 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
{
|
||||
mexPrintf("!!!! device access error (write C)\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
mexPrintf("just before calling\n");
|
||||
mexEvalString("drawnow;");
|
||||
status = cublasSetVector(n2, sizeof(QQ[0]), QQ, 1, d_D, 1);
|
||||
|
@ -742,22 +736,22 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
{
|
||||
mexPrintf("!!!! device access error (write D)\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Performs operation using plain C code
|
||||
|
||||
cublasDsymm(handle, CUBLAS_SIDE_RIGHT, CUBLAS_FILL_MODE_UPPER, n, n,
|
||||
&one, d_A, n,
|
||||
d_B, n, &zero,
|
||||
d_C, n);
|
||||
&one, d_A, n,
|
||||
d_B, n, &zero,
|
||||
d_C, n);
|
||||
/*dgemm("N", "T", &n_b, &n_b,
|
||||
&n_b, &one, tmp, &n_b,
|
||||
T, &n_b, &one,
|
||||
P, &n_b);*/
|
||||
&n_b, &one, tmp, &n_b,
|
||||
T, &n_b, &one,
|
||||
P, &n_b);*/
|
||||
cublasDgemm(handle, CUBLAS_OP_N, CUBLAS_OP_T, n, n,
|
||||
n, &one, d_C, n,
|
||||
d_B, n, &one,
|
||||
d_D, n);
|
||||
n, &one, d_C, n,
|
||||
d_B, n, &one,
|
||||
d_D, n);
|
||||
//double_symm(n, &one, h_A, h_B, &zero, h_C);
|
||||
|
||||
status = cublasGetVector(n2, sizeof(P[0]), d_D, 1, P, 1);
|
||||
|
@ -767,14 +761,14 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef USE_OMP
|
||||
#pragma omp parallel for shared(K_P) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
#endif
|
||||
# else
|
||||
# ifdef USE_OMP
|
||||
# pragma omp parallel for shared(K_P) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
# endif
|
||||
for (int i = pure_obs; i < n; i++)
|
||||
{
|
||||
unsigned int i1 = i - pure_obs;
|
||||
for (int j = i ; j < n; j++)
|
||||
for (int j = i; j < n; j++)
|
||||
{
|
||||
unsigned int j1 = j - pure_obs;
|
||||
double res = 0.0;
|
||||
|
@ -785,9 +779,9 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_OMP
|
||||
#pragma omp parallel for shared(P_t_t1) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
#endif
|
||||
# ifdef USE_OMP
|
||||
# pragma omp parallel for shared(P_t_t1) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
# endif
|
||||
for (int i = pure_obs; i < n; i++)
|
||||
{
|
||||
unsigned int i1 = i - pure_obs;
|
||||
|
@ -801,9 +795,9 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
|
||||
memset(tmp, 0, n * n_state * sizeof(double));
|
||||
|
||||
#ifdef USE_OMP
|
||||
#pragma omp parallel for shared(tmp) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
#endif
|
||||
# ifdef USE_OMP
|
||||
# pragma omp parallel for shared(tmp) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
# endif
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
int max_k = i_nz_state_var[i];
|
||||
|
@ -811,7 +805,7 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
{
|
||||
int j1 = j - pure_obs;
|
||||
int j1_n_state = j1 * n_state - pure_obs;
|
||||
int indx_tmp = i + j1 * n ;
|
||||
int indx_tmp = i + j1 * n;
|
||||
for (int k = pure_obs; k < max_k; k++)
|
||||
tmp[indx_tmp] += T[i + k * n] * P_t_t1[k + j1_n_state];
|
||||
}
|
||||
|
@ -819,10 +813,10 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
|
||||
memset(P, 0, n * n * sizeof(double));
|
||||
|
||||
int n_n_obs = - n * pure_obs;
|
||||
#ifdef USE_OMP
|
||||
#pragma omp parallel for shared(P) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
#endif
|
||||
int n_n_obs = -n * pure_obs;
|
||||
# ifdef USE_OMP
|
||||
# pragma omp parallel for shared(P) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
# endif
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
for (int j = i; j < n; j++)
|
||||
|
@ -837,17 +831,17 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_OMP
|
||||
#pragma omp parallel for shared(P) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
#endif
|
||||
for ( int i = 0; i < n; i++)
|
||||
# ifdef USE_OMP
|
||||
# pragma omp parallel for shared(P) num_threads(atoi(getenv("DYNARE_NUM_THREADS")))
|
||||
# endif
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
for ( int j = i ; j < n; j++)
|
||||
for (int j = i; j < n; j++)
|
||||
P[j + i * n] += QQ[j + i * n];
|
||||
for ( int j = i + 1; j < n; j++)
|
||||
for (int j = i + 1; j < n; j++)
|
||||
P[i + j * n] = P[j + i * n];
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
#endif
|
||||
if (t >= no_more_missing_observations)
|
||||
{
|
||||
|
@ -861,7 +855,7 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
notsteady = max_abs > riccati_tol;
|
||||
|
||||
//oldK = K(:);
|
||||
|
||||
|
||||
memcpy(oldK, K, n * pp * sizeof(double));
|
||||
}
|
||||
}
|
||||
|
@ -875,8 +869,7 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
BlockKalmanFilter::return_results_and_clean(int nlhs, mxArray *plhs[], double *P_mf[], double *v_pp[], double *K[], double *v_n[], double *a[], double *K_P[], double *P_t_t1[], double *tmp[], double *P[])
|
||||
{
|
||||
plhs[0] = mxCreateDoubleScalar(0);
|
||||
|
@ -884,7 +877,7 @@ BlockKalmanFilter::return_results_and_clean(int nlhs, mxArray *plhs[], double *P
|
|||
if (nlhs >= 2)
|
||||
{
|
||||
plhs[1] = mxCreateDoubleMatrix(1, 1, mxREAL);
|
||||
double* pind = mxGetPr(plhs[1]);
|
||||
double *pind = mxGetPr(plhs[1]);
|
||||
pind[0] = LIK;
|
||||
}
|
||||
|
||||
|
@ -903,7 +896,7 @@ BlockKalmanFilter::return_results_and_clean(int nlhs, mxArray *plhs[], double *P
|
|||
mxFree(ipiv);
|
||||
mxFree(oldK);
|
||||
//mxFree(P_mf);
|
||||
|
||||
|
||||
mxDestroyArray(pa);
|
||||
mxDestroyArray(p_tmp);
|
||||
mxDestroyArray(pQQ);
|
||||
|
@ -918,9 +911,8 @@ BlockKalmanFilter::return_results_and_clean(int nlhs, mxArray *plhs[], double *P
|
|||
void
|
||||
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||
{
|
||||
double *P_mf, * v_pp, *v_n, *a, *K, *K_P, *P_t_t1, *tmp, *P;
|
||||
double *P_mf, *v_pp, *v_n, *a, *K, *K_P, *P_t_t1, *tmp, *P;
|
||||
BlockKalmanFilter block_kalman_filter(nlhs, plhs, nrhs, prhs, &P_mf, &v_pp, &K, &v_n, &a, &K_P, &P_t_t1, &tmp, &P);
|
||||
if (block_kalman_filter.block_kalman_filter(nlhs, plhs, P_mf, v_pp, K, K_P, a, K_P, P_t_t1, tmp, P))
|
||||
block_kalman_filter.return_results_and_clean(nlhs, plhs, &P_mf, &v_pp, &K, &K_P, &a, &K_P, &P_t_t1, &tmp, &P);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,30 +32,30 @@ using namespace std;
|
|||
|
||||
class BlockKalmanFilter
|
||||
{
|
||||
public:
|
||||
mxArray *pT , *pR, *pQ, *pH, *pP, *pY, *pQQ, *pv, *pF, *piF, *p_P_t_t1, *pK, *p_K_P;
|
||||
double *T , *R, *Q , *H, *Y, *mfd, *QQ, *v, *F, *iF;
|
||||
public:
|
||||
mxArray *pT, *pR, *pQ, *pH, *pP, *pY, *pQQ, *pv, *pF, *piF, *p_P_t_t1, *pK, *p_K_P;
|
||||
double *T, *R, *Q, *H, *Y, *mfd, *QQ, *v, *F, *iF;
|
||||
int start, pure_obs, smpl, n, n_state, n_shocks, H_size;
|
||||
double kalman_tol, riccati_tol, dF, LIK, Inf, pi;
|
||||
lapack_int pp, lw, info;
|
||||
|
||||
double* nz_state_var;
|
||||
double *nz_state_var;
|
||||
int *i_nz_state_var, *mf;
|
||||
int n_diag, t;
|
||||
mxArray *M_;
|
||||
mxArray* pa, *p_tmp, *p_tmp1, *plik;
|
||||
mxArray *pa, *p_tmp, *p_tmp1, *plik;
|
||||
double *tmp_a, *tmp1, *lik, *v_n, *w, *oldK;
|
||||
bool notsteady, F_singular, missing_observations;
|
||||
lapack_int *iw, *ipiv;
|
||||
double anorm, rcond;
|
||||
lapack_int size_d_index;
|
||||
int no_more_missing_observations, number_of_observations;
|
||||
const mxArray* pdata_index;
|
||||
const mxArray *pdata_index;
|
||||
vector<int> d_index;
|
||||
const mxArray* pd_index;
|
||||
double* dd_index;
|
||||
const mxArray *pd_index;
|
||||
double *dd_index;
|
||||
|
||||
public:
|
||||
public:
|
||||
BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[], double *P_mf[], double *v_pp[], double *K[], double *v_n[], double *a[], double *K_P[], double *P_t_t1[], double *tmp[], double *P[]);
|
||||
bool block_kalman_filter(int nlhs, mxArray *plhs[], double *P_mf, double *v_pp, double *K, double *v_n, double *a, double *K_P, double *P_t_t1, double *tmp, double *P);
|
||||
void block_kalman_filter_ss(double *P_mf, double *v_pp, double *K, double *v_n, double *a, double *K_P, double *P_t_t1, double *tmp, double *P);
|
||||
|
|
|
@ -31,11 +31,11 @@
|
|||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265358979323846)
|
||||
# define M_PI (3.14159265358979323846)
|
||||
#endif
|
||||
|
||||
#ifndef M_SQRT2
|
||||
#define M_SQRT2 1.41421356237309504880
|
||||
# define M_SQRT2 1.41421356237309504880
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_EX
|
||||
|
@ -50,114 +50,114 @@
|
|||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <limits>
|
||||
#define M_E 2.71828182845904523536
|
||||
#define M_LOG2E 1.44269504088896340736
|
||||
#define M_LOG10E 0.434294481903251827651
|
||||
#define M_LN2 0.693147180559945309417
|
||||
#define M_LN10 2.30258509299404568402
|
||||
#define M_PI 3.14159265358979323846
|
||||
#define M_PI_2 1.57079632679489661923
|
||||
#define M_PI_4 0.785398163397448309616
|
||||
#define M_1_PI 0.318309886183790671538
|
||||
#define M_2_PI 0.636619772367581343076
|
||||
#define M_1_SQRTPI 0.564189583547756286948
|
||||
#define M_2_SQRTPI 1.12837916709551257390
|
||||
#define M_SQRT2 1.41421356237309504880
|
||||
#define M_SQRT_2 0.707106781186547524401
|
||||
#define NAN numeric_limits<double>::quiet_NaN()
|
||||
# include <limits>
|
||||
# define M_E 2.71828182845904523536
|
||||
# define M_LOG2E 1.44269504088896340736
|
||||
# define M_LOG10E 0.434294481903251827651
|
||||
# define M_LN2 0.693147180559945309417
|
||||
# define M_LN10 2.30258509299404568402
|
||||
# define M_PI 3.14159265358979323846
|
||||
# define M_PI_2 1.57079632679489661923
|
||||
# define M_PI_4 0.785398163397448309616
|
||||
# define M_1_PI 0.318309886183790671538
|
||||
# define M_2_PI 0.636619772367581343076
|
||||
# define M_1_SQRTPI 0.564189583547756286948
|
||||
# define M_2_SQRTPI 1.12837916709551257390
|
||||
# define M_SQRT2 1.41421356237309504880
|
||||
# define M_SQRT_2 0.707106781186547524401
|
||||
# define NAN numeric_limits<double>::quiet_NaN()
|
||||
|
||||
#define isnan(x) _isnan(x)
|
||||
#define isinf(x) (!_finite(x))
|
||||
#define fpu_error(x) (isinf(x) || isnan(x))
|
||||
# define isnan(x) _isnan(x)
|
||||
# define isinf(x) (!_finite(x))
|
||||
# define fpu_error(x) (isinf(x) || isnan(x))
|
||||
|
||||
#define finite(x) _finite(x)
|
||||
# define finite(x) _finite(x)
|
||||
|
||||
class MSVCpp_missings
|
||||
{
|
||||
public:
|
||||
public:
|
||||
inline double
|
||||
asinh(double x) const
|
||||
{
|
||||
if(x==0.0)
|
||||
return 0.0;
|
||||
double ax = abs(x);
|
||||
return log(x+ax*sqrt(1.+1./(ax*ax)));
|
||||
}
|
||||
{
|
||||
if (x == 0.0)
|
||||
return 0.0;
|
||||
double ax = abs(x);
|
||||
return log(x+ax*sqrt(1.+1./(ax*ax)));
|
||||
}
|
||||
|
||||
inline double
|
||||
acosh(double x) const
|
||||
{
|
||||
if(x==0.0)
|
||||
return 0.0;
|
||||
double ax = abs(x);
|
||||
return log(x+ax*sqrt(1.-1./(ax*ax)));
|
||||
}
|
||||
{
|
||||
if (x == 0.0)
|
||||
return 0.0;
|
||||
double ax = abs(x);
|
||||
return log(x+ax*sqrt(1.-1./(ax*ax)));
|
||||
}
|
||||
|
||||
inline double
|
||||
atanh(double x) const
|
||||
{
|
||||
return log((1+x)/(1-x))/2;
|
||||
}
|
||||
{
|
||||
return log((1+x)/(1-x))/2;
|
||||
}
|
||||
|
||||
inline double
|
||||
erf(double x) const
|
||||
{
|
||||
const double a1 = -1.26551223, a2 = 1.00002368,
|
||||
a3 = 0.37409196, a4 = 0.09678418,
|
||||
a5 = -0.18628806, a6 = 0.27886807,
|
||||
a7 = -1.13520398, a8 = 1.48851587,
|
||||
a9 = -0.82215223, a10 = 0.17087277;
|
||||
double v = 1;
|
||||
double z = abs(x);
|
||||
if (z <= 0)
|
||||
return v;
|
||||
double t = 1 / (1 + 0.5 * z);
|
||||
v = t*exp((-z*z) +a1+t*(a2+t*(a3+t*(a4+t*(a5+t*(a6+t*(a7+t*(a8+t*(a9+t*a10)))))))));
|
||||
if (x < 0)
|
||||
v = 2 - v;
|
||||
return 1 - v;
|
||||
}
|
||||
{
|
||||
const double a1 = -1.26551223, a2 = 1.00002368,
|
||||
a3 = 0.37409196, a4 = 0.09678418,
|
||||
a5 = -0.18628806, a6 = 0.27886807,
|
||||
a7 = -1.13520398, a8 = 1.48851587,
|
||||
a9 = -0.82215223, a10 = 0.17087277;
|
||||
double v = 1;
|
||||
double z = abs(x);
|
||||
if (z <= 0)
|
||||
return v;
|
||||
double t = 1 / (1 + 0.5 * z);
|
||||
v = t*exp((-z*z) +a1+t*(a2+t*(a3+t*(a4+t*(a5+t*(a6+t*(a7+t*(a8+t*(a9+t*a10)))))))));
|
||||
if (x < 0)
|
||||
v = 2 - v;
|
||||
return 1 - v;
|
||||
}
|
||||
|
||||
inline double
|
||||
nearbyint(double x) const
|
||||
{
|
||||
return floor(x + 0.5);
|
||||
}
|
||||
{
|
||||
return floor(x + 0.5);
|
||||
}
|
||||
|
||||
inline double
|
||||
fmax(double x, double y) const
|
||||
{
|
||||
if (x > y)
|
||||
return x;
|
||||
else
|
||||
return y;
|
||||
}
|
||||
{
|
||||
if (x > y)
|
||||
return x;
|
||||
else
|
||||
return y;
|
||||
}
|
||||
|
||||
inline double
|
||||
fmin(double x, double y) const
|
||||
{
|
||||
if (x < y)
|
||||
return x;
|
||||
else
|
||||
return y;
|
||||
}
|
||||
{
|
||||
if (x < y)
|
||||
return x;
|
||||
else
|
||||
return y;
|
||||
}
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#define __CROSS_COMPILATION__
|
||||
# define __CROSS_COMPILATION__
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW64__
|
||||
#define __CROSS_COMPILATION__
|
||||
# define __CROSS_COMPILATION__
|
||||
#endif
|
||||
|
||||
#ifdef __CROSS_COMPILATION__
|
||||
#define M_PI 3.14159265358979323846
|
||||
#define M_SQRT2 1.41421356237309504880
|
||||
#define finite(x) !std::isfinite(x)
|
||||
# define M_PI 3.14159265358979323846
|
||||
# define M_SQRT2 1.41421356237309504880
|
||||
# define finite(x) !std::isfinite(x)
|
||||
#endif
|
||||
|
||||
//#define DEBUG
|
||||
|
@ -166,11 +166,9 @@ using namespace std;
|
|||
const int NO_ERROR_ON_EXIT = 0;
|
||||
const int ERROR_ON_EXIT = 1;
|
||||
|
||||
|
||||
typedef vector<pair<Tags, void * > > code_liste_type;
|
||||
typedef code_liste_type::const_iterator it_code_type;
|
||||
|
||||
|
||||
class GeneralExceptionHandling
|
||||
{
|
||||
string ErrorMsg;
|
||||
|
@ -253,7 +251,7 @@ public:
|
|||
value2(value2_arg)
|
||||
{
|
||||
ostringstream tmp;
|
||||
if (fabs(value1) > 1e-10 )
|
||||
if (fabs(value1) > 1e-10)
|
||||
tmp << " with X=" << value1 << "\n";
|
||||
else
|
||||
tmp << " with X=" << value1 << " and a=" << value2 << "\n";
|
||||
|
@ -292,11 +290,11 @@ struct s_plan
|
|||
};
|
||||
|
||||
struct table_conditional_local_type
|
||||
{
|
||||
bool is_cond;
|
||||
int var_exo, var_endo;
|
||||
double constrained_value;
|
||||
};
|
||||
{
|
||||
bool is_cond;
|
||||
int var_exo, var_endo;
|
||||
double constrained_value;
|
||||
};
|
||||
typedef vector<table_conditional_local_type> vector_table_conditional_local_type;
|
||||
typedef map< int, vector_table_conditional_local_type > table_conditional_global_type;
|
||||
#ifdef MATLAB_MEX_FILE
|
||||
|
@ -330,9 +328,9 @@ public:
|
|||
|
||||
ExpressionType EQN_type;
|
||||
it_code_type it_code_expr;
|
||||
/*unsigned int*/size_t nb_endo, nb_exo, nb_param;
|
||||
/*unsigned int*/ size_t nb_endo, nb_exo, nb_param;
|
||||
char *P_endo_names, *P_exo_names, *P_param_names;
|
||||
size_t/*unsigned int*/ endo_name_length, exo_name_length, param_name_length;
|
||||
size_t /*unsigned int*/ endo_name_length, exo_name_length, param_name_length;
|
||||
unsigned int EQN_equation, EQN_block, EQN_block_number;
|
||||
unsigned int EQN_dvar1, EQN_dvar2, EQN_dvar3;
|
||||
vector<pair<string, pair<SymbolType, unsigned int> > > Variable_list;
|
||||
|
@ -388,7 +386,7 @@ public:
|
|||
string tmp_n(str.length(), ' ');
|
||||
string dollar, pound, tilde;
|
||||
dollar = "$";
|
||||
pound = "£";
|
||||
pound = "£";
|
||||
tilde = "~";
|
||||
for (unsigned int i = 0; i < str.length(); i++)
|
||||
{
|
||||
|
@ -397,9 +395,9 @@ public:
|
|||
else
|
||||
{
|
||||
if (dollar.compare(&str[i]) == 0)
|
||||
pos1 = int(temp.length());
|
||||
pos1 = int (temp.length());
|
||||
else
|
||||
pos2 = int(temp.length());
|
||||
pos2 = int (temp.length());
|
||||
if (pos1 >= 0 && pos2 >= 0)
|
||||
{
|
||||
tmp_n.erase(pos1, pos2-pos1+1);
|
||||
|
@ -416,14 +414,14 @@ public:
|
|||
load_variable_list()
|
||||
{
|
||||
ostringstream res;
|
||||
for (unsigned int variable_num = 0; variable_num < (unsigned int)nb_endo; variable_num++)
|
||||
for (unsigned int variable_num = 0; variable_num < (unsigned int) nb_endo; variable_num++)
|
||||
{
|
||||
for (unsigned int i = 0; i < endo_name_length; i++)
|
||||
if (P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)] != ' ')
|
||||
res << P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)];
|
||||
Variable_list.push_back(make_pair(res.str(), make_pair(eEndogenous, variable_num)));
|
||||
}
|
||||
for (unsigned int variable_num = 0; variable_num < (unsigned int)nb_exo; variable_num++)
|
||||
for (unsigned int variable_num = 0; variable_num < (unsigned int) nb_exo; variable_num++)
|
||||
{
|
||||
for (unsigned int i = 0; i < exo_name_length; i++)
|
||||
if (P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)] != ' ')
|
||||
|
@ -453,7 +451,7 @@ public:
|
|||
}
|
||||
i++;
|
||||
}
|
||||
return(-1);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
inline string
|
||||
|
@ -634,8 +632,8 @@ public:
|
|||
while (go_on)
|
||||
{
|
||||
#ifdef MATLAB_MEX_FILE
|
||||
if ( utIsInterruptPending() )
|
||||
throw UserExceptionHandling();
|
||||
if (utIsInterruptPending())
|
||||
throw UserExceptionHandling();
|
||||
#endif
|
||||
switch (it_code->first)
|
||||
{
|
||||
|
@ -701,7 +699,7 @@ public:
|
|||
var = ((FLDV_ *) it_code->second)->get_pos();
|
||||
#ifdef DEBUG
|
||||
mexPrintf("FLDV_ Param var=%d\n", var);
|
||||
mexPrintf("get_variable(eParameter, var)=%s\n",get_variable(eParameter, var).c_str());
|
||||
mexPrintf("get_variable(eParameter, var)=%s\n", get_variable(eParameter, var).c_str());
|
||||
mexEvalString("drawnow;");
|
||||
#endif
|
||||
Stack.push(get_variable(eParameter, var));
|
||||
|
@ -713,7 +711,7 @@ public:
|
|||
lag = ((FLDV_ *) it_code->second)->get_lead_lag();
|
||||
#ifdef DEBUG
|
||||
mexPrintf("FLDV_ endo var=%d, lag=%d\n", var, lag);
|
||||
mexPrintf("get_variable(eEndogenous, var)=%s, compute=%d\n",get_variable(eEndogenous, var).c_str(), compute);
|
||||
mexPrintf("get_variable(eEndogenous, var)=%s, compute=%d\n", get_variable(eEndogenous, var).c_str(), compute);
|
||||
mexPrintf("it_=%d, lag=%d, y_size=%d, var=%d, y=%x\n", it_, lag, y_size, var, y);
|
||||
mexEvalString("drawnow;");
|
||||
#endif
|
||||
|
@ -1331,7 +1329,7 @@ public:
|
|||
tmp_out << "$";
|
||||
tmp_out << " / ";
|
||||
if (isinf(r))
|
||||
tmp_out << "£";
|
||||
tmp_out << "£";
|
||||
}
|
||||
else
|
||||
tmp_out << " / ";
|
||||
|
@ -1494,7 +1492,7 @@ public:
|
|||
if (compute)
|
||||
{
|
||||
if (isnan(r))
|
||||
tmp_out << "$ ^ " << "£";
|
||||
tmp_out << "$ ^ " << "£";
|
||||
else
|
||||
tmp_out << " ^ ";
|
||||
}
|
||||
|
@ -1514,7 +1512,7 @@ public:
|
|||
Stack.pop();
|
||||
if (compute)
|
||||
{
|
||||
int derivOrder = int(nearbyint(Stackf.top()));
|
||||
int derivOrder = int (nearbyint(Stackf.top()));
|
||||
Stackf.pop();
|
||||
if (fabs(v1f) < NEAR_ZERO && v2f > 0
|
||||
&& derivOrder > v2f
|
||||
|
@ -1536,7 +1534,7 @@ public:
|
|||
if (compute)
|
||||
{
|
||||
if (isnan(r))
|
||||
tmp_out << "$ PowerDeriv " << "£";
|
||||
tmp_out << "$ PowerDeriv " << "£";
|
||||
else
|
||||
tmp_out << "PowerDeriv";
|
||||
}
|
||||
|
@ -1610,7 +1608,7 @@ public:
|
|||
if (compute)
|
||||
{
|
||||
if (isnan(r))
|
||||
tmp_out << "$log" << "£" << "(" << v1 << ")";
|
||||
tmp_out << "$log" << "£" << "(" << v1 << ")";
|
||||
else
|
||||
tmp_out << "log(" << v1 << ")";
|
||||
}
|
||||
|
@ -1628,7 +1626,7 @@ public:
|
|||
if (compute)
|
||||
{
|
||||
if (isnan(r))
|
||||
tmp_out << "$log10" << "£" << "(" << v1 << ")";
|
||||
tmp_out << "$log10" << "£" << "(" << v1 << ")";
|
||||
else
|
||||
tmp_out << "log10(" << v1 << ")";
|
||||
}
|
||||
|
@ -2234,17 +2232,18 @@ public:
|
|||
it_code_ret = it_code;
|
||||
return (tmp_out.str());
|
||||
}
|
||||
void
|
||||
|
||||
inline test_mxMalloc(void* z, int line, string file, string func, int amount)
|
||||
{
|
||||
if (!z && (amount > 0))
|
||||
{
|
||||
ostringstream tmp;
|
||||
tmp << " mxMalloc: out of memory " << amount << " bytes required at line " << line << " in function " << func << " (file " << file;
|
||||
throw FatalExceptionHandling(tmp.str());
|
||||
}
|
||||
}
|
||||
void
|
||||
|
||||
inline
|
||||
test_mxMalloc(void *z, int line, string file, string func, int amount)
|
||||
{
|
||||
if (!z && (amount > 0))
|
||||
{
|
||||
ostringstream tmp;
|
||||
tmp << " mxMalloc: out of memory " << amount << " bytes required at line " << line << " in function " << func << " (file " << file;
|
||||
throw FatalExceptionHandling(tmp.str());
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@ Evaluate::Evaluate()
|
|||
block = -1;
|
||||
}
|
||||
|
||||
Evaluate::Evaluate(const int y_size_arg, const int y_kmin_arg, const int y_kmax_arg, const bool print_it_arg, const bool steady_state_arg, const int periods_arg, const int minimal_solving_periods_arg, const double slowc_arg):
|
||||
print_it(print_it_arg), minimal_solving_periods(minimal_solving_periods_arg)
|
||||
Evaluate::Evaluate(const int y_size_arg, const int y_kmin_arg, const int y_kmax_arg, const bool print_it_arg, const bool steady_state_arg, const int periods_arg, const int minimal_solving_periods_arg, const double slowc_arg) :
|
||||
print_it(print_it_arg), minimal_solving_periods(minimal_solving_periods_arg)
|
||||
{
|
||||
symbol_table_endo_nbr = 0;
|
||||
Block_List_Max_Lag = 0;
|
||||
|
@ -107,7 +107,6 @@ Evaluate::log10_1(double a)
|
|||
return r;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Evaluate::compute_block_time(const int Per_u_, const bool evaluate, /*const int block_num, const int size, const bool steady_state,*/ const bool no_derivative)
|
||||
{
|
||||
|
@ -137,14 +136,14 @@ Evaluate::compute_block_time(const int Per_u_, const bool evaluate, /*const int
|
|||
}
|
||||
}
|
||||
#ifdef MATLAB_MEX_FILE
|
||||
if ( utIsInterruptPending() )
|
||||
throw UserExceptionHandling();
|
||||
if (utIsInterruptPending())
|
||||
throw UserExceptionHandling();
|
||||
#endif
|
||||
|
||||
while (go_on)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
mexPrintf("it_code->first=%d\n",it_code->first);
|
||||
mexPrintf("it_code->first=%d\n", it_code->first);
|
||||
#endif
|
||||
switch (it_code->first)
|
||||
{
|
||||
|
@ -738,7 +737,7 @@ Evaluate::compute_block_time(const int Per_u_, const bool evaluate, /*const int
|
|||
pos_col = ((FSTPG3_ *) it_code->second)->get_col_pos();
|
||||
#ifdef DEBUG
|
||||
mexPrintf("Endo eq=%d, pos_col=%d, size=%d, jacob=%x\n", eq, pos_col, size, jacob);
|
||||
mexPrintf("jacob=%x\n",jacob);
|
||||
mexPrintf("jacob=%x\n", jacob);
|
||||
#endif
|
||||
jacob[eq + size*pos_col] = rr;
|
||||
break;
|
||||
|
@ -843,7 +842,7 @@ Evaluate::compute_block_time(const int Per_u_, const bool evaluate, /*const int
|
|||
case oLess:
|
||||
Stack.push(double (v1 < v2));
|
||||
#ifdef DEBUG
|
||||
mexPrintf("v1=%f v2=%f v1 < v2 = %f\n",v1,v2,double(v1 < v2));
|
||||
mexPrintf("v1=%f v2=%f v1 < v2 = %f\n", v1, v2, double (v1 < v2));
|
||||
#endif
|
||||
break;
|
||||
case oGreater:
|
||||
|
@ -897,7 +896,7 @@ Evaluate::compute_block_time(const int Per_u_, const bool evaluate, /*const int
|
|||
break;
|
||||
case oPowerDeriv:
|
||||
{
|
||||
int derivOrder = int(nearbyint(Stack.top()));
|
||||
int derivOrder = int (nearbyint(Stack.top()));
|
||||
Stack.pop();
|
||||
try
|
||||
{
|
||||
|
@ -1216,7 +1215,7 @@ Evaluate::compute_block_time(const int Per_u_, const bool evaluate, /*const int
|
|||
case ExternalFunctionNumericalFirstDerivative:
|
||||
{
|
||||
input_arguments = (mxArray **) mxMalloc((nb_input_arguments+1+nb_add_input_arguments) * sizeof(mxArray *));
|
||||
test_mxMalloc(input_arguments, __LINE__, __FILE__, __func__, (nb_input_arguments+1+nb_add_input_arguments) * sizeof(mxArray *));
|
||||
test_mxMalloc(input_arguments, __LINE__, __FILE__, __func__, (nb_input_arguments+1+nb_add_input_arguments) * sizeof(mxArray *));
|
||||
mxArray *vv = mxCreateString(arg_func_name.c_str());
|
||||
input_arguments[0] = vv;
|
||||
vv = mxCreateDoubleScalar(fc->get_row());
|
||||
|
@ -1489,7 +1488,7 @@ Evaluate::compute_block_time(const int Per_u_, const bool evaluate, /*const int
|
|||
throw FatalExceptionHandling(tmp.str());
|
||||
}
|
||||
#ifdef DEBUG
|
||||
mexPrintf("it_code++=%d\n",it_code);
|
||||
mexPrintf("it_code++=%d\n", it_code);
|
||||
#endif
|
||||
it_code++;
|
||||
}
|
||||
|
@ -1499,8 +1498,6 @@ Evaluate::compute_block_time(const int Per_u_, const bool evaluate, /*const int
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Evaluate::evaluate_over_periods(const bool forward)
|
||||
{
|
||||
|
@ -1533,7 +1530,7 @@ Evaluate::solve_simple_one_periods()
|
|||
{
|
||||
bool cvg = false;
|
||||
int iter = 0;
|
||||
double ya ;
|
||||
double ya;
|
||||
double slowc_save = slowc;
|
||||
res1 = 0;
|
||||
while (!(cvg || (iter > maxit_)))
|
||||
|
@ -1545,7 +1542,7 @@ Evaluate::solve_simple_one_periods()
|
|||
if (!finite(res1))
|
||||
{
|
||||
res1 = NAN;
|
||||
while ((isinf(res1) || isnan(res1)) && (slowc > 1e-9) )
|
||||
while ((isinf(res1) || isnan(res1)) && (slowc > 1e-9))
|
||||
{
|
||||
it_code = start_code;
|
||||
compute_block_time(0, false, false);
|
||||
|
@ -1565,7 +1562,7 @@ Evaluate::solve_simple_one_periods()
|
|||
continue;
|
||||
try
|
||||
{
|
||||
y[Block_Contain[0].Variable + Per_y_] += - slowc * divide(rr, g1[0]);
|
||||
y[Block_Contain[0].Variable + Per_y_] += -slowc *divide(rr, g1[0]);
|
||||
}
|
||||
catch (FloatingPointExceptionHandling &fpeh)
|
||||
{
|
||||
|
@ -1583,7 +1580,6 @@ Evaluate::solve_simple_one_periods()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Evaluate::solve_simple_over_periods(const bool forward)
|
||||
{
|
||||
|
@ -1612,7 +1608,7 @@ Evaluate::solve_simple_over_periods(const bool forward)
|
|||
|
||||
void
|
||||
Evaluate::set_block(const int size_arg, const int type_arg, string file_name_arg, string bin_base_name_arg, const int block_num_arg,
|
||||
const bool is_linear_arg, const int symbol_table_endo_nbr_arg, const int Block_List_Max_Lag_arg, const int Block_List_Max_Lead_arg, const int u_count_int_arg, const int block_arg)
|
||||
const bool is_linear_arg, const int symbol_table_endo_nbr_arg, const int Block_List_Max_Lag_arg, const int Block_List_Max_Lead_arg, const int u_count_int_arg, const int block_arg)
|
||||
{
|
||||
size = size_arg;
|
||||
type = type_arg;
|
||||
|
@ -1634,7 +1630,6 @@ Evaluate::evaluate_complete(const bool no_derivatives)
|
|||
compute_block_time(0, false, no_derivatives);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Evaluate::compute_complete_2b(const bool no_derivatives, double *_res1, double *_res2, double *_max_res, int *_max_res_idx)
|
||||
{
|
||||
|
@ -1651,21 +1646,21 @@ Evaluate::compute_complete_2b(const bool no_derivatives, double *_res1, double *
|
|||
compute_block_time(Per_u_, false, no_derivatives);
|
||||
if (!(isnan(res1) || isinf(res1)))
|
||||
{
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
double rr;
|
||||
rr = r[i];
|
||||
res[i+shift] = rr;
|
||||
if (max_res < fabs(rr))
|
||||
{
|
||||
*_max_res = fabs(rr);
|
||||
*_max_res_idx = i;
|
||||
}
|
||||
*_res2 += rr*rr;
|
||||
*_res1 += fabs(rr);
|
||||
}
|
||||
}
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
double rr;
|
||||
rr = r[i];
|
||||
res[i+shift] = rr;
|
||||
if (max_res < fabs(rr))
|
||||
{
|
||||
*_max_res = fabs(rr);
|
||||
*_max_res_idx = i;
|
||||
}
|
||||
*_res2 += rr*rr;
|
||||
*_res1 += fabs(rr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
@ -1673,7 +1668,6 @@ Evaluate::compute_complete_2b(const bool no_derivatives, double *_res1, double *
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Evaluate::compute_complete(const bool no_derivatives, double &_res1, double &_res2, double &_max_res, int &_max_res_idx)
|
||||
{
|
||||
|
@ -1683,23 +1677,23 @@ Evaluate::compute_complete(const bool no_derivatives, double &_res1, double &_re
|
|||
compute_block_time(0, false, no_derivatives);
|
||||
if (!(isnan(res1) || isinf(res1)))
|
||||
{
|
||||
{
|
||||
_res1 = 0;
|
||||
_res2 = 0;
|
||||
_max_res = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
double rr;
|
||||
rr = r[i];
|
||||
if (max_res < fabs(rr))
|
||||
{
|
||||
_max_res = fabs(rr);
|
||||
_max_res_idx = i;
|
||||
}
|
||||
_res2 += rr*rr;
|
||||
_res1 += fabs(rr);
|
||||
}
|
||||
}
|
||||
{
|
||||
_res1 = 0;
|
||||
_res2 = 0;
|
||||
_max_res = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
double rr;
|
||||
rr = r[i];
|
||||
if (max_res < fabs(rr))
|
||||
{
|
||||
_max_res = fabs(rr);
|
||||
_max_res_idx = i;
|
||||
}
|
||||
_res2 += rr*rr;
|
||||
_res1 += fabs(rr);
|
||||
}
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
|
@ -1707,7 +1701,6 @@ Evaluate::compute_complete(const bool no_derivatives, double &_res1, double &_re
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Evaluate::compute_complete(double lambda, double *crit)
|
||||
{
|
||||
|
@ -1728,10 +1721,10 @@ Evaluate::compute_complete(double lambda, double *crit)
|
|||
{
|
||||
res2_ = res2;
|
||||
/*res1_ = res1;
|
||||
if (max_res > max_res_)
|
||||
if (max_res > max_res_)
|
||||
{
|
||||
max_res = max_res_;
|
||||
max_res_idx = max_res_idx_;
|
||||
max_res = max_res_;
|
||||
max_res_idx = max_res_idx_;
|
||||
}*/
|
||||
}
|
||||
else
|
||||
|
@ -1765,7 +1758,7 @@ Evaluate::compute_complete(double lambda, double *crit)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
mexPrintf(" lambda=%e, res2=%e\n", lambda, res2_);
|
||||
mexPrintf(" lambda=%e, res2=%e\n", lambda, res2_);
|
||||
*crit = res2_/2;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -63,13 +63,13 @@ protected:
|
|||
double solve_tolf;
|
||||
bool GaussSeidel;
|
||||
map<pair<pair<int, int>, int>, int> IM_i;
|
||||
int equation, derivative_equation, derivative_variable;
|
||||
int equation, derivative_equation, derivative_variable;
|
||||
string filename;
|
||||
int stack_solve_algo, solve_algo;
|
||||
bool global_temporary_terms;
|
||||
bool print, print_error;
|
||||
double res1, res2, max_res;
|
||||
int max_res_idx;
|
||||
int max_res_idx;
|
||||
vector<Block_contain_type> Block_Contain;
|
||||
|
||||
int size;
|
||||
|
@ -87,7 +87,7 @@ public:
|
|||
Evaluate(const int y_size_arg, const int y_kmin_arg, const int y_kmax_arg, const bool print_it_arg, const bool steady_state_arg, const int periods_arg, const int minimal_solving_periods_arg, const double slowc);
|
||||
//typedef void (Interpreter::*InterfpreterMemFn)(const int block_num, const int size, const bool steady_state, int it);
|
||||
void set_block(const int size_arg, const int type_arg, string file_name_arg, string bin_base_name_arg, const int block_num_arg,
|
||||
const bool is_linear_arg, const int symbol_table_endo_nbr_arg, const int Block_List_Max_Lag_arg, const int Block_List_Max_Lead_arg, const int u_count_int_arg, const int block_arg);
|
||||
const bool is_linear_arg, const int symbol_table_endo_nbr_arg, const int Block_List_Max_Lag_arg, const int Block_List_Max_Lead_arg, const int u_count_int_arg, const int block_arg);
|
||||
void evaluate_complete(const bool no_derivatives);
|
||||
bool compute_complete(const bool no_derivatives, double &res1, double &res2, double &max_res, int &max_res_idx);
|
||||
void compute_complete_2b(const bool no_derivatives, double *_res1, double *_res2, double *_max_res, int *_max_res_idx);
|
||||
|
|
|
@ -40,11 +40,11 @@ Interpreter::Interpreter(double *params_arg, double *y_arg, double *ya_arg, doub
|
|||
, const int CUDA_device_arg, cublasHandle_t cublas_handle_arg, cusparseHandle_t cusparse_handle_arg, cusparseMatDescr_t descr_arg
|
||||
#endif
|
||||
)
|
||||
: dynSparseMatrix(y_size_arg, y_kmin_arg, y_kmax_arg, print_it_arg, steady_state_arg, periods_arg, minimal_solving_periods_arg, slowc_arg
|
||||
: dynSparseMatrix(y_size_arg, y_kmin_arg, y_kmax_arg, print_it_arg, steady_state_arg, periods_arg, minimal_solving_periods_arg, slowc_arg
|
||||
#ifdef CUDA
|
||||
, CUDA_device_arg, cublas_handle_arg, cusparse_handle_arg, descr_arg
|
||||
, CUDA_device_arg, cublas_handle_arg, cusparse_handle_arg, descr_arg
|
||||
#endif
|
||||
)
|
||||
)
|
||||
{
|
||||
params = params_arg;
|
||||
y = y_arg;
|
||||
|
@ -73,12 +73,12 @@ Interpreter::Interpreter(double *params_arg, double *y_arg, double *ya_arg, doub
|
|||
solve_algo = solve_algo_arg;
|
||||
global_temporary_terms = global_temporary_terms_arg;
|
||||
print = print_arg;
|
||||
col_x = col_x_arg;
|
||||
col_x = col_x_arg;
|
||||
col_y = col_y_arg;
|
||||
GlobalTemporaryTerms = GlobalTemporaryTerms_arg;
|
||||
print_error = print_error_arg;
|
||||
//steady_state = steady_state_arg;
|
||||
print_it = print_it_arg;
|
||||
print_it = print_it_arg;
|
||||
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ Interpreter::evaluate_a_block(bool initialization)
|
|||
case EVALUATE_FORWARD:
|
||||
if (steady_state)
|
||||
{
|
||||
compute_block_time(0, true, /*block_num, size, steady_state, */false);
|
||||
compute_block_time(0, true, /*block_num, size, steady_state, */ false);
|
||||
if (block >= 0)
|
||||
for (int j = 0; j < size; j++)
|
||||
residual[j] = y[Block_Contain[j].Variable] - ya[Block_Contain[j].Variable];
|
||||
|
@ -107,7 +107,7 @@ Interpreter::evaluate_a_block(bool initialization)
|
|||
{
|
||||
it_code = begining;
|
||||
Per_y_ = it_*y_size;
|
||||
compute_block_time(0, true, /*block_num, size, steady_state, */false);
|
||||
compute_block_time(0, true, /*block_num, size, steady_state, */ false);
|
||||
if (block >= 0)
|
||||
for (int j = 0; j < size; j++)
|
||||
residual[it_*size+j] = y[it_*y_size+Block_Contain[j].Variable] - ya[it_*y_size+Block_Contain[j].Variable];
|
||||
|
@ -118,9 +118,9 @@ Interpreter::evaluate_a_block(bool initialization)
|
|||
}
|
||||
break;
|
||||
case SOLVE_FORWARD_SIMPLE:
|
||||
g1 = (double *) mxMalloc(size*size*sizeof(double));
|
||||
g1 = (double *) mxMalloc(size*size*sizeof(double));
|
||||
test_mxMalloc(g1, __LINE__, __FILE__, __func__, size*size*sizeof(double));
|
||||
r = (double *) mxMalloc(size*sizeof(double));
|
||||
r = (double *) mxMalloc(size*sizeof(double));
|
||||
test_mxMalloc(r, __LINE__, __FILE__, __func__, size*sizeof(double));
|
||||
if (steady_state)
|
||||
{
|
||||
|
@ -147,20 +147,20 @@ Interpreter::evaluate_a_block(bool initialization)
|
|||
for (int j = 0; j < size; j++)
|
||||
residual[it_*size+j] = r[j];
|
||||
}
|
||||
}
|
||||
mxFree(g1);
|
||||
}
|
||||
mxFree(g1);
|
||||
mxFree(r);
|
||||
break;
|
||||
case SOLVE_FORWARD_COMPLETE:
|
||||
if (initialization)
|
||||
{
|
||||
fixe_u(&u, u_count_int, u_count_int);
|
||||
Read_SparseMatrix(bin_base_name, size, 1, 0, 0, false, stack_solve_algo, solve_algo);
|
||||
}
|
||||
{
|
||||
fixe_u(&u, u_count_int, u_count_int);
|
||||
Read_SparseMatrix(bin_base_name, size, 1, 0, 0, false, stack_solve_algo, solve_algo);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
mexPrintf("in SOLVE_FORWARD_COMPLETE r = mxMalloc(%d*sizeof(double))\n", size);
|
||||
#endif
|
||||
r = (double *) mxMalloc(size*sizeof(double));
|
||||
r = (double *) mxMalloc(size*sizeof(double));
|
||||
test_mxMalloc(r, __LINE__, __FILE__, __func__, size*sizeof(double));
|
||||
if (steady_state)
|
||||
{
|
||||
|
@ -219,9 +219,9 @@ Interpreter::evaluate_a_block(bool initialization)
|
|||
}
|
||||
break;
|
||||
case SOLVE_BACKWARD_SIMPLE:
|
||||
g1 = (double *) mxMalloc(size*size*sizeof(double));
|
||||
g1 = (double *) mxMalloc(size*size*sizeof(double));
|
||||
test_mxMalloc(g1, __LINE__, __FILE__, __func__, size*size*sizeof(double));
|
||||
r = (double *) mxMalloc(size*sizeof(double));
|
||||
r = (double *) mxMalloc(size*sizeof(double));
|
||||
test_mxMalloc(r, __LINE__, __FILE__, __func__, size*sizeof(double));
|
||||
if (steady_state)
|
||||
{
|
||||
|
@ -258,7 +258,7 @@ Interpreter::evaluate_a_block(bool initialization)
|
|||
fixe_u(&u, u_count_int, u_count_int);
|
||||
Read_SparseMatrix(bin_base_name, size, 1, 0, 0, false, stack_solve_algo, solve_algo);
|
||||
}
|
||||
r = (double *) mxMalloc(size*sizeof(double));
|
||||
r = (double *) mxMalloc(size*sizeof(double));
|
||||
test_mxMalloc(r, __LINE__, __FILE__, __func__, size*sizeof(double));
|
||||
if (steady_state)
|
||||
{
|
||||
|
@ -277,7 +277,7 @@ Interpreter::evaluate_a_block(bool initialization)
|
|||
{
|
||||
it_code = begining;
|
||||
Per_y_ = it_*y_size;
|
||||
compute_block_time(0, true, /*block_num, size, steady_state, */false);
|
||||
compute_block_time(0, true, /*block_num, size, steady_state, */ false);
|
||||
if (block < 0)
|
||||
for (int j = 0; j < size; j++)
|
||||
residual[Per_y_+Block_Contain[j].Equation] = r[j];
|
||||
|
@ -296,7 +296,7 @@ Interpreter::evaluate_a_block(bool initialization)
|
|||
Read_SparseMatrix(bin_base_name, size, periods, y_kmin, y_kmax, true, stack_solve_algo, solve_algo);
|
||||
}
|
||||
u_count = u_count_int*(periods+y_kmax+y_kmin);
|
||||
r = (double *) mxMalloc(size*sizeof(double));
|
||||
r = (double *) mxMalloc(size*sizeof(double));
|
||||
test_mxMalloc(r, __LINE__, __FILE__, __func__, size*sizeof(double));
|
||||
begining = it_code;
|
||||
for (it_ = y_kmin; it_ < periods+y_kmin; it_++)
|
||||
|
@ -317,8 +317,6 @@ Interpreter::evaluate_a_block(bool initialization)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
Interpreter::simulate_a_block(vector_table_conditional_local_type vector_table_conditional_local)
|
||||
{
|
||||
|
@ -338,14 +336,14 @@ Interpreter::simulate_a_block(vector_table_conditional_local_type vector_table_c
|
|||
mexPrintf("EVALUATE_FORWARD\n");
|
||||
mexEvalString("drawnow;");
|
||||
#endif
|
||||
evaluate_over_periods(true);
|
||||
evaluate_over_periods(true);
|
||||
break;
|
||||
case EVALUATE_BACKWARD:
|
||||
#ifdef DEBUG
|
||||
mexPrintf("EVALUATE_BACKWARD\n");
|
||||
mexEvalString("drawnow;");
|
||||
#endif
|
||||
evaluate_over_periods(false);
|
||||
evaluate_over_periods(false);
|
||||
break;
|
||||
case SOLVE_FORWARD_SIMPLE:
|
||||
#ifdef DEBUG
|
||||
|
@ -438,11 +436,11 @@ Interpreter::simulate_a_block(vector_table_conditional_local_type vector_table_c
|
|||
Read_SparseMatrix(bin_base_name, size, periods, y_kmin, y_kmax, true, stack_solve_algo, solve_algo);
|
||||
}
|
||||
u_count = u_count_int*(periods+y_kmax+y_kmin);
|
||||
r = (double *) mxMalloc(size*sizeof(double));
|
||||
r = (double *) mxMalloc(size*sizeof(double));
|
||||
test_mxMalloc(r, __LINE__, __FILE__, __func__, size*sizeof(double));
|
||||
res = (double *) mxMalloc(size*periods*sizeof(double));
|
||||
res = (double *) mxMalloc(size*periods*sizeof(double));
|
||||
test_mxMalloc(res, __LINE__, __FILE__, __func__, size*periods*sizeof(double));
|
||||
y_save = (double *) mxMalloc(y_size*sizeof(double)*(periods+y_kmax+y_kmin));
|
||||
y_save = (double *) mxMalloc(y_size*sizeof(double)*(periods+y_kmax+y_kmin));
|
||||
test_mxMalloc(y_save, __LINE__, __FILE__, __func__, y_size*sizeof(double)*(periods+y_kmax+y_kmin));
|
||||
start_code = it_code;
|
||||
iter = 0;
|
||||
|
@ -461,7 +459,7 @@ Interpreter::simulate_a_block(vector_table_conditional_local_type vector_table_c
|
|||
memcpy(y_save, y, y_size*sizeof(double)*(periods+y_kmax+y_kmin));
|
||||
if (vector_table_conditional_local.size())
|
||||
{
|
||||
for (vector_table_conditional_local_type::iterator it1 = vector_table_conditional_local.begin(); it1 != vector_table_conditional_local.end() ; it1++)
|
||||
for (vector_table_conditional_local_type::iterator it1 = vector_table_conditional_local.begin(); it1 != vector_table_conditional_local.end(); it1++)
|
||||
{
|
||||
if (it1->is_cond)
|
||||
{
|
||||
|
@ -476,7 +474,7 @@ Interpreter::simulate_a_block(vector_table_conditional_local_type vector_table_c
|
|||
if (!(isnan(res1) || isinf(res1)))
|
||||
cvg = (max_res < solve_tolf);
|
||||
if (isnan(res1) || isinf(res1) || (stack_solve_algo == 4 && iter > 0))
|
||||
memcpy(y, y_save, y_size*sizeof(double)*(periods+y_kmax+y_kmin));
|
||||
memcpy(y, y_save, y_size*sizeof(double)*(periods+y_kmax+y_kmin));
|
||||
u_count = u_count_saved;
|
||||
int prev_iter = iter;
|
||||
Simulate_Newton_Two_Boundaries(block_num, symbol_table_endo_nbr, y_kmin, y_kmax, size, periods, cvg, minimal_solving_periods, stack_solve_algo, endo_name_length, P_endo_names, vector_table_conditional_local);
|
||||
|
@ -509,17 +507,17 @@ Interpreter::simulate_a_block(vector_table_conditional_local_type vector_table_c
|
|||
Simulate_Newton_Two_Boundaries(block_num, symbol_table_endo_nbr, y_kmin, y_kmax, size, periods, cvg, minimal_solving_periods, stack_solve_algo, endo_name_length, P_endo_names, vector_table_conditional_local);
|
||||
max_res = 0; max_res_idx = 0;
|
||||
}
|
||||
it_code = end_code;
|
||||
it_code = end_code;
|
||||
if (r)
|
||||
mxFree(r);
|
||||
mxFree(r);
|
||||
if (y_save)
|
||||
mxFree(y_save);
|
||||
mxFree(y_save);
|
||||
if (u)
|
||||
mxFree(u);
|
||||
mxFree(u);
|
||||
if (index_vara)
|
||||
mxFree(index_vara);
|
||||
mxFree(index_vara);
|
||||
if (index_equa)
|
||||
mxFree(index_equa);
|
||||
mxFree(index_equa);
|
||||
if (res)
|
||||
mxFree(res);
|
||||
memset(direction, 0, size_of_direction);
|
||||
|
@ -601,9 +599,8 @@ Interpreter::ReadCodeFile(string file_name, CodeLoad &code)
|
|||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Interpreter::check_for_controlled_exo_validity(FBEGINBLOCK_ *fb,vector<s_plan> sconstrained_extended_path)
|
||||
Interpreter::check_for_controlled_exo_validity(FBEGINBLOCK_ *fb, vector<s_plan> sconstrained_extended_path)
|
||||
{
|
||||
vector<unsigned int> exogenous = fb->get_exogenous();
|
||||
vector<int> endogenous = fb->get_endogenous();
|
||||
|
@ -632,8 +629,6 @@ Interpreter::check_for_controlled_exo_validity(FBEGINBLOCK_ *fb,vector<s_plan> s
|
|||
previous_block_exogenous.push_back(*it);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
Interpreter::MainLoop(string bin_basename, CodeLoad code, bool evaluate, int block, bool last_call, bool constrained, vector<s_plan> sconstrained_extended_path, vector_table_conditional_local_type vector_table_conditional_local)
|
||||
{
|
||||
|
@ -670,7 +665,7 @@ Interpreter::MainLoop(string bin_basename, CodeLoad code, bool evaluate, int blo
|
|||
Block_Contain = fb->get_Block_Contain();
|
||||
it_code++;
|
||||
if (constrained)
|
||||
check_for_controlled_exo_validity(fb,sconstrained_extended_path);
|
||||
check_for_controlled_exo_validity(fb, sconstrained_extended_path);
|
||||
set_block(fb->get_size(), fb->get_type(), file_name, bin_basename, Block_Count, fb->get_is_linear(), fb->get_endo_nbr(), fb->get_Max_Lag(), fb->get_Max_Lead(), fb->get_u_count_int(), block);
|
||||
if (print)
|
||||
print_a_block();
|
||||
|
@ -761,8 +756,8 @@ Interpreter::MainLoop(string bin_basename, CodeLoad code, bool evaluate, int blo
|
|||
#endif
|
||||
var = ((FDIMT_ *) it_code->second)->get_size();
|
||||
if (T)
|
||||
mxFree(T);
|
||||
T = (double *) mxMalloc(var*(periods+y_kmin+y_kmax)*sizeof(double));
|
||||
mxFree(T);
|
||||
T = (double *) mxMalloc(var*(periods+y_kmin+y_kmax)*sizeof(double));
|
||||
test_mxMalloc(T, __LINE__, __FILE__, __func__, var*(periods+y_kmin+y_kmax)*sizeof(double));
|
||||
if (block >= 0)
|
||||
{
|
||||
|
@ -788,13 +783,12 @@ Interpreter::MainLoop(string bin_basename, CodeLoad code, bool evaluate, int blo
|
|||
GlobalTemporaryTerms = mxCreateDoubleMatrix(var, 1, mxREAL);
|
||||
T = mxGetPr(GlobalTemporaryTerms);
|
||||
}
|
||||
else
|
||||
{
|
||||
T = (double *) mxMalloc(var*sizeof(double));
|
||||
test_mxMalloc(T, __LINE__, __FILE__, __func__, var*sizeof(double));
|
||||
else
|
||||
{
|
||||
T = (double *) mxMalloc(var*sizeof(double));
|
||||
test_mxMalloc(T, __LINE__, __FILE__, __func__, var*sizeof(double));
|
||||
}
|
||||
|
||||
|
||||
if (block >= 0)
|
||||
it_code = code_liste.begin() + code.get_begin_block(block);
|
||||
else
|
||||
|
@ -806,7 +800,7 @@ Interpreter::MainLoop(string bin_basename, CodeLoad code, bool evaluate, int blo
|
|||
throw FatalExceptionHandling(tmp.str());
|
||||
}
|
||||
}
|
||||
max_res = max_res_local ;
|
||||
max_res = max_res_local;
|
||||
max_res_idx = max_res_idx_local;
|
||||
Close_SaveCode();
|
||||
return true;
|
||||
|
@ -825,13 +819,13 @@ Interpreter::elastic(string str, unsigned int len, bool left)
|
|||
if (left)
|
||||
{
|
||||
//mexPrintf("(1) diff=%d\n",diff);
|
||||
str.insert(str.end(),diff-1,' ');
|
||||
str.insert(str.begin(),1,' ');
|
||||
str.insert(str.end(), diff-1, ' ');
|
||||
str.insert(str.begin(), 1, ' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
str.insert(str.end(),diff/2,' ');
|
||||
str.insert(str.begin(),diff/2,' ');
|
||||
str.insert(str.end(), diff/2, ' ');
|
||||
str.insert(str.begin(), diff/2, ' ');
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -839,13 +833,13 @@ Interpreter::elastic(string str, unsigned int len, bool left)
|
|||
if (left)
|
||||
{
|
||||
//mexPrintf("(2) diff=%d\n",diff);
|
||||
str.insert(str.end(),diff-1,' ');
|
||||
str.insert(str.begin(),1,' ');
|
||||
str.insert(str.end(), diff-1, ' ');
|
||||
str.insert(str.begin(), 1, ' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
str.insert(str.end(),ceil(diff/2),' ');
|
||||
str.insert(str.begin(),ceil(diff/2+1),' ');
|
||||
str.insert(str.end(), ceil(diff/2), ' ');
|
||||
str.insert(str.begin(), ceil(diff/2+1), ' ');
|
||||
}
|
||||
}
|
||||
return str;
|
||||
|
@ -855,14 +849,14 @@ Interpreter::elastic(string str, unsigned int len, bool left)
|
|||
bool
|
||||
Interpreter::extended_path(string file_name, string bin_basename, bool evaluate, int block, int &nb_blocks, int nb_periods, vector<s_plan> sextended_path, vector<s_plan> sconstrained_extended_path, vector<string> dates, table_conditional_global_type table_conditional_global)
|
||||
{
|
||||
CodeLoad code;
|
||||
CodeLoad code;
|
||||
|
||||
ReadCodeFile(file_name, code);
|
||||
it_code = code_liste.begin();
|
||||
it_code_type Init_Code = code_liste.begin();
|
||||
/*size_t size_of_direction = y_size*(periods + y_kmax + y_kmin)*sizeof(double);
|
||||
double *y_save = (double *) mxMalloc(size_of_direction);
|
||||
double *x_save = (double *) mxMalloc((periods + y_kmax + y_kmin) * col_x *sizeof(double));*/
|
||||
double *y_save = (double *) mxMalloc(size_of_direction);
|
||||
double *x_save = (double *) mxMalloc((periods + y_kmax + y_kmin) * col_x *sizeof(double));*/
|
||||
size_t size_of_direction = y_size*col_y*sizeof(double);
|
||||
double *y_save = (double *) mxMalloc(size_of_direction);
|
||||
test_mxMalloc(y_save, __LINE__, __FILE__, __func__, size_of_direction);
|
||||
|
@ -872,7 +866,7 @@ Interpreter::extended_path(string file_name, string bin_basename, bool evaluate,
|
|||
vector_table_conditional_local_type vector_table_conditional_local;
|
||||
vector_table_conditional_local.clear();
|
||||
|
||||
int endo_name_length_l = endo_name_length;
|
||||
int endo_name_length_l = endo_name_length;
|
||||
for (int j = 0; j < col_x* nb_row_x; j++)
|
||||
{
|
||||
x_save[j] = x[j];
|
||||
|
@ -892,16 +886,16 @@ Interpreter::extended_path(string file_name, string bin_basename, bool evaluate,
|
|||
int date_length = dates[0].length();
|
||||
int table_length = 2 + date_length + 3 + endo_name_length_l + 3 + real_max_length + 3 + 3 + 2 + 6 + 2;
|
||||
string line;
|
||||
line.insert(line.begin(),table_length,'-');
|
||||
line.insert(line.length(),"\n");
|
||||
line.insert(line.begin(), table_length, '-');
|
||||
line.insert(line.length(), "\n");
|
||||
if (old_print_it)
|
||||
{
|
||||
mexPrintf("\nExtended Path simulation:\n");
|
||||
mexPrintf("-------------------------\n");
|
||||
mexPrintf(line.c_str());
|
||||
string title = "|" + elastic("date",date_length+2, false) + "|" + elastic("variable",endo_name_length_l+2, false) + "|" + elastic("max. value",real_max_length+2, false) + "| iter. |" + elastic("cvg",5, false) + "|\n";
|
||||
mexPrintf(title.c_str());
|
||||
mexPrintf(line.c_str());
|
||||
mexPrintf("\nExtended Path simulation:\n");
|
||||
mexPrintf("-------------------------\n");
|
||||
mexPrintf(line.c_str());
|
||||
string title = "|" + elastic("date", date_length+2, false) + "|" + elastic("variable", endo_name_length_l+2, false) + "|" + elastic("max. value", real_max_length+2, false) + "| iter. |" + elastic("cvg", 5, false) + "|\n";
|
||||
mexPrintf(title.c_str());
|
||||
mexPrintf(line.c_str());
|
||||
}
|
||||
for (int t = 0; t < nb_periods; t++)
|
||||
{
|
||||
|
@ -909,7 +903,7 @@ Interpreter::extended_path(string file_name, string bin_basename, bool evaluate,
|
|||
previous_block_exogenous.clear();
|
||||
if (old_print_it)
|
||||
{
|
||||
mexPrintf("|%s|",elastic(dates[t], date_length+2, false).c_str());
|
||||
mexPrintf("|%s|", elastic(dates[t], date_length+2, false).c_str());
|
||||
mexEvalString("drawnow;");
|
||||
}
|
||||
for (vector<s_plan>::const_iterator it = sextended_path.begin(); it != sextended_path.end(); it++)
|
||||
|
@ -932,8 +926,8 @@ Interpreter::extended_path(string file_name, string bin_basename, bool evaluate,
|
|||
y[j ] = y[ j + (y_kmin) * y_size];
|
||||
}
|
||||
for (int j = 0; j < col_x; j++)
|
||||
{
|
||||
x_save[t + y_kmin + j * nb_row_x] = x[y_kmin + j * nb_row_x];
|
||||
{
|
||||
x_save[t + y_kmin + j * nb_row_x] = x[y_kmin + j * nb_row_x];
|
||||
if (t < nb_periods)
|
||||
x[y_kmin + j * nb_row_x] = x_save[t + 1 + y_kmin + j * nb_row_x];
|
||||
}
|
||||
|
@ -945,30 +939,30 @@ Interpreter::extended_path(string file_name, string bin_basename, bool evaluate,
|
|||
if (P_endo_names[CHAR_LENGTH*(max_res_idx+i*y_size)] != ' ')
|
||||
res << P_endo_names[CHAR_LENGTH*(max_res_idx+i*y_size)];
|
||||
res1 << std::scientific << max_res;
|
||||
mexPrintf("%s|%s| %4d | x |\n",elastic(res.str(),endo_name_length_l+2, true).c_str(), elastic(res1.str(), real_max_length+2, false).c_str(), iter);
|
||||
mexPrintf("%s|%s| %4d | x |\n", elastic(res.str(), endo_name_length_l+2, true).c_str(), elastic(res1.str(), real_max_length+2, false).c_str(), iter);
|
||||
mexPrintf(line.c_str());
|
||||
mexEvalString("drawnow;");
|
||||
}
|
||||
}
|
||||
}
|
||||
print_it = old_print_it;
|
||||
/*for (int j = 0; j < y_size; j++)
|
||||
{
|
||||
for(int k = nb_periods; k < periods; k++)
|
||||
y_save[j + (k + y_kmin) * y_size] = y[ j + ( k - (nb_periods-1) + y_kmin) * y_size];
|
||||
for(int k = nb_periods; k < periods; k++)
|
||||
y_save[j + (k + y_kmin) * y_size] = y[ j + ( k - (nb_periods-1) + y_kmin) * y_size];
|
||||
}*/
|
||||
for (int i = 0; i < y_size * col_y; i++)
|
||||
y[i] = y_save[i];
|
||||
for (int i = 0; i < y_size * col_y; i++)
|
||||
y[i] = y_save[i];
|
||||
for (int j = 0; j < col_x * nb_row_x; j++)
|
||||
x[j] = x_save[j];
|
||||
x[j] = x_save[j];
|
||||
if (Init_Code->second)
|
||||
mxFree(Init_Code->second);
|
||||
mxFree(Init_Code->second);
|
||||
if (y_save)
|
||||
mxFree(y_save);
|
||||
mxFree(y_save);
|
||||
if (x_save)
|
||||
mxFree(x_save);
|
||||
mxFree(x_save);
|
||||
nb_blocks = Block_Count+1;
|
||||
if (T && !global_temporary_terms)
|
||||
mxFree(T);
|
||||
mxFree(T);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -986,7 +980,6 @@ Interpreter::compute_blocks(string file_name, string bin_basename, bool evaluate
|
|||
|
||||
MainLoop(bin_basename, code, evaluate, block, true, false, s_plan_junk, vector_table_conditional_local_junk);
|
||||
|
||||
|
||||
mxFree(Init_Code->second);
|
||||
nb_blocks = Block_Count+1;
|
||||
if (T && !global_temporary_terms)
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#define BYTE_CODE
|
||||
#include "CodeInterpreter.hh"
|
||||
#include "SparseMatrix.hh"
|
||||
#include "Evaluate.hh"
|
||||
#include "Evaluate.hh"
|
||||
#ifdef LINBCG
|
||||
# include "linbcg.hh"
|
||||
#endif
|
||||
|
@ -41,11 +41,10 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
|
||||
class Interpreter : public dynSparseMatrix
|
||||
{
|
||||
private:
|
||||
vector<int> previous_block_exogenous;
|
||||
vector<int> previous_block_exogenous;
|
||||
protected:
|
||||
void evaluate_a_block(bool initialization);
|
||||
int simulate_a_block(vector_table_conditional_local_type vector_table_conditional_local);
|
||||
|
@ -66,7 +65,7 @@ public:
|
|||
);
|
||||
bool extended_path(string file_name, string bin_basename, bool evaluate, int block, int &nb_blocks, int nb_periods, vector<s_plan> sextended_path, vector<s_plan> sconstrained_extended_path, vector<string> dates, table_conditional_global_type table_conditional_global);
|
||||
bool compute_blocks(string file_name, string bin_basename, bool evaluate, int block, int &nb_blocks);
|
||||
void check_for_controlled_exo_validity(FBEGINBLOCK_ *fb,vector<s_plan> sconstrained_extended_path);
|
||||
void check_for_controlled_exo_validity(FBEGINBLOCK_ *fb, vector<s_plan> sconstrained_extended_path);
|
||||
bool MainLoop(string bin_basename, CodeLoad code, bool evaluate, int block, bool last_call, bool constrained, vector<s_plan> sconstrained_extended_path, vector_table_conditional_local_type vector_table_conditional_local);
|
||||
void ReadCodeFile(string file_name, CodeLoad &code);
|
||||
|
||||
|
|
|
@ -25,14 +25,14 @@ Mem_Mngr::Mem_Mngr()
|
|||
swp_f_b = 0;
|
||||
}
|
||||
/*void
|
||||
Mem_Mngr::Print_heap()
|
||||
{
|
||||
Mem_Mngr::Print_heap()
|
||||
{
|
||||
unsigned int i;
|
||||
mexPrintf("i :");
|
||||
for (i = 0; i < CHUNK_SIZE; i++)
|
||||
mexPrintf("%3d ", i);
|
||||
mexPrintf("%3d ", i);
|
||||
mexPrintf("\n");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void
|
||||
|
@ -78,20 +78,20 @@ Mem_Mngr::mxMalloc_NZE()
|
|||
{
|
||||
CHUNK_SIZE += CHUNK_BLCK_SIZE;
|
||||
Nb_CHUNK++;
|
||||
NZE_Mem = (NonZeroElem *) mxMalloc(CHUNK_BLCK_SIZE*sizeof(NonZeroElem)); /*The block of memory allocated*/
|
||||
NZE_Mem = (NonZeroElem *) mxMalloc(CHUNK_BLCK_SIZE*sizeof(NonZeroElem)); /*The block of memory allocated*/
|
||||
error_msg.test_mxMalloc(NZE_Mem, __LINE__, __FILE__, __func__, CHUNK_BLCK_SIZE*sizeof(NonZeroElem));
|
||||
NZE_Mem_Allocated.push_back(NZE_Mem);
|
||||
if (!NZE_Mem)
|
||||
mexPrintf("Not enough memory available\n");
|
||||
if (NZE_Mem_add)
|
||||
{
|
||||
NZE_Mem_add = (NonZeroElem **) mxRealloc(NZE_Mem_add, CHUNK_SIZE*sizeof(NonZeroElem *)); /*We have to redefine the size of pointer on the memory*/
|
||||
error_msg.test_mxMalloc(NZE_Mem_add , __LINE__, __FILE__, __func__, CHUNK_SIZE*sizeof(NonZeroElem *));
|
||||
if (NZE_Mem_add)
|
||||
{
|
||||
NZE_Mem_add = (NonZeroElem **) mxRealloc(NZE_Mem_add, CHUNK_SIZE*sizeof(NonZeroElem *)); /*We have to redefine the size of pointer on the memory*/
|
||||
error_msg.test_mxMalloc(NZE_Mem_add, __LINE__, __FILE__, __func__, CHUNK_SIZE*sizeof(NonZeroElem *));
|
||||
}
|
||||
else
|
||||
{
|
||||
NZE_Mem_add = (NonZeroElem **) mxMalloc(CHUNK_SIZE*sizeof(NonZeroElem *)); /*We have to define the size of pointer on the memory*/
|
||||
error_msg.test_mxMalloc(NZE_Mem_add , __LINE__, __FILE__, __func__, CHUNK_SIZE*sizeof(NonZeroElem *));
|
||||
else
|
||||
{
|
||||
NZE_Mem_add = (NonZeroElem **) mxMalloc(CHUNK_SIZE*sizeof(NonZeroElem *)); /*We have to define the size of pointer on the memory*/
|
||||
error_msg.test_mxMalloc(NZE_Mem_add, __LINE__, __FILE__, __func__, CHUNK_SIZE*sizeof(NonZeroElem *));
|
||||
}
|
||||
|
||||
if (!NZE_Mem_add)
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#ifndef MEM_MNGR_HH_INCLUDED
|
||||
#define MEM_MNGR_HH_INCLUDED
|
||||
|
||||
|
||||
#include "ErrorHandling.hh"
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
@ -27,7 +27,7 @@
|
|||
# include <dynmex.h>
|
||||
#else
|
||||
# include "mex_interface.hh"
|
||||
#endif
|
||||
#endif
|
||||
//using namespace std;
|
||||
|
||||
struct NonZeroElem
|
||||
|
@ -50,7 +50,7 @@ public:
|
|||
void Free_All();
|
||||
Mem_Mngr();
|
||||
void fixe_file_name(string filename_arg);
|
||||
bool swp_f;
|
||||
bool swp_f;
|
||||
ErrorMsg error_msg;
|
||||
private:
|
||||
v_NonZeroElem Chunk_Stack;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -27,14 +27,14 @@
|
|||
#include <ctime>
|
||||
#include "dynblas.h"
|
||||
#if !(defined _MSC_VER)
|
||||
#include "dynumfpack.h"
|
||||
# include "dynumfpack.h"
|
||||
#endif
|
||||
|
||||
#ifdef CUDA
|
||||
#include "cuda.h"
|
||||
#include "cuda_runtime_api.h"
|
||||
#include "cublas_v2.h"
|
||||
#include "cusparse_v2.h"
|
||||
# include "cuda.h"
|
||||
# include "cuda_runtime_api.h"
|
||||
# include "cublas_v2.h"
|
||||
# include "cusparse_v2.h"
|
||||
#endif
|
||||
|
||||
#include "Mem_Mngr.hh"
|
||||
|
@ -42,38 +42,38 @@
|
|||
//#include "Interpreter.hh"
|
||||
#include "Evaluate.hh"
|
||||
|
||||
#define cudaChk(x, y) \
|
||||
{ \
|
||||
cudaError_t cuda_error = x; \
|
||||
if (cuda_error != cudaSuccess) \
|
||||
{ \
|
||||
ostringstream tmp; \
|
||||
tmp << y; \
|
||||
throw FatalExceptionHandling(tmp.str()); \
|
||||
} \
|
||||
};
|
||||
#define cudaChk(x, y) \
|
||||
{ \
|
||||
cudaError_t cuda_error = x; \
|
||||
if (cuda_error != cudaSuccess) \
|
||||
{ \
|
||||
ostringstream tmp; \
|
||||
tmp << y; \
|
||||
throw FatalExceptionHandling(tmp.str()); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define cusparseChk(x, y) \
|
||||
{ \
|
||||
cusparseStatus_t cusparse_status = x; \
|
||||
if (cusparse_status != CUSPARSE_STATUS_SUCCESS) \
|
||||
{ \
|
||||
ostringstream tmp; \
|
||||
tmp << y; \
|
||||
throw FatalExceptionHandling(tmp.str()); \
|
||||
} \
|
||||
};
|
||||
#define cusparseChk(x, y) \
|
||||
{ \
|
||||
cusparseStatus_t cusparse_status = x; \
|
||||
if (cusparse_status != CUSPARSE_STATUS_SUCCESS) \
|
||||
{ \
|
||||
ostringstream tmp; \
|
||||
tmp << y; \
|
||||
throw FatalExceptionHandling(tmp.str()); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define cublasChk(x, y) \
|
||||
{ \
|
||||
cublasStatus_t cublas_status = x; \
|
||||
if (cublas_status != CUBLAS_STATUS_SUCCESS) \
|
||||
{ \
|
||||
ostringstream tmp; \
|
||||
tmp << y; \
|
||||
throw FatalExceptionHandling(tmp.str()); \
|
||||
} \
|
||||
};
|
||||
#define cublasChk(x, y) \
|
||||
{ \
|
||||
cublasStatus_t cublas_status = x; \
|
||||
if (cublas_status != CUBLAS_STATUS_SUCCESS) \
|
||||
{ \
|
||||
ostringstream tmp; \
|
||||
tmp << y; \
|
||||
throw FatalExceptionHandling(tmp.str()); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define NEW_ALLOC
|
||||
#define MARKOVITZ
|
||||
|
@ -99,20 +99,18 @@ const double very_big = 1e24;
|
|||
const int alt_symbolic_count_max = 1;
|
||||
const double mem_increasing_factor = 1.1;
|
||||
|
||||
|
||||
|
||||
class dynSparseMatrix : public Evaluate
|
||||
{
|
||||
public:
|
||||
#if (defined _MSC_VER)
|
||||
#if (defined _MSC_VER)
|
||||
typedef int64_t SuiteSparse_long;
|
||||
#endif
|
||||
#endif
|
||||
dynSparseMatrix();
|
||||
dynSparseMatrix(const int y_size_arg, const int y_kmin_arg, const int y_kmax_arg, const bool print_it_arg, const bool steady_state_arg, const int periods_arg, const int minimal_solving_periods_arg, const double slowc_arg
|
||||
#ifdef CUDA
|
||||
,const int CUDA_device_arg, cublasHandle_t cublas_handle_arg, cusparseHandle_t cusparse_handle_arg, cusparseMatDescr_t descr_arg
|
||||
, const int CUDA_device_arg, cublasHandle_t cublas_handle_arg, cusparseHandle_t cusparse_handle_arg, cusparseMatDescr_t descr_arg
|
||||
#endif
|
||||
);
|
||||
);
|
||||
void Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin, int y_kmax, int Size, int periods, bool cvg, int minimal_solving_periods, int stack_solve_algo, unsigned int endo_name_length, char *P_endo_names, vector_table_conditional_local_type vector_table_conditional_local);
|
||||
void Simulate_Newton_One_Boundary(bool forward);
|
||||
void fixe_u(double **u, int u_count_int, int max_lag_plus_max_lead_plus_1);
|
||||
|
@ -146,17 +144,17 @@ private:
|
|||
void Solve_Matlab_LU_UMFPack(mxArray *A_m, mxArray *b_m, int Size, double slowc_l, bool is_two_boundaries, int it_);
|
||||
void Print_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, int n);
|
||||
void Printfull_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, double *b, int n);
|
||||
void PrintM(int n, double* Ax, mwIndex *Ap, mwIndex *Ai);
|
||||
void PrintM(int n, double *Ax, mwIndex *Ap, mwIndex *Ai);
|
||||
void Solve_LU_UMFPack(mxArray *A_m, mxArray *b_m, int Size, double slowc_l, bool is_two_boundaries, int it_);
|
||||
void Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, double *b, int n, int Size, double slowc_l, bool is_two_boundaries, int it_, vector_table_conditional_local_type vector_table_conditional_local);
|
||||
void Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, double *b, int n, int Size, double slowc_l, bool is_two_boundaries, int it_);
|
||||
|
||||
void End_Matlab_LU_UMFPack();
|
||||
#ifdef CUDA
|
||||
void Solve_CUDA_BiCGStab_Free(double* tmp_vect_host, double* p, double* r, double* v, double* s, double* t, double* y_, double* z, double* tmp_,
|
||||
int* Ai, double* Ax, int* Ap, double* x0, double* b, double* A_tild, int* A_tild_i, int* A_tild_p,
|
||||
cusparseSolveAnalysisInfo_t infoL, cusparseSolveAnalysisInfo_t infoU,
|
||||
cusparseMatDescr_t descrL, cusparseMatDescr_t descrU, int preconditioner);
|
||||
void Solve_CUDA_BiCGStab_Free(double *tmp_vect_host, double *p, double *r, double *v, double *s, double *t, double *y_, double *z, double *tmp_,
|
||||
int *Ai, double *Ax, int *Ap, double *x0, double *b, double *A_tild, int *A_tild_i, int *A_tild_p,
|
||||
cusparseSolveAnalysisInfo_t infoL, cusparseSolveAnalysisInfo_t infoU,
|
||||
cusparseMatDescr_t descrL, cusparseMatDescr_t descrU, int preconditioner);
|
||||
int Solve_CUDA_BiCGStab(int *Ap, int *Ai, double *Ax, int *Ap_tild, int *Ai_tild, double *A_tild, double *b, double *x0, int n, int Size, double slowc_l, bool is_two_boundaries, int it_, int nnz, int nnz_tild, int preconditioner, int max_iterations, int block);
|
||||
#endif
|
||||
void Solve_Matlab_GMRES(mxArray *A_m, mxArray *b_m, int Size, double slowc, int block, bool is_two_boundaries, int it_, mxArray *x0_m);
|
||||
|
@ -171,7 +169,7 @@ private:
|
|||
, long int *ndiv, long int *nsub
|
||||
#endif
|
||||
);
|
||||
void Grad_f_product(int n, mxArray *b_m, double* vectr, mxArray *A_m, SuiteSparse_long *Ap, SuiteSparse_long *Ai, double* Ax, double *b);
|
||||
void Grad_f_product(int n, mxArray *b_m, double *vectr, mxArray *A_m, SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, double *b);
|
||||
void Insert(const int r, const int c, const int u_index, const int lag_index);
|
||||
void Delete(const int r, const int c);
|
||||
int At_Row(int r, NonZeroElem **first);
|
||||
|
@ -186,15 +184,15 @@ private:
|
|||
void Delete_u(int pos);
|
||||
void Clear_u();
|
||||
void Print_u();
|
||||
void *Symbolic, *Numeric ;
|
||||
void *Symbolic, *Numeric;
|
||||
void CheckIt(int y_size, int y_kmin, int y_kmax, int Size, int periods);
|
||||
void Check_the_Solution(int periods, int y_kmin, int y_kmax, int Size, double *u, int *pivot, int *b);
|
||||
int complete(int beg_t, int Size, int periods, int *b);
|
||||
void bksub(int tbreak, int last_period, int Size, double slowc_l
|
||||
#ifdef PROFILER
|
||||
, long int *nmul
|
||||
, long int *nmul
|
||||
#endif
|
||||
);
|
||||
);
|
||||
void simple_bksub(int it_, int Size, double slowc_l);
|
||||
mxArray *Sparse_transpose(mxArray *A_m);
|
||||
mxArray *Sparse_mult_SAT_SB(mxArray *A_m, mxArray *B_m);
|
||||
|
@ -245,7 +243,7 @@ protected:
|
|||
int u_count_alloc, u_count_alloc_save;
|
||||
vector<double *> jac;
|
||||
double *jcb;
|
||||
double slowc_save, prev_slowc_save, markowitz_c;
|
||||
double slowc_save, prev_slowc_save, markowitz_c;
|
||||
int y_decal;
|
||||
int *index_equa;
|
||||
int u_count, tbreak_g;
|
||||
|
@ -254,7 +252,7 @@ protected:
|
|||
int restart;
|
||||
double g_lambda1, g_lambda2, gp_0;
|
||||
double lu_inc_tol;
|
||||
//private:
|
||||
//private:
|
||||
SuiteSparse_long *Ap_save, *Ai_save;
|
||||
double *Ax_save, *b_save;
|
||||
mxArray *A_m_save, *b_m_save;
|
||||
|
|
|
@ -22,46 +22,42 @@
|
|||
#include <ctime>
|
||||
#include <math.h>
|
||||
#ifdef DYN_MEX_FUNC_ERR_MSG_TXT
|
||||
#undef DYN_MEX_FUNC_ERR_MSG_TXT
|
||||
# undef DYN_MEX_FUNC_ERR_MSG_TXT
|
||||
#endif // DYN_MEX_FUNC_ERR_MSG_TXT
|
||||
|
||||
#define DYN_MEX_FUNC_ERR_MSG_TXT(str) \
|
||||
do { \
|
||||
mexPrintf("%s\n", str); \
|
||||
if (nlhs > 0) \
|
||||
{ \
|
||||
plhs[0] = mxCreateDoubleScalar(1); \
|
||||
if (nlhs > 1) \
|
||||
{ \
|
||||
double *pind; \
|
||||
plhs[1] = mxCreateDoubleMatrix(int(row_y), int(col_y), mxREAL); \
|
||||
pind = mxGetPr(plhs[1]); \
|
||||
if (evaluate ) \
|
||||
{ \
|
||||
for (unsigned int i = 0; i < row_y*col_y; i++) \
|
||||
pind[i] = 0; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
for (unsigned int i = 0; i < row_y*col_y; i++) \
|
||||
pind[i] = yd[i]; \
|
||||
} \
|
||||
for (int i = 2; i < nlhs; i++) \
|
||||
plhs[i] = mxCreateDoubleScalar(1); \
|
||||
} \
|
||||
} \
|
||||
return; \
|
||||
#define DYN_MEX_FUNC_ERR_MSG_TXT(str) \
|
||||
do { \
|
||||
mexPrintf("%s\n", str); \
|
||||
if (nlhs > 0) \
|
||||
{ \
|
||||
plhs[0] = mxCreateDoubleScalar(1); \
|
||||
if (nlhs > 1) \
|
||||
{ \
|
||||
double *pind; \
|
||||
plhs[1] = mxCreateDoubleMatrix(int (row_y), int (col_y), mxREAL); \
|
||||
pind = mxGetPr(plhs[1]); \
|
||||
if (evaluate) \
|
||||
{ \
|
||||
for (unsigned int i = 0; i < row_y*col_y; i++) \
|
||||
pind[i] = 0; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
for (unsigned int i = 0; i < row_y*col_y; i++) \
|
||||
pind[i] = yd[i]; \
|
||||
} \
|
||||
for (int i = 2; i < nlhs; i++) \
|
||||
plhs[i] = mxCreateDoubleScalar(1); \
|
||||
} \
|
||||
} \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#ifdef DEBUG_EX
|
||||
|
||||
using namespace std;
|
||||
# include <sstream>
|
||||
|
||||
|
||||
|
||||
|
||||
string
|
||||
Get_Argument(const char *argv)
|
||||
{
|
||||
|
@ -73,7 +69,6 @@ Get_Argument(const char *argv)
|
|||
|
||||
void (*prev_fn)(int);
|
||||
|
||||
|
||||
string
|
||||
Get_Argument(const mxArray *prhs)
|
||||
{
|
||||
|
@ -90,11 +85,9 @@ Get_Argument(const mxArray *prhs)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
//#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifdef CUDA
|
||||
int
|
||||
GPU_Test_and_Info(cublasHandle_t *cublas_handle, cusparseHandle_t *cusparse_handle, cusparseMatDescr_t *descr)
|
||||
|
@ -103,7 +96,7 @@ GPU_Test_and_Info(cublasHandle_t *cublas_handle, cusparseHandle_t *cusparse_hand
|
|||
int device_count, device, version, version_max = 0;
|
||||
cublasStatus_t cublas_status;
|
||||
cudaError_t cuda_error;
|
||||
*descr=0;
|
||||
*descr = 0;
|
||||
|
||||
/* ask cuda how many devices it can find */
|
||||
cudaGetDeviceCount(&device_count);
|
||||
|
@ -124,9 +117,9 @@ GPU_Test_and_Info(cublasHandle_t *cublas_handle, cusparseHandle_t *cusparse_hand
|
|||
cuda_error = cudaGetDeviceProperties(&deviceProp, i);
|
||||
if (cuda_error != cudaSuccess)
|
||||
{
|
||||
ostringstream tmp;
|
||||
tmp << " bytecode cudaGetDeviceProperties failed\n";
|
||||
throw FatalExceptionHandling(tmp.str());
|
||||
ostringstream tmp;
|
||||
tmp << " bytecode cudaGetDeviceProperties failed\n";
|
||||
throw FatalExceptionHandling(tmp.str());
|
||||
}
|
||||
mexPrintf("> GPU device %d: \"%s\" has:\n - %d Multi-Processors,\n - %d threads per multiprocessor,\n", i, deviceProp.name, deviceProp.multiProcessorCount, deviceProp.maxThreadsPerMultiProcessor);
|
||||
mexEvalString("drawnow;");
|
||||
|
@ -136,7 +129,7 @@ GPU_Test_and_Info(cublasHandle_t *cublas_handle, cusparseHandle_t *cusparse_hand
|
|||
device = i;
|
||||
version_max = version;
|
||||
}
|
||||
mexPrintf(" - %4.2fMhz clock rate,\n - %2.0fMb of memory,\n - %d.%d compute capabilities.\n", double(deviceProp.clockRate) / (1024 * 1024), double(deviceProp.totalGlobalMem) / (1024 * 1024), deviceProp.major, deviceProp.minor);
|
||||
mexPrintf(" - %4.2fMhz clock rate,\n - %2.0fMb of memory,\n - %d.%d compute capabilities.\n", double (deviceProp.clockRate) / (1024 * 1024), double (deviceProp.totalGlobalMem) / (1024 * 1024), deviceProp.major, deviceProp.minor);
|
||||
mexEvalString("drawnow;");
|
||||
}
|
||||
}
|
||||
|
@ -146,17 +139,17 @@ GPU_Test_and_Info(cublasHandle_t *cublas_handle, cusparseHandle_t *cusparse_hand
|
|||
cuda_error = cudaSetDevice(device);
|
||||
if (cuda_error != cudaSuccess)
|
||||
{
|
||||
ostringstream tmp;
|
||||
tmp << " bytecode cudaSetDevice failed\n";
|
||||
throw FatalExceptionHandling(tmp.str());
|
||||
ostringstream tmp;
|
||||
tmp << " bytecode cudaSetDevice failed\n";
|
||||
throw FatalExceptionHandling(tmp.str());
|
||||
}
|
||||
|
||||
if(version_max < 0x11)
|
||||
if (version_max < 0x11)
|
||||
{
|
||||
ostringstream tmp;
|
||||
tmp << " bytecode requires a minimum CUDA compute 1.1 capability\n";
|
||||
cudaDeviceReset();
|
||||
throw FatalExceptionHandling(tmp.str());
|
||||
ostringstream tmp;
|
||||
tmp << " bytecode requires a minimum CUDA compute 1.1 capability\n";
|
||||
cudaDeviceReset();
|
||||
throw FatalExceptionHandling(tmp.str());
|
||||
}
|
||||
|
||||
// Initialize CuBlas library
|
||||
|
@ -164,16 +157,16 @@ GPU_Test_and_Info(cublasHandle_t *cublas_handle, cusparseHandle_t *cusparse_hand
|
|||
if (cublas_status != CUBLAS_STATUS_SUCCESS)
|
||||
{
|
||||
ostringstream tmp;
|
||||
switch(cublas_status)
|
||||
switch (cublas_status)
|
||||
{
|
||||
case CUBLAS_STATUS_NOT_INITIALIZED:
|
||||
tmp << " the CUBLAS initialization failed.\n";
|
||||
break;
|
||||
case CUBLAS_STATUS_ALLOC_FAILED:
|
||||
tmp << " the resources could not be allocated.\n";
|
||||
break;
|
||||
default:
|
||||
tmp << " unknown error during the initialization of cusparse library.\n";
|
||||
case CUBLAS_STATUS_NOT_INITIALIZED:
|
||||
tmp << " the CUBLAS initialization failed.\n";
|
||||
break;
|
||||
case CUBLAS_STATUS_ALLOC_FAILED:
|
||||
tmp << " the resources could not be allocated.\n";
|
||||
break;
|
||||
default:
|
||||
tmp << " unknown error during the initialization of cusparse library.\n";
|
||||
}
|
||||
throw FatalExceptionHandling(tmp.str());
|
||||
}
|
||||
|
@ -184,19 +177,19 @@ GPU_Test_and_Info(cublasHandle_t *cublas_handle, cusparseHandle_t *cusparse_hand
|
|||
if (cusparse_status != CUSPARSE_STATUS_SUCCESS)
|
||||
{
|
||||
ostringstream tmp;
|
||||
switch(cusparse_status)
|
||||
switch (cusparse_status)
|
||||
{
|
||||
case CUSPARSE_STATUS_NOT_INITIALIZED:
|
||||
tmp << " the CUDA Runtime initialization failed.\n";
|
||||
break;
|
||||
case CUSPARSE_STATUS_ALLOC_FAILED:
|
||||
tmp << " the resources could not be allocated.\n";
|
||||
break;
|
||||
case CUSPARSE_STATUS_ARCH_MISMATCH:
|
||||
tmp << " the device compute capability (CC) is less than 1.1. The CC of at least 1.1 is required.\n";
|
||||
break;
|
||||
default:
|
||||
tmp << " unknown error during the initialization of cusparse library.\n";
|
||||
case CUSPARSE_STATUS_NOT_INITIALIZED:
|
||||
tmp << " the CUDA Runtime initialization failed.\n";
|
||||
break;
|
||||
case CUSPARSE_STATUS_ALLOC_FAILED:
|
||||
tmp << " the resources could not be allocated.\n";
|
||||
break;
|
||||
case CUSPARSE_STATUS_ARCH_MISMATCH:
|
||||
tmp << " the device compute capability (CC) is less than 1.1. The CC of at least 1.1 is required.\n";
|
||||
break;
|
||||
default:
|
||||
tmp << " unknown error during the initialization of cusparse library.\n";
|
||||
}
|
||||
throw FatalExceptionHandling(tmp.str());
|
||||
}
|
||||
|
@ -221,7 +214,7 @@ GPU_Test_and_Info(cublasHandle_t *cublas_handle, cusparseHandle_t *cusparse_hand
|
|||
tmp << " cudaGetVersion has failed\n";
|
||||
throw FatalExceptionHandling(tmp.str());
|
||||
}
|
||||
mexPrintf(" - CUDA version %5.3f\n", double(cuda_version) / 1000);
|
||||
mexPrintf(" - CUDA version %5.3f\n", double (cuda_version) / 1000);
|
||||
int cublas_version;
|
||||
cublas_status = cublasGetVersion(*cublas_handle, &cublas_version);
|
||||
if (cublas_status != CUBLAS_STATUS_SUCCESS)
|
||||
|
@ -230,7 +223,7 @@ GPU_Test_and_Info(cublasHandle_t *cublas_handle, cusparseHandle_t *cusparse_hand
|
|||
tmp << " cublasGetVersion has failed\n";
|
||||
throw FatalExceptionHandling(tmp.str());
|
||||
}
|
||||
mexPrintf(" - CUBLAS version %5.3f\n", double(cublas_version) / 1000);
|
||||
mexPrintf(" - CUBLAS version %5.3f\n", double (cublas_version) / 1000);
|
||||
int cusparse_version;
|
||||
cusparse_status = cusparseGetVersion(*cusparse_handle, &cusparse_version);
|
||||
if (cusparse_status != CUSPARSE_STATUS_SUCCESS)
|
||||
|
@ -239,7 +232,7 @@ GPU_Test_and_Info(cublasHandle_t *cublas_handle, cusparseHandle_t *cusparse_hand
|
|||
tmp << " cusparseGetVersion has failed\n";
|
||||
throw FatalExceptionHandling(tmp.str());
|
||||
}
|
||||
mexPrintf(" - CUSPARSE version %5.3f\n", double(cusparse_version) / 1000);
|
||||
mexPrintf(" - CUSPARSE version %5.3f\n", double (cusparse_version) / 1000);
|
||||
mexPrintf("-----------------------------------------\n");
|
||||
return device;
|
||||
}
|
||||
|
@ -247,16 +240,16 @@ GPU_Test_and_Info(cublasHandle_t *cublas_handle, cusparseHandle_t *cusparse_hand
|
|||
void
|
||||
GPU_close(cublasHandle_t cublas_handle, cusparseHandle_t cusparse_handle, cusparseMatDescr_t descr)
|
||||
{
|
||||
cublasChk(cublasDestroy(cublas_handle),"in bytecode cublasDestroy failed\n");
|
||||
cublasChk(cublasDestroy(cublas_handle), "in bytecode cublasDestroy failed\n");
|
||||
cusparseChk(cusparseDestroyMatDescr(descr), "in bytecode cusparseDestroyMatDescr failed\n");
|
||||
cusparseChk(cusparseDestroy(cusparse_handle),"in bytecode cusparseDestroy failed\n");
|
||||
cusparseChk(cusparseDestroy(cusparse_handle), "in bytecode cusparseDestroy failed\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
string
|
||||
deblank(string x)
|
||||
{
|
||||
for(int i = 0; i < (int) x.length(); i++)
|
||||
for (int i = 0; i < (int) x.length(); i++)
|
||||
if (x[i] == ' ')
|
||||
x.erase(i--, 1);
|
||||
return x;
|
||||
|
@ -317,7 +310,7 @@ Get_Arguments_and_global_variables(int nrhs,
|
|||
steady_col_y = mxGetN(prhs[i]);
|
||||
break;
|
||||
case 4:
|
||||
periods = int(mxGetScalar(prhs[i]));
|
||||
periods = int (mxGetScalar(prhs[i]));
|
||||
break;
|
||||
case 5:
|
||||
*block_structur = mxDuplicateArray(prhs[i]);
|
||||
|
@ -327,7 +320,7 @@ Get_Arguments_and_global_variables(int nrhs,
|
|||
*GlobalTemporaryTerms = mxDuplicateArray(prhs[i]);
|
||||
break;
|
||||
default:
|
||||
mexPrintf("Unknown argument count_array_argument=%d\n",count_array_argument);
|
||||
mexPrintf("Unknown argument count_array_argument=%d\n", count_array_argument);
|
||||
break;
|
||||
}
|
||||
count_array_argument++;
|
||||
|
@ -358,7 +351,7 @@ Get_Arguments_and_global_variables(int nrhs,
|
|||
pos += 5;
|
||||
block = atoi(Get_Argument(prhs[i]).substr(pos, string::npos).c_str())-1;
|
||||
}
|
||||
else if (Get_Argument(prhs[i]).substr(0,13) == "extended_path")
|
||||
else if (Get_Argument(prhs[i]).substr(0, 13) == "extended_path")
|
||||
{
|
||||
*extended_path = true;
|
||||
if ((i+1) >= nrhs)
|
||||
|
@ -430,7 +423,6 @@ Get_Arguments_and_global_variables(int nrhs,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_EX
|
||||
int
|
||||
main(int nrhs, const char *prhs[])
|
||||
|
@ -449,7 +441,7 @@ main(int nrhs, const char *prhs[])
|
|||
char *plhs[1];
|
||||
load_global((char *) prhs[1]);
|
||||
#endif
|
||||
mxArray *pfplan_struct = NULL;
|
||||
mxArray *pfplan_struct = NULL;
|
||||
ErrorMsg error_msg;
|
||||
size_t i, row_y = 0, col_y = 0, row_x = 0, col_x = 0, nb_row_xd = 0;
|
||||
size_t steady_row_y, steady_col_y;
|
||||
|
@ -467,7 +459,7 @@ main(int nrhs, const char *prhs[])
|
|||
double *steady_yd = NULL, *steady_xd = NULL;
|
||||
string plan, pfplan;
|
||||
bool extended_path;
|
||||
mxArray* extended_path_struct;
|
||||
mxArray *extended_path_struct;
|
||||
|
||||
table_conditional_local_type conditional_local;
|
||||
vector<s_plan> splan, spfplan, sextended_path, sconditional_extended_path;
|
||||
|
@ -520,76 +512,76 @@ main(int nrhs, const char *prhs[])
|
|||
string tmp = "The 'extended_path' option must be followed by the extended_path descriptor";
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
mxArray* date_str = mxGetField(extended_path_struct, 0, "date_str");
|
||||
mxArray *date_str = mxGetField(extended_path_struct, 0, "date_str");
|
||||
if (date_str == NULL)
|
||||
{
|
||||
string tmp = "date_str";
|
||||
tmp.insert(0,"The extended_path description structure does not contain the member: ");
|
||||
tmp.insert(0, "The extended_path description structure does not contain the member: ");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
int nb_periods = mxGetM(date_str) * mxGetN(date_str);
|
||||
|
||||
mxArray* constrained_vars_ = mxGetField(extended_path_struct, 0, "constrained_vars_");
|
||||
mxArray *constrained_vars_ = mxGetField(extended_path_struct, 0, "constrained_vars_");
|
||||
if (constrained_vars_ == NULL)
|
||||
{
|
||||
string tmp = "constrained_vars_";
|
||||
tmp.insert(0,"The extended_path description structure does not contain the member: ");
|
||||
tmp.insert(0, "The extended_path description structure does not contain the member: ");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
mxArray* constrained_paths_ = mxGetField(extended_path_struct, 0, "constrained_paths_");
|
||||
mxArray *constrained_paths_ = mxGetField(extended_path_struct, 0, "constrained_paths_");
|
||||
if (constrained_paths_ == NULL)
|
||||
{
|
||||
string tmp = "constrained_paths_";
|
||||
tmp.insert(0,"The extended_path description structure does not contain the member: ");
|
||||
tmp.insert(0, "The extended_path description structure does not contain the member: ");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
mxArray* constrained_int_date_ = mxGetField(extended_path_struct, 0, "constrained_int_date_");
|
||||
mxArray *constrained_int_date_ = mxGetField(extended_path_struct, 0, "constrained_int_date_");
|
||||
if (constrained_int_date_ == NULL)
|
||||
{
|
||||
string tmp = "constrained_int_date_";
|
||||
tmp.insert(0,"The extended_path description structure does not contain the member: ");
|
||||
tmp.insert(0, "The extended_path description structure does not contain the member: ");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
mxArray* constrained_perfect_foresight_ = mxGetField(extended_path_struct, 0, "constrained_perfect_foresight_");
|
||||
mxArray *constrained_perfect_foresight_ = mxGetField(extended_path_struct, 0, "constrained_perfect_foresight_");
|
||||
if (constrained_perfect_foresight_ == NULL)
|
||||
{
|
||||
string tmp = "constrained_perfect_foresight_";
|
||||
tmp.insert(0,"The extended_path description structure does not contain the member: ");
|
||||
tmp.insert(0, "The extended_path description structure does not contain the member: ");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
|
||||
mxArray* shock_var_ = mxGetField(extended_path_struct, 0, "shock_vars_");
|
||||
mxArray *shock_var_ = mxGetField(extended_path_struct, 0, "shock_vars_");
|
||||
if (shock_var_ == NULL)
|
||||
{
|
||||
string tmp = "shock_vars_";
|
||||
tmp.insert(0,"The extended_path description structure does not contain the member: ");
|
||||
tmp.insert(0, "The extended_path description structure does not contain the member: ");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
mxArray* shock_paths_ = mxGetField(extended_path_struct, 0, "shock_paths_");
|
||||
mxArray *shock_paths_ = mxGetField(extended_path_struct, 0, "shock_paths_");
|
||||
if (shock_paths_ == NULL)
|
||||
{
|
||||
string tmp = "shock_paths_";
|
||||
tmp.insert(0,"The extended_path description structure does not contain the member: ");
|
||||
tmp.insert(0, "The extended_path description structure does not contain the member: ");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
mxArray* shock_int_date_ = mxGetField(extended_path_struct, 0, "shock_int_date_");
|
||||
mxArray *shock_int_date_ = mxGetField(extended_path_struct, 0, "shock_int_date_");
|
||||
if (shock_int_date_ == NULL)
|
||||
{
|
||||
string tmp = "shock_int_date_";
|
||||
tmp.insert(0,"The extended_path description structure does not contain the member: ");
|
||||
tmp.insert(0, "The extended_path description structure does not contain the member: ");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
mxArray* shock_str_date_ = mxGetField(extended_path_struct, 0, "shock_str_date_");
|
||||
mxArray *shock_str_date_ = mxGetField(extended_path_struct, 0, "shock_str_date_");
|
||||
if (shock_str_date_ == NULL)
|
||||
{
|
||||
string tmp = "shock_str_date_";
|
||||
tmp.insert(0,"The extended_path description structure does not contain the member: ");
|
||||
tmp.insert(0, "The extended_path description structure does not contain the member: ");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
int nb_constrained = mxGetM(constrained_vars_) * mxGetN(constrained_vars_);
|
||||
int nb_controlled = 0;
|
||||
mxArray* options_cond_fcst_ = mxGetField(extended_path_struct, 0, "options_cond_fcst_");
|
||||
mxArray* controlled_varexo = NULL;
|
||||
mxArray *options_cond_fcst_ = mxGetField(extended_path_struct, 0, "options_cond_fcst_");
|
||||
mxArray *controlled_varexo = NULL;
|
||||
if (options_cond_fcst_ != NULL)
|
||||
{
|
||||
controlled_varexo = mxGetField(options_cond_fcst_, 0, "controlled_varexo");
|
||||
|
@ -599,13 +591,13 @@ main(int nrhs, const char *prhs[])
|
|||
DYN_MEX_FUNC_ERR_MSG_TXT("The number of exogenized variables and the number of exogenous controlled variables should be equal.");
|
||||
}
|
||||
}
|
||||
double * controlled_varexo_value = NULL;
|
||||
double *controlled_varexo_value = NULL;
|
||||
if (controlled_varexo != NULL)
|
||||
controlled_varexo_value = mxGetPr(controlled_varexo);
|
||||
double * constrained_var_value = mxGetPr(constrained_vars_);
|
||||
double *constrained_var_value = mxGetPr(constrained_vars_);
|
||||
sconditional_extended_path.resize(nb_constrained);
|
||||
max_periods = 0;
|
||||
if ( nb_constrained)
|
||||
if (nb_constrained)
|
||||
{
|
||||
conditional_local.is_cond = false;
|
||||
conditional_local.var_exo = 0;
|
||||
|
@ -628,18 +620,18 @@ main(int nrhs, const char *prhs[])
|
|||
{
|
||||
sconditional_extended_path[i].exo_num = ceil(constrained_var_value[i]);
|
||||
sconditional_extended_path[i].var_num = ceil(controlled_varexo_value[i]);
|
||||
mxArray* Array_constrained_paths_ = mxGetCell(constrained_paths_, i);
|
||||
mxArray *Array_constrained_paths_ = mxGetCell(constrained_paths_, i);
|
||||
double *specific_constrained_paths_ = mxGetPr(Array_constrained_paths_);
|
||||
double *specific_constrained_int_date_ = mxGetPr(mxGetCell(constrained_int_date_, i));
|
||||
int nb_local_periods = mxGetM(Array_constrained_paths_) * mxGetN(Array_constrained_paths_);
|
||||
int* constrained_int_date = (int*)mxMalloc(nb_local_periods * sizeof(int));
|
||||
error_msg.test_mxMalloc(constrained_int_date, __LINE__, __FILE__, __func__, nb_local_periods * sizeof(int));
|
||||
int *constrained_int_date = (int *) mxMalloc(nb_local_periods * sizeof(int));
|
||||
error_msg.test_mxMalloc(constrained_int_date, __LINE__, __FILE__, __func__, nb_local_periods * sizeof(int));
|
||||
if (nb_periods < nb_local_periods)
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << nb_periods;
|
||||
string tmp = oss.str();
|
||||
tmp.insert(0,"The total number of simulation periods (");
|
||||
tmp.insert(0, "The total number of simulation periods (");
|
||||
tmp.append(") is lesser than the number of periods in the shock definitions (");
|
||||
oss << nb_local_periods;
|
||||
string tmp1 = oss.str();
|
||||
|
@ -653,27 +645,27 @@ main(int nrhs, const char *prhs[])
|
|||
sconditional_extended_path[i].value[j] = 0;
|
||||
for (int j = 0; j < nb_local_periods; j++)
|
||||
{
|
||||
constrained_int_date[j] = int(specific_constrained_int_date_[j]) - 1;
|
||||
constrained_int_date[j] = int (specific_constrained_int_date_[j]) - 1;
|
||||
conditional_local.is_cond = true;
|
||||
conditional_local.var_exo = sconditional_extended_path[i].var_num - 1;
|
||||
conditional_local.var_endo = sconditional_extended_path[i].exo_num - 1;
|
||||
conditional_local.constrained_value = specific_constrained_paths_[j];
|
||||
table_conditional_global[constrained_int_date[j]][sconditional_extended_path[i].exo_num - 1] = conditional_local;
|
||||
sconditional_extended_path[i].per_value[j] = make_pair(constrained_int_date[j], specific_constrained_paths_[j]);
|
||||
sconditional_extended_path[i].value[constrained_int_date[j]] = specific_constrained_paths_[j];
|
||||
sconditional_extended_path[i].value[constrained_int_date[j]] = specific_constrained_paths_[j];
|
||||
if (max_periods < constrained_int_date[j] + 1)
|
||||
max_periods = constrained_int_date[j] + 1;
|
||||
max_periods = constrained_int_date[j] + 1;
|
||||
}
|
||||
mxFree(constrained_int_date);
|
||||
}
|
||||
vector_table_conditional_local_type vv = table_conditional_global[0];
|
||||
double * shock_var_value = mxGetPr(shock_var_);
|
||||
double *shock_var_value = mxGetPr(shock_var_);
|
||||
int nb_shocks = mxGetM(shock_var_) * mxGetN(shock_var_);
|
||||
sextended_path.resize(nb_shocks);
|
||||
for (int i = 0; i < nb_shocks; i++)
|
||||
{
|
||||
sextended_path[i].exo_num = ceil(shock_var_value[i]);
|
||||
mxArray* Array_shock_paths_ = mxGetCell(shock_paths_, i);
|
||||
mxArray *Array_shock_paths_ = mxGetCell(shock_paths_, i);
|
||||
double *specific_shock_paths_ = mxGetPr(Array_shock_paths_);
|
||||
double *specific_shock_int_date_ = mxGetPr(mxGetCell(shock_int_date_, i));
|
||||
int nb_local_periods = mxGetM(Array_shock_paths_) * mxGetN(Array_shock_paths_);
|
||||
|
@ -682,7 +674,7 @@ main(int nrhs, const char *prhs[])
|
|||
ostringstream oss;
|
||||
oss << nb_periods;
|
||||
string tmp = oss.str();
|
||||
tmp.insert(0,"The total number of simulation periods (");
|
||||
tmp.insert(0, "The total number of simulation periods (");
|
||||
tmp.append(") is lesser than the number of periods in the shock definitions (");
|
||||
oss << nb_local_periods;
|
||||
string tmp1 = oss.str();
|
||||
|
@ -696,16 +688,16 @@ main(int nrhs, const char *prhs[])
|
|||
sextended_path[i].value[j] = 0;
|
||||
for (int j = 0; j < nb_local_periods; j++)
|
||||
{
|
||||
sextended_path[i].per_value[j] = make_pair(int(specific_shock_int_date_[j]), specific_shock_paths_[j]);
|
||||
sextended_path[i].value[int(specific_shock_int_date_[j]-1)] = specific_shock_paths_[j];
|
||||
if (max_periods < int(specific_shock_int_date_[j]) )
|
||||
max_periods = int(specific_shock_int_date_[j]);
|
||||
sextended_path[i].per_value[j] = make_pair(int (specific_shock_int_date_[j]), specific_shock_paths_[j]);
|
||||
sextended_path[i].value[int (specific_shock_int_date_[j]-1)] = specific_shock_paths_[j];
|
||||
if (max_periods < int (specific_shock_int_date_[j]))
|
||||
max_periods = int (specific_shock_int_date_[j]);
|
||||
}
|
||||
}
|
||||
for (int i=0; i < nb_periods; i++)
|
||||
for (int i = 0; i < nb_periods; i++)
|
||||
{
|
||||
int buflen = mxGetNumberOfElements(mxGetCell(date_str, i)) + 1;
|
||||
char* buf = (char*)mxCalloc(buflen, sizeof(char));
|
||||
char *buf = (char *) mxCalloc(buflen, sizeof(char));
|
||||
int info = mxGetString(mxGetCell(date_str, i), buf, buflen);
|
||||
if (info)
|
||||
{
|
||||
|
@ -715,14 +707,14 @@ main(int nrhs, const char *prhs[])
|
|||
dates.push_back(string(buf));//string(Dates[i]);
|
||||
mxFree(buf);
|
||||
}
|
||||
}
|
||||
if (plan.length()>0)
|
||||
}
|
||||
if (plan.length() > 0)
|
||||
{
|
||||
mxArray* plan_struct = mexGetVariable("base", plan.c_str());
|
||||
mxArray *plan_struct = mexGetVariable("base", plan.c_str());
|
||||
if (plan_struct == NULL)
|
||||
{
|
||||
string tmp = plan;
|
||||
tmp.insert(0,"Can't find the plan: ");
|
||||
tmp.insert(0, "Can't find the plan: ");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
size_t n_plan = mxGetN(plan_struct);
|
||||
|
@ -731,7 +723,7 @@ main(int nrhs, const char *prhs[])
|
|||
{
|
||||
splan[i].var = "";
|
||||
splan[i].exo = "";
|
||||
mxArray* tmp = mxGetField(plan_struct, i, "exo");
|
||||
mxArray *tmp = mxGetField(plan_struct, i, "exo");
|
||||
if (tmp)
|
||||
{
|
||||
char name [100];
|
||||
|
@ -744,7 +736,7 @@ main(int nrhs, const char *prhs[])
|
|||
else
|
||||
{
|
||||
string tmp = name;
|
||||
tmp.insert(0,"the variable '");
|
||||
tmp.insert(0, "the variable '");
|
||||
tmp.append("' defined as var in plan is not an exogenous or a deterministic exogenous\n");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
|
@ -762,7 +754,7 @@ main(int nrhs, const char *prhs[])
|
|||
else
|
||||
{
|
||||
string tmp = name;
|
||||
tmp.insert(0,"the variable '");
|
||||
tmp.insert(0, "the variable '");
|
||||
tmp.append("' defined as exo in plan is not an endogenous variable\n");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
|
@ -772,7 +764,7 @@ main(int nrhs, const char *prhs[])
|
|||
{
|
||||
size_t num_shocks = mxGetM(tmp);
|
||||
(splan[i]).per_value.resize(num_shocks);
|
||||
double * per_value = mxGetPr(tmp);
|
||||
double *per_value = mxGetPr(tmp);
|
||||
for (int j = 0; j < (int) num_shocks; j++)
|
||||
(splan[i]).per_value[j] = make_pair(ceil(per_value[j]), per_value[j + num_shocks]);
|
||||
}
|
||||
|
@ -788,19 +780,19 @@ main(int nrhs, const char *prhs[])
|
|||
mexPrintf(" plan shocks on var=%s for the following periods and with the following values:\n", it->var.c_str());
|
||||
for (vector<pair<int, double> >::iterator it1 = it->per_value.begin(); it1 != it->per_value.end(); it1++)
|
||||
{
|
||||
mexPrintf(" %3d %10.5f\n",it1->first, it1->second);
|
||||
mexPrintf(" %3d %10.5f\n", it1->first, it1->second);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (pfplan.length()>0)
|
||||
if (pfplan.length() > 0)
|
||||
{
|
||||
pfplan_struct = mexGetVariable("base", pfplan.c_str());
|
||||
if (!pfplan_struct)
|
||||
{
|
||||
string tmp = pfplan;
|
||||
tmp.insert(0,"Can't find the pfplan: ");
|
||||
tmp.insert(0, "Can't find the pfplan: ");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
size_t n_plan = mxGetN(pfplan_struct);
|
||||
|
@ -809,7 +801,7 @@ main(int nrhs, const char *prhs[])
|
|||
{
|
||||
spfplan[i].var = "";
|
||||
spfplan[i].exo = "";
|
||||
mxArray* tmp = mxGetField(pfplan_struct, i, "var");
|
||||
mxArray *tmp = mxGetField(pfplan_struct, i, "var");
|
||||
if (tmp)
|
||||
{
|
||||
char name [100];
|
||||
|
@ -822,7 +814,7 @@ main(int nrhs, const char *prhs[])
|
|||
else
|
||||
{
|
||||
string tmp = name;
|
||||
tmp.insert(0,"the variable '");
|
||||
tmp.insert(0, "the variable '");
|
||||
tmp.append("' defined as var in pfplan is not an exogenous or a deterministic exogenous\n");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
|
@ -840,7 +832,7 @@ main(int nrhs, const char *prhs[])
|
|||
else
|
||||
{
|
||||
string tmp = name;
|
||||
tmp.insert(0,"the variable '");
|
||||
tmp.insert(0, "the variable '");
|
||||
tmp.append("' defined as exo in pfplan is not an endogenous variable\n");
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str());
|
||||
}
|
||||
|
@ -849,7 +841,7 @@ main(int nrhs, const char *prhs[])
|
|||
if (tmp)
|
||||
{
|
||||
size_t num_shocks = mxGetM(tmp);
|
||||
double * per_value = mxGetPr(tmp);
|
||||
double *per_value = mxGetPr(tmp);
|
||||
(spfplan[i]).per_value.resize(num_shocks);
|
||||
for (int j = 0; j < (int) num_shocks; j++)
|
||||
spfplan[i].per_value[j] = make_pair(ceil(per_value[j]), per_value[j+ num_shocks]);
|
||||
|
@ -866,14 +858,12 @@ main(int nrhs, const char *prhs[])
|
|||
mexPrintf(" plan shocks on var=%s (%d) for the following periods and with the following values:\n", it->var.c_str(), it->var_num);
|
||||
for (vector<pair<int, double> >::iterator it1 = it->per_value.begin(); it1 != it->per_value.end(); it1++)
|
||||
{
|
||||
mexPrintf(" %3d %10.5f\n",it1->first, it1->second);
|
||||
mexPrintf(" %3d %10.5f\n", it1->first, it1->second);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int field_steady_state = mxGetFieldNumber(oo_, "steady_state");
|
||||
if (field_steady_state < 0)
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT("steady_state is not a field of oo_");
|
||||
|
@ -893,11 +883,11 @@ main(int nrhs, const char *prhs[])
|
|||
|
||||
if (!count_array_argument)
|
||||
{
|
||||
mxArray* endo_sim_arr = mxGetFieldByNumber(oo_, 0, field_endo_simul);
|
||||
mxArray *endo_sim_arr = mxGetFieldByNumber(oo_, 0, field_endo_simul);
|
||||
yd = mxGetPr(endo_sim_arr);
|
||||
row_y = mxGetM(endo_sim_arr);
|
||||
col_y = mxGetN(endo_sim_arr);
|
||||
mxArray* exo_sim_arr = mxGetFieldByNumber(oo_, 0, field_exo_simul);
|
||||
mxArray *exo_sim_arr = mxGetFieldByNumber(oo_, 0, field_exo_simul);
|
||||
xd = mxGetPr(exo_sim_arr);
|
||||
row_x = mxGetM(exo_sim_arr);
|
||||
col_x = mxGetN(exo_sim_arr);
|
||||
|
@ -928,9 +918,9 @@ main(int nrhs, const char *prhs[])
|
|||
DYN_MEX_FUNC_ERR_MSG_TXT("options_ is not a field of options_");
|
||||
}
|
||||
|
||||
if (!steady_yd )
|
||||
if (!steady_yd)
|
||||
{
|
||||
mxArray* steady_state_arr = mxGetFieldByNumber(oo_, 0, field_steady_state);
|
||||
mxArray *steady_state_arr = mxGetFieldByNumber(oo_, 0, field_steady_state);
|
||||
steady_yd = mxGetPr(steady_state_arr);
|
||||
steady_row_y = mxGetM(steady_state_arr);
|
||||
steady_col_y = mxGetN(steady_state_arr);
|
||||
|
@ -941,12 +931,12 @@ main(int nrhs, const char *prhs[])
|
|||
{
|
||||
if (!count_array_argument)
|
||||
{
|
||||
mxArray* steady_state_arr = mxGetFieldByNumber(oo_, 0, field_steady_state);
|
||||
mxArray *steady_state_arr = mxGetFieldByNumber(oo_, 0, field_steady_state);
|
||||
yd = mxGetPr(steady_state_arr);
|
||||
row_y = mxGetM(steady_state_arr);
|
||||
col_y = mxGetN(steady_state_arr);
|
||||
|
||||
mxArray* exo_steady_state_arr = mxGetFieldByNumber(oo_, 0, field_exo_steady_state);
|
||||
mxArray *exo_steady_state_arr = mxGetFieldByNumber(oo_, 0, field_exo_steady_state);
|
||||
xd = mxGetPr(exo_steady_state_arr);
|
||||
row_x = mxGetM(exo_steady_state_arr);
|
||||
col_x = mxGetN(exo_steady_state_arr);
|
||||
|
@ -956,7 +946,7 @@ main(int nrhs, const char *prhs[])
|
|||
int field = mxGetFieldNumber(options_, "verbosity");
|
||||
int verbose = 0;
|
||||
if (field >= 0)
|
||||
verbose = int(*mxGetPr((mxGetFieldByNumber(options_, 0, field))));
|
||||
verbose = int (*mxGetPr((mxGetFieldByNumber(options_, 0, field))));
|
||||
else
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT("verbosity is not a field of options_");
|
||||
if (verbose)
|
||||
|
@ -976,7 +966,7 @@ main(int nrhs, const char *prhs[])
|
|||
DYN_MEX_FUNC_ERR_MSG_TXT("steady is not a field of options_");
|
||||
}
|
||||
field = mxGetFieldNumber(temporaryfield, "maxit");
|
||||
if (field<0)
|
||||
if (field < 0)
|
||||
{
|
||||
if (!steady_state)
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT("maxit is not a field of options_.simul");
|
||||
|
@ -1027,7 +1017,7 @@ main(int nrhs, const char *prhs[])
|
|||
DYN_MEX_FUNC_ERR_MSG_TXT("dynatol is not a field of options_");
|
||||
field = mxGetFieldNumber(dynatol, "f");
|
||||
if (field >= 0)
|
||||
solve_tolf= *mxGetPr((mxGetFieldByNumber(dynatol, 0, field)));
|
||||
solve_tolf = *mxGetPr((mxGetFieldByNumber(dynatol, 0, field)));
|
||||
else
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT("f is not a field of options_.dynatol");
|
||||
}
|
||||
|
@ -1040,7 +1030,7 @@ main(int nrhs, const char *prhs[])
|
|||
size_t buflen = mxGetM(mxa) * mxGetN(mxa) + 1;
|
||||
char *fname;
|
||||
fname = (char *) mxCalloc(buflen+1, sizeof(char));
|
||||
size_t status = mxGetString(mxa, fname, int(buflen));
|
||||
size_t status = mxGetString(mxa, fname, int (buflen));
|
||||
fname[buflen] = ' ';
|
||||
if (status != 0)
|
||||
mexWarnMsgTxt("Not enough space. Filename is truncated.");
|
||||
|
@ -1059,7 +1049,7 @@ main(int nrhs, const char *prhs[])
|
|||
#else
|
||||
if (stack_solve_algo == 7 && !steady_state)
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT("bytecode has not been compiled with CUDA option. Bytecode Can't use options_.stack_solve_algo=7\n");
|
||||
#endif
|
||||
#endif
|
||||
size_t size_of_direction = col_y*row_y*sizeof(double);
|
||||
double *y = (double *) mxMalloc(size_of_direction);
|
||||
error_msg.test_mxMalloc(y, __LINE__, __FILE__, __func__, size_of_direction);
|
||||
|
@ -1067,8 +1057,8 @@ main(int nrhs, const char *prhs[])
|
|||
error_msg.test_mxMalloc(ya, __LINE__, __FILE__, __func__, size_of_direction);
|
||||
direction = (double *) mxMalloc(size_of_direction);
|
||||
error_msg.test_mxMalloc(direction, __LINE__, __FILE__, __func__, size_of_direction);
|
||||
memset(direction, 0, size_of_direction);
|
||||
/*mexPrintf("col_x : %d, row_x : %d\n",col_x, row_x);*/
|
||||
memset(direction, 0, size_of_direction);
|
||||
/*mexPrintf("col_x : %d, row_x : %d\n",col_x, row_x);*/
|
||||
double *x = (double *) mxMalloc(col_x*row_x*sizeof(double));
|
||||
error_msg.test_mxMalloc(x, __LINE__, __FILE__, __func__, col_x*row_x*sizeof(double));
|
||||
for (i = 0; i < row_x*col_x; i++)
|
||||
|
@ -1079,10 +1069,10 @@ main(int nrhs, const char *prhs[])
|
|||
{
|
||||
y[i] = double (yd[i]);
|
||||
ya[i] = double (yd[i]);
|
||||
}
|
||||
size_t y_size = row_y;
|
||||
size_t nb_row_x = row_x;
|
||||
|
||||
}
|
||||
size_t y_size = row_y;
|
||||
size_t nb_row_x = row_x;
|
||||
|
||||
clock_t t0 = clock();
|
||||
Interpreter interprete(params, y, ya, x, steady_yd, steady_xd, direction, y_size, nb_row_x, nb_row_xd, periods, y_kmin, y_kmax, maxit_, solve_tolf, size_of_direction, slowc, y_decal,
|
||||
markowitz_c, file_name, minimal_solving_periods, stack_solve_algo, solve_algo, global_temporary_terms, print, print_error, GlobalTemporaryTerms, steady_state,
|
||||
|
@ -1096,28 +1086,28 @@ main(int nrhs, const char *prhs[])
|
|||
int nb_blocks = 0;
|
||||
double *pind;
|
||||
bool no_error = true;
|
||||
|
||||
|
||||
if (extended_path)
|
||||
{
|
||||
try
|
||||
{
|
||||
interprete.extended_path(f, f, evaluate, block, nb_blocks, max_periods, sextended_path, sconditional_extended_path, dates, table_conditional_global);
|
||||
}
|
||||
catch (GeneralExceptionHandling &feh)
|
||||
{
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(feh.GetErrorMsg().c_str());
|
||||
}
|
||||
{
|
||||
try
|
||||
{
|
||||
interprete.extended_path(f, f, evaluate, block, nb_blocks, max_periods, sextended_path, sconditional_extended_path, dates, table_conditional_global);
|
||||
}
|
||||
catch (GeneralExceptionHandling &feh)
|
||||
{
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(feh.GetErrorMsg().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
interprete.compute_blocks(f, f, evaluate, block, nb_blocks);
|
||||
}
|
||||
catch (GeneralExceptionHandling &feh)
|
||||
{
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(feh.GetErrorMsg().c_str());
|
||||
}
|
||||
try
|
||||
{
|
||||
interprete.compute_blocks(f, f, evaluate, block, nb_blocks);
|
||||
}
|
||||
catch (GeneralExceptionHandling &feh)
|
||||
{
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(feh.GetErrorMsg().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CUDA
|
||||
|
@ -1145,7 +1135,7 @@ main(int nrhs, const char *prhs[])
|
|||
if (evaluate)
|
||||
{
|
||||
vector<double> residual = interprete.get_residual();
|
||||
plhs[1] = mxCreateDoubleMatrix(int(residual.size()/double(col_y)), int(col_y), mxREAL);
|
||||
plhs[1] = mxCreateDoubleMatrix(int (residual.size()/double (col_y)), int (col_y), mxREAL);
|
||||
pind = mxGetPr(plhs[1]);
|
||||
for (i = 0; i < residual.size(); i++)
|
||||
pind[i] = residual[i];
|
||||
|
@ -1157,20 +1147,20 @@ main(int nrhs, const char *prhs[])
|
|||
out_periods = max_periods + y_kmin;
|
||||
else
|
||||
out_periods = row_y;
|
||||
plhs[1] = mxCreateDoubleMatrix(out_periods, int(col_y), mxREAL);
|
||||
plhs[1] = mxCreateDoubleMatrix(out_periods, int (col_y), mxREAL);
|
||||
pind = mxGetPr(plhs[1]);
|
||||
for (i = 0; i < out_periods*col_y; i++)
|
||||
pind[i] = y[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
int out_periods;
|
||||
if (extended_path)
|
||||
out_periods = max_periods + y_kmin;
|
||||
else
|
||||
out_periods = col_y;
|
||||
plhs[1] = mxCreateDoubleMatrix(int(row_y), out_periods, mxREAL);
|
||||
plhs[1] = mxCreateDoubleMatrix(int (row_y), out_periods, mxREAL);
|
||||
pind = mxGetPr(plhs[1]);
|
||||
if (evaluate)
|
||||
{
|
||||
|
@ -1180,7 +1170,7 @@ main(int nrhs, const char *prhs[])
|
|||
}
|
||||
else
|
||||
for (i = 0; i < row_y*out_periods; i++)
|
||||
pind[i] = y[i];
|
||||
pind[i] = y[i];
|
||||
}
|
||||
if (nlhs > 2)
|
||||
{
|
||||
|
@ -1194,7 +1184,7 @@ main(int nrhs, const char *prhs[])
|
|||
jacob_exo_field_number = 1;
|
||||
jacob_exo_det_field_number = 2;
|
||||
jacob_other_endo_field_number = 3;
|
||||
mwSize dims[1] = {(mwSize)nb_blocks };
|
||||
mwSize dims[1] = {(mwSize) nb_blocks };
|
||||
plhs[2] = mxCreateStructArray(1, dims, 4, field_names);
|
||||
}
|
||||
else if (!mxIsStruct(block_structur))
|
||||
|
@ -1234,18 +1224,18 @@ main(int nrhs, const char *prhs[])
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plhs[2] = mxCreateDoubleMatrix(int(row_x), int(col_x), mxREAL);
|
||||
{
|
||||
plhs[2] = mxCreateDoubleMatrix(int (row_x), int (col_x), mxREAL);
|
||||
pind = mxGetPr(plhs[2]);
|
||||
for (i = 0; i < row_x*col_x; i++)
|
||||
{
|
||||
pind[i] = x[i];
|
||||
for (i = 0; i < row_x*col_x; i++)
|
||||
{
|
||||
pind[i] = x[i];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (nlhs > 3)
|
||||
{
|
||||
plhs[3] = mxCreateDoubleMatrix(int(row_y), int(col_y), mxREAL);
|
||||
plhs[3] = mxCreateDoubleMatrix(int (row_y), int (col_y), mxREAL);
|
||||
pind = mxGetPr(plhs[3]);
|
||||
for (i = 0; i < row_y*col_y; i++)
|
||||
pind[i] = y[i];
|
||||
|
@ -1253,7 +1243,7 @@ main(int nrhs, const char *prhs[])
|
|||
{
|
||||
mxArray *GlobalTemporaryTerms = interprete.get_Temporary_Terms();
|
||||
size_t nb_temp_terms = mxGetM(GlobalTemporaryTerms);
|
||||
plhs[4] = mxCreateDoubleMatrix(int(nb_temp_terms), 1, mxREAL);
|
||||
plhs[4] = mxCreateDoubleMatrix(int (nb_temp_terms), 1, mxREAL);
|
||||
pind = mxGetPr(plhs[4]);
|
||||
double *tt = mxGetPr(GlobalTemporaryTerms);
|
||||
for (i = 0; i < nb_temp_terms; i++)
|
||||
|
@ -1266,15 +1256,15 @@ main(int nrhs, const char *prhs[])
|
|||
}
|
||||
#else
|
||||
Free_global();
|
||||
#endif
|
||||
#endif
|
||||
if (x)
|
||||
mxFree(x);
|
||||
mxFree(x);
|
||||
if (y)
|
||||
mxFree(y);
|
||||
mxFree(y);
|
||||
if (ya)
|
||||
mxFree(ya);
|
||||
mxFree(ya);
|
||||
if (direction)
|
||||
mxFree(direction);
|
||||
mxFree(direction);
|
||||
#ifdef _MSC_VER_
|
||||
/*fFreeResult =*/ FreeLibrary(hinstLib);
|
||||
#endif
|
||||
|
|
|
@ -142,7 +142,7 @@ mxCreateStructArray(unsigned int rows, mwSize *cols, int nfields, const string &
|
|||
return mxCreateStructMatrix(rows, *cols, nfields, fieldnames);
|
||||
};
|
||||
mxArray *mxCreatNULLMatrix();
|
||||
void mexCallMATLAB(unsigned int n_lhs, mxArray* lhs[], unsigned int n_rhs, mxArray* rhs[], const char *function);
|
||||
void mexCallMATLAB(unsigned int n_lhs, mxArray *lhs[], unsigned int n_rhs, mxArray *rhs[], const char *function);
|
||||
void mxDestroyArray(mxArray *A_m);
|
||||
mxArray *read_struct(FILE *fid);
|
||||
mxArray *read_Array(FILE *fid);
|
||||
|
|
|
@ -28,60 +28,60 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* size of Info and Control arrays */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* size of Info and Control arrays */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* These might be larger in future versions, since there are only 3 unused
|
||||
* entries in Info, and no unused entries in Control. */
|
||||
/* These might be larger in future versions, since there are only 3 unused
|
||||
* entries in Info, and no unused entries in Control. */
|
||||
|
||||
#define UMFPACK_INFO 90
|
||||
#define UMFPACK_CONTROL 20
|
||||
/* used in all UMFPACK_report_* routines: */
|
||||
#define UMFPACK_PRL 0 /* print level */
|
||||
/* returned by all routines that use Info: */
|
||||
/* used in all UMFPACK_report_* routines: */
|
||||
#define UMFPACK_PRL 0 /* print level */
|
||||
/* returned by all routines that use Info: */
|
||||
#define UMFPACK_OK (0)
|
||||
#define UMFPACK_STATUS 0 /* UMFPACK_OK, or other result */
|
||||
#define UMFPACK_STATUS 0 /* UMFPACK_OK, or other result */
|
||||
|
||||
#ifdef _WIN64
|
||||
typedef long long int SuiteSparse_long;
|
||||
typedef long long int SuiteSparse_long;
|
||||
#else
|
||||
typedef long SuiteSparse_long;
|
||||
typedef long SuiteSparse_long;
|
||||
#endif
|
||||
|
||||
void umfpack_dl_defaults(double Control[UMFPACK_CONTROL]);
|
||||
void umfpack_dl_defaults(double Control[UMFPACK_CONTROL]);
|
||||
|
||||
SuiteSparse_long umfpack_dl_symbolic(SuiteSparse_long n_row, SuiteSparse_long n_col,
|
||||
const SuiteSparse_long Ap [ ], const SuiteSparse_long Ai [ ],
|
||||
const double Ax [ ], void **Symbolic,
|
||||
const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO]);
|
||||
SuiteSparse_long umfpack_dl_symbolic(SuiteSparse_long n_row, SuiteSparse_long n_col,
|
||||
const SuiteSparse_long Ap [], const SuiteSparse_long Ai [],
|
||||
const double Ax [], void **Symbolic,
|
||||
const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO]);
|
||||
|
||||
SuiteSparse_long umfpack_dl_numeric(const SuiteSparse_long Ap [ ], const SuiteSparse_long Ai [ ],
|
||||
const double Ax [ ], void *Symbolic, void **Numeric,
|
||||
SuiteSparse_long umfpack_dl_numeric(const SuiteSparse_long Ap [], const SuiteSparse_long Ai [],
|
||||
const double Ax [], void *Symbolic, void **Numeric,
|
||||
const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO]);
|
||||
|
||||
SuiteSparse_long umfpack_dl_solve(SuiteSparse_long sys, const SuiteSparse_long Ap [],
|
||||
const SuiteSparse_long Ai [], const double Ax [],
|
||||
double X [], const double B [], void *Numeric,
|
||||
const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO]);
|
||||
|
||||
SuiteSparse_long umfpack_dl_solve(SuiteSparse_long sys, const SuiteSparse_long Ap [ ],
|
||||
const SuiteSparse_long Ai [ ], const double Ax [ ],
|
||||
double X [ ], const double B [ ], void *Numeric,
|
||||
const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO]);
|
||||
void umfpack_dl_report_info(const double Control [UMFPACK_CONTROL],
|
||||
const double Info [UMFPACK_INFO]);
|
||||
|
||||
void umfpack_dl_report_info(const double Control [UMFPACK_CONTROL],
|
||||
const double Info [UMFPACK_INFO]);
|
||||
void umfpack_dl_report_status(const double Control [UMFPACK_CONTROL],
|
||||
SuiteSparse_long status);
|
||||
|
||||
void umfpack_dl_report_status(const double Control [UMFPACK_CONTROL],
|
||||
SuiteSparse_long status);
|
||||
void umfpack_dl_free_symbolic(void **Symbolic);
|
||||
|
||||
void umfpack_dl_free_symbolic(void **Symbolic);
|
||||
void umfpack_dl_free_numeric(void **Numeric);
|
||||
|
||||
void umfpack_dl_free_numeric(void **Numeric);
|
||||
SuiteSparse_long umfpack_dl_load_symbolic(void **Symbolic, char *filename);
|
||||
|
||||
SuiteSparse_long umfpack_dl_load_symbolic (void **Symbolic, char *filename) ;
|
||||
SuiteSparse_long umfpack_dl_load_numeric(void **Numeric, char *filename);
|
||||
|
||||
SuiteSparse_long umfpack_dl_load_numeric (void **Numeric, char *filename) ;
|
||||
SuiteSparse_long umfpack_dl_save_symbolic(void *Symbolic, char *filename);
|
||||
|
||||
SuiteSparse_long umfpack_dl_save_symbolic (void *Symbolic, char *filename) ;
|
||||
|
||||
SuiteSparse_long umfpack_dl_save_numeric (void *Numeric, char *filename) ;
|
||||
SuiteSparse_long umfpack_dl_save_numeric(void *Numeric, char *filename);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
@ -213,4 +213,3 @@ operator<<(std::ostream &out, const DecisionRules::BlanchardKahnException &e)
|
|||
out << "The Blanchard Kahn rank condition is not satisfied";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,9 @@ public:
|
|||
//! True if the model fails the order condition. False if it fails the rank condition.
|
||||
const bool order;
|
||||
const int n_fwrd_vars, n_explosive_eigenvals;
|
||||
BlanchardKahnException(bool order_arg, int n_fwrd_vars_arg, int n_explosive_eigenvals_arg) : order(order_arg), n_fwrd_vars(n_fwrd_vars_arg), n_explosive_eigenvals(n_explosive_eigenvals_arg) {};
|
||||
BlanchardKahnException(bool order_arg, int n_fwrd_vars_arg, int n_explosive_eigenvals_arg) : order(order_arg), n_fwrd_vars(n_fwrd_vars_arg), n_explosive_eigenvals(n_explosive_eigenvals_arg)
|
||||
{
|
||||
};
|
||||
};
|
||||
/*!
|
||||
The zetas are supposed to follow C convention (first vector index is zero).
|
||||
|
@ -57,7 +59,9 @@ public:
|
|||
DecisionRules(size_t n_arg, size_t p_arg, const std::vector<size_t> &zeta_fwrd_arg,
|
||||
const std::vector<size_t> &zeta_back_arg, const std::vector<size_t> &zeta_mixed_arg,
|
||||
const std::vector<size_t> &zeta_static_arg, double qz_criterium);
|
||||
virtual ~DecisionRules(){};
|
||||
virtual ~DecisionRules()
|
||||
{
|
||||
};
|
||||
|
||||
/*!
|
||||
\param jacobian First columns are backetermined vars at t-1 (in the order of zeta_back_mixed), then all vars at t (in the orig order), then forward vars at t+1 (in the order of zeta_fwrd_mixed), then exogenous vars.
|
||||
|
|
|
@ -44,4 +44,3 @@ DetrendData::detrend(const VectorView &SteadyState, const MatrixConstView &dataV
|
|||
detrendedDataView(i, j) = dataView(i, j) - SteadyState(varobs[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -31,7 +31,9 @@ class DetrendData
|
|||
{
|
||||
|
||||
public:
|
||||
virtual ~DetrendData(){};
|
||||
virtual ~DetrendData()
|
||||
{
|
||||
};
|
||||
DetrendData(const std::vector<size_t> &varobs_arg, bool noconstant_arg);
|
||||
void detrend(const VectorView &SteadyState, const MatrixConstView &dataView, MatrixView &detrendedDataView);
|
||||
|
||||
|
|
|
@ -37,4 +37,3 @@ EstimatedParameter::EstimatedParameter(const EstimatedParameter::pType type_arg,
|
|||
EstimatedParameter::~EstimatedParameter()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -33,19 +33,20 @@ struct EstimatedParameter
|
|||
public:
|
||||
// parameter types
|
||||
enum pType
|
||||
{
|
||||
shock_SD = 1, // standard deviation of a structural shock
|
||||
measureErr_SD = 2, // standard deviation of a measurement error
|
||||
shock_Corr = 3, // correlation betwwen two structural shocks
|
||||
measureErr_Corr = 4, // correlation between two measurement errors
|
||||
deepPar = 5 // deep parameter
|
||||
};
|
||||
{
|
||||
shock_SD = 1, // standard deviation of a structural shock
|
||||
measureErr_SD = 2, // standard deviation of a measurement error
|
||||
shock_Corr = 3, // correlation betwwen two structural shocks
|
||||
measureErr_Corr = 4, // correlation between two measurement errors
|
||||
deepPar = 5 // deep parameter
|
||||
};
|
||||
|
||||
EstimatedParameter(const EstimatedParameter::pType type,
|
||||
size_t ID1, size_t ID2, const std::vector<size_t> &subSampleIDs,
|
||||
double lower_bound, double upper_bound, Prior *prior
|
||||
);
|
||||
virtual ~EstimatedParameter();
|
||||
virtual
|
||||
~EstimatedParameter();
|
||||
|
||||
enum pType ptype;
|
||||
size_t ID1;
|
||||
|
|
|
@ -45,7 +45,8 @@
|
|||
class EstimatedParametersDescription
|
||||
{
|
||||
public:
|
||||
virtual ~EstimatedParametersDescription();
|
||||
virtual
|
||||
~EstimatedParametersDescription();
|
||||
EstimatedParametersDescription(std::vector<EstimationSubsample> &estSubsamples, std::vector<EstimatedParameter> &estParams);
|
||||
std::vector<EstimationSubsample> estSubsamples;
|
||||
std::vector<EstimatedParameter> estParams;
|
||||
|
|
|
@ -33,4 +33,3 @@ EstimationSubsample::EstimationSubsample(size_t INstartPeriod, size_t INendPerio
|
|||
EstimationSubsample::~EstimationSubsample()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,8 @@ class EstimationSubsample
|
|||
{
|
||||
public:
|
||||
EstimationSubsample(size_t startPeriod, size_t endPeriod);
|
||||
virtual ~EstimationSubsample();
|
||||
virtual
|
||||
~EstimationSubsample();
|
||||
|
||||
size_t startPeriod;
|
||||
size_t endPeriod;
|
||||
|
|
|
@ -74,4 +74,3 @@ InitializeKalmanFilter::setPstar(Matrix &Pstar, Matrix &Pinf, const Matrix &T, c
|
|||
|
||||
Pinf.setAll(0.0);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,13 +49,15 @@ public:
|
|||
const std::vector<size_t> &varobs_arg,
|
||||
double qz_criterium_arg, double lyapunov_tol_arg,
|
||||
bool noconstant_arg);
|
||||
virtual ~InitializeKalmanFilter();
|
||||
virtual
|
||||
~InitializeKalmanFilter();
|
||||
// initialise parameter dependent KF matrices only but not Ps
|
||||
template <class Vec1, class Vec2, class Mat1, class Mat2>
|
||||
void initialize(Vec1 &steadyState, const Vec2 &deepParams, Mat1 &R,
|
||||
const Mat2 &Q, Matrix &RQRt, Matrix &T,
|
||||
const MatrixConstView &dataView,
|
||||
MatrixView &detrendedDataView)
|
||||
void
|
||||
initialize(Vec1 &steadyState, const Vec2 &deepParams, Mat1 &R,
|
||||
const Mat2 &Q, Matrix &RQRt, Matrix &T,
|
||||
const MatrixConstView &dataView,
|
||||
MatrixView &detrendedDataView)
|
||||
{
|
||||
modelSolution.compute(steadyState, deepParams, g_x, g_u);
|
||||
detrendData.detrend(steadyState, dataView, detrendedDataView);
|
||||
|
@ -66,10 +68,11 @@ public:
|
|||
|
||||
// initialise all KF matrices
|
||||
template <class Vec1, class Vec2, class Mat1, class Mat2>
|
||||
void initialize(Vec1 &steadyState, const Vec2 &deepParams, Mat1 &R,
|
||||
const Mat2 &Q, Matrix &RQRt, Matrix &T, Matrix &Pstar, Matrix &Pinf,
|
||||
const MatrixConstView &dataView,
|
||||
MatrixView &detrendedDataView)
|
||||
void
|
||||
initialize(Vec1 &steadyState, const Vec2 &deepParams, Mat1 &R,
|
||||
const Mat2 &Q, Matrix &RQRt, Matrix &T, Matrix &Pstar, Matrix &Pinf,
|
||||
const MatrixConstView &dataView,
|
||||
MatrixView &detrendedDataView)
|
||||
{
|
||||
initialize(steadyState, deepParams, R, Q, RQRt, T, dataView, detrendedDataView);
|
||||
setPstar(Pstar, Pinf, T, RQRt);
|
||||
|
@ -90,7 +93,8 @@ private:
|
|||
void setT(Matrix &T);
|
||||
|
||||
template <class Mat1, class Mat2>
|
||||
void setRQR(Mat1 &R, const Mat2 &Q, Matrix &RQRt)
|
||||
void
|
||||
setRQR(Mat1 &R, const Mat2 &Q, Matrix &RQRt)
|
||||
{
|
||||
mat::assignByVectors(R, mat::nullVec, mat::nullVec, g_u, zeta_varobs_back_mixed, mat::nullVec);
|
||||
|
||||
|
|
|
@ -74,7 +74,6 @@ KalmanFilter::compute_zeta_varobs_back_mixed(const std::vector<size_t> &zeta_bac
|
|||
return zeta_varobs_back_mixed;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Multi-variate standard Kalman Filter
|
||||
*/
|
||||
|
@ -86,7 +85,7 @@ KalmanFilter::filter(const MatrixView &detrendedDataView, const Matrix &H, Vect
|
|||
bool nonstationary = true;
|
||||
a_init.setAll(0.0);
|
||||
int info;
|
||||
|
||||
|
||||
for (size_t t = 0; t < detrendedDataView.getCols(); ++t)
|
||||
{
|
||||
if (nonstationary)
|
||||
|
@ -192,4 +191,3 @@ KalmanFilter::filter(const MatrixView &detrendedDataView, const Matrix &H, Vect
|
|||
|
||||
return loglik;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,8 @@ class KalmanFilter
|
|||
{
|
||||
|
||||
public:
|
||||
virtual ~KalmanFilter();
|
||||
virtual
|
||||
~KalmanFilter();
|
||||
KalmanFilter(const std::string &basename, size_t n_endo, size_t n_exo, const std::vector<size_t> &zeta_fwrd_arg,
|
||||
const std::vector<size_t> &zeta_back_arg, const std::vector<size_t> &zeta_mixed_arg, const std::vector<size_t> &zeta_static_arg,
|
||||
double qz_criterium_arg, const std::vector<size_t> &varobs_arg,
|
||||
|
@ -56,18 +57,19 @@ public:
|
|||
bool noconstant_arg);
|
||||
|
||||
template <class Vec1, class Vec2, class Mat1>
|
||||
double compute(const MatrixConstView &dataView, Vec1 &steadyState,
|
||||
const Mat1 &Q, const Matrix &H, const Vec2 &deepParams,
|
||||
VectorView &vll, MatrixView &detrendedDataView, size_t start, size_t period)
|
||||
double
|
||||
compute(const MatrixConstView &dataView, Vec1 &steadyState,
|
||||
const Mat1 &Q, const Matrix &H, const Vec2 &deepParams,
|
||||
VectorView &vll, MatrixView &detrendedDataView, size_t start, size_t period)
|
||||
{
|
||||
if (period == 0) // initialise all KF matrices
|
||||
initKalmanFilter.initialize(steadyState, deepParams, R, Q, RQRt, T, Pstar, Pinf,
|
||||
dataView, detrendedDataView);
|
||||
else // initialise parameter dependent KF matrices only but not Ps
|
||||
initKalmanFilter.initialize(steadyState, deepParams, R, Q, RQRt, T,
|
||||
dataView, detrendedDataView);
|
||||
if (period == 0) // initialise all KF matrices
|
||||
initKalmanFilter.initialize(steadyState, deepParams, R, Q, RQRt, T, Pstar, Pinf,
|
||||
dataView, detrendedDataView);
|
||||
else // initialise parameter dependent KF matrices only but not Ps
|
||||
initKalmanFilter.initialize(steadyState, deepParams, R, Q, RQRt, T,
|
||||
dataView, detrendedDataView);
|
||||
|
||||
return filter(detrendedDataView, H, vll, start);
|
||||
return filter(detrendedDataView, H, vll, start);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -31,11 +31,11 @@ LogLikelihoodMain::LogLikelihoodMain(const std::string &basename, EstimatedParam
|
|||
const std::vector<size_t> &varobs, double riccati_tol, double lyapunov_tol,
|
||||
bool noconstant_arg)
|
||||
|
||||
: estSubsamples(estiParDesc.estSubsamples),
|
||||
logLikelihoodSubSample(basename, estiParDesc, n_endo, n_exo, zeta_fwrd_arg, zeta_back_arg, zeta_mixed_arg, zeta_static_arg, qz_criterium,
|
||||
varobs, riccati_tol, lyapunov_tol, noconstant_arg),
|
||||
vll(estiParDesc.getNumberOfPeriods()), // time dimension size of data
|
||||
detrendedData(varobs.size(), estiParDesc.getNumberOfPeriods())
|
||||
: estSubsamples(estiParDesc.estSubsamples),
|
||||
logLikelihoodSubSample(basename, estiParDesc, n_endo, n_exo, zeta_fwrd_arg, zeta_back_arg, zeta_mixed_arg, zeta_static_arg, qz_criterium,
|
||||
varobs, riccati_tol, lyapunov_tol, noconstant_arg),
|
||||
vll(estiParDesc.getNumberOfPeriods()), // time dimension size of data
|
||||
detrendedData(varobs.size(), estiParDesc.getNumberOfPeriods())
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -44,5 +44,3 @@ LogLikelihoodMain::~LogLikelihoodMain()
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -36,7 +36,8 @@ private:
|
|||
Matrix detrendedData;
|
||||
|
||||
public:
|
||||
virtual ~LogLikelihoodMain();
|
||||
virtual
|
||||
~LogLikelihoodMain();
|
||||
LogLikelihoodMain(const std::string &basename, EstimatedParametersDescription &estiParDesc, size_t n_endo, size_t n_exo,
|
||||
const std::vector<size_t> &zeta_fwrd_arg, const std::vector<size_t> &zeta_back_arg, const std::vector<size_t> &zeta_mixed_arg,
|
||||
const std::vector<size_t> &zeta_static_arg, const double qz_criterium_arg, const std::vector<size_t> &varobs_arg,
|
||||
|
@ -53,25 +54,30 @@ public:
|
|||
*/
|
||||
|
||||
template <class VEC1, class VEC2>
|
||||
double compute(VEC1 &steadyState, VEC2 &estParams, VectorView &deepParams, const MatrixConstView &data,
|
||||
MatrixView &Q, Matrix &H, size_t start)
|
||||
double
|
||||
compute(VEC1 &steadyState, VEC2 &estParams, VectorView &deepParams, const MatrixConstView &data,
|
||||
MatrixView &Q, Matrix &H, size_t start)
|
||||
{
|
||||
double logLikelihood = 0;
|
||||
for (size_t i = 0; i < estSubsamples.size(); ++i)
|
||||
{
|
||||
MatrixConstView dataView(data, 0, estSubsamples[i].startPeriod,
|
||||
data.getRows(), estSubsamples[i].endPeriod-estSubsamples[i].startPeriod+1);
|
||||
MatrixView detrendedDataView(detrendedData, 0, estSubsamples[i].startPeriod,
|
||||
data.getRows(), estSubsamples[i].endPeriod-estSubsamples[i].startPeriod+1);
|
||||
MatrixConstView dataView(data, 0, estSubsamples[i].startPeriod,
|
||||
data.getRows(), estSubsamples[i].endPeriod-estSubsamples[i].startPeriod+1);
|
||||
MatrixView detrendedDataView(detrendedData, 0, estSubsamples[i].startPeriod,
|
||||
data.getRows(), estSubsamples[i].endPeriod-estSubsamples[i].startPeriod+1);
|
||||
|
||||
VectorView vllView(vll, estSubsamples[i].startPeriod, estSubsamples[i].endPeriod-estSubsamples[i].startPeriod+1);
|
||||
logLikelihood += logLikelihoodSubSample.compute(steadyState, dataView, estParams, deepParams,
|
||||
Q, H, vllView, detrendedDataView, start, i);
|
||||
VectorView vllView(vll, estSubsamples[i].startPeriod, estSubsamples[i].endPeriod-estSubsamples[i].startPeriod+1);
|
||||
logLikelihood += logLikelihoodSubSample.compute(steadyState, dataView, estParams, deepParams,
|
||||
Q, H, vllView, detrendedDataView, start, i);
|
||||
}
|
||||
return logLikelihood;
|
||||
};
|
||||
|
||||
Vector &getVll() { return vll; };
|
||||
Vector &
|
||||
getVll()
|
||||
{
|
||||
return vll;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // !defined(E126AEF5_AC28_400a_821A_3BCFD1BC4C22__INCLUDED_)
|
||||
|
|
|
@ -38,4 +38,3 @@ LogLikelihoodSubSample::LogLikelihoodSubSample(const std::string &basename, Esti
|
|||
varobs, riccati_tol, lyapunov_tol, noconstant_arg), eigQ(n_exo), eigH(varobs.size())
|
||||
{
|
||||
};
|
||||
|
||||
|
|
|
@ -42,15 +42,17 @@ public:
|
|||
const std::vector<size_t> &varobs_arg, double riccati_tol_in, double lyapunov_tol, bool noconstant_arg);
|
||||
|
||||
template <class VEC1, class VEC2>
|
||||
double compute(VEC1 &steadyState, const MatrixConstView &dataView, VEC2 &estParams, VectorView &deepParams,
|
||||
MatrixView &Q, Matrix &H, VectorView &vll, MatrixView &detrendedDataView, size_t start, size_t period)
|
||||
double
|
||||
compute(VEC1 &steadyState, const MatrixConstView &dataView, VEC2 &estParams, VectorView &deepParams,
|
||||
MatrixView &Q, Matrix &H, VectorView &vll, MatrixView &detrendedDataView, size_t start, size_t period)
|
||||
{
|
||||
updateParams(estParams, deepParams, Q, H, period);
|
||||
|
||||
return kalmanFilter.compute(dataView, steadyState, Q, H, deepParams, vll, detrendedDataView, start, period);
|
||||
}
|
||||
|
||||
virtual ~LogLikelihoodSubSample();
|
||||
virtual
|
||||
~LogLikelihoodSubSample();
|
||||
|
||||
class UpdateParamsException
|
||||
{
|
||||
|
@ -69,8 +71,9 @@ private:
|
|||
|
||||
// methods
|
||||
template <class VEC>
|
||||
void updateParams(VEC &estParams, VectorView &deepParams,
|
||||
MatrixView &Q, Matrix &H, size_t period)
|
||||
void
|
||||
updateParams(VEC &estParams, VectorView &deepParams,
|
||||
MatrixView &Q, Matrix &H, size_t period)
|
||||
{
|
||||
size_t i, k, k1, k2;
|
||||
int test;
|
||||
|
@ -79,97 +82,96 @@ private:
|
|||
|
||||
for (i = 0; i < estParams.getSize(); ++i)
|
||||
{
|
||||
found = false;
|
||||
it = find(estiParDesc.estParams[i].subSampleIDs.begin(),
|
||||
estiParDesc.estParams[i].subSampleIDs.end(), period);
|
||||
if (it != estiParDesc.estParams[i].subSampleIDs.end())
|
||||
found = true;
|
||||
if (found)
|
||||
{
|
||||
switch (estiParDesc.estParams[i].ptype)
|
||||
{
|
||||
case EstimatedParameter::shock_SD:
|
||||
k = estiParDesc.estParams[i].ID1;
|
||||
Q(k, k) = estParams(i)*estParams(i);
|
||||
break;
|
||||
found = false;
|
||||
it = find(estiParDesc.estParams[i].subSampleIDs.begin(),
|
||||
estiParDesc.estParams[i].subSampleIDs.end(), period);
|
||||
if (it != estiParDesc.estParams[i].subSampleIDs.end())
|
||||
found = true;
|
||||
if (found)
|
||||
{
|
||||
switch (estiParDesc.estParams[i].ptype)
|
||||
{
|
||||
case EstimatedParameter::shock_SD:
|
||||
k = estiParDesc.estParams[i].ID1;
|
||||
Q(k, k) = estParams(i)*estParams(i);
|
||||
break;
|
||||
|
||||
case EstimatedParameter::measureErr_SD:
|
||||
k = estiParDesc.estParams[i].ID1;
|
||||
H(k, k) = estParams(i)*estParams(i);
|
||||
break;
|
||||
case EstimatedParameter::measureErr_SD:
|
||||
k = estiParDesc.estParams[i].ID1;
|
||||
H(k, k) = estParams(i)*estParams(i);
|
||||
break;
|
||||
|
||||
case EstimatedParameter::shock_Corr:
|
||||
k1 = estiParDesc.estParams[i].ID1;
|
||||
k2 = estiParDesc.estParams[i].ID2;
|
||||
Q(k1, k2) = estParams(i)*sqrt(Q(k1, k1)*Q(k2, k2));
|
||||
Q(k2, k1) = Q(k1, k2);
|
||||
// [CholQ,testQ] = chol(Q);
|
||||
test = lapack::choleskyDecomp(Q, "L");
|
||||
case EstimatedParameter::shock_Corr:
|
||||
k1 = estiParDesc.estParams[i].ID1;
|
||||
k2 = estiParDesc.estParams[i].ID2;
|
||||
Q(k1, k2) = estParams(i)*sqrt(Q(k1, k1)*Q(k2, k2));
|
||||
Q(k2, k1) = Q(k1, k2);
|
||||
// [CholQ,testQ] = chol(Q);
|
||||
test = lapack::choleskyDecomp(Q, "L");
|
||||
assert(test >= 0);
|
||||
|
||||
if (test > 0)
|
||||
{
|
||||
// The variance-covariance matrix of the structural innovations is not definite positive.
|
||||
// We have to compute the eigenvalues of this matrix in order to build the penalty.
|
||||
double delta = 0;
|
||||
eigQ.calculate(Q); // get eigenvalues
|
||||
//k = find(a < 0);
|
||||
if (eigQ.hasConverged())
|
||||
{
|
||||
const Vector &evQ = eigQ.getD();
|
||||
for (i = 0; i < evQ.getSize(); ++i)
|
||||
if (evQ(i) < 0)
|
||||
delta -= evQ(i);
|
||||
}
|
||||
|
||||
throw UpdateParamsException(delta);
|
||||
} // if
|
||||
break;
|
||||
if (test > 0)
|
||||
{
|
||||
// The variance-covariance matrix of the structural innovations is not definite positive.
|
||||
// We have to compute the eigenvalues of this matrix in order to build the penalty.
|
||||
double delta = 0;
|
||||
eigQ.calculate(Q); // get eigenvalues
|
||||
//k = find(a < 0);
|
||||
if (eigQ.hasConverged())
|
||||
{
|
||||
const Vector &evQ = eigQ.getD();
|
||||
for (i = 0; i < evQ.getSize(); ++i)
|
||||
if (evQ(i) < 0)
|
||||
delta -= evQ(i);
|
||||
}
|
||||
|
||||
case EstimatedParameter::measureErr_Corr:
|
||||
k1 = estiParDesc.estParams[i].ID1;
|
||||
k2 = estiParDesc.estParams[i].ID2;
|
||||
// H(k1,k2) = xparam1(i)*sqrt(H(k1,k1)*H(k2,k2));
|
||||
// H(k2,k1) = H(k1,k2);
|
||||
H(k1, k2) = estParams(i)*sqrt(H(k1, k1)*H(k2, k2));
|
||||
H(k2, k1) = H(k1, k2);
|
||||
throw UpdateParamsException(delta);
|
||||
} // if
|
||||
break;
|
||||
|
||||
//[CholH,testH] = chol(H);
|
||||
test = lapack::choleskyDecomp(H, "L");
|
||||
assert(test >= 0);
|
||||
case EstimatedParameter::measureErr_Corr:
|
||||
k1 = estiParDesc.estParams[i].ID1;
|
||||
k2 = estiParDesc.estParams[i].ID2;
|
||||
// H(k1,k2) = xparam1(i)*sqrt(H(k1,k1)*H(k2,k2));
|
||||
// H(k2,k1) = H(k1,k2);
|
||||
H(k1, k2) = estParams(i)*sqrt(H(k1, k1)*H(k2, k2));
|
||||
H(k2, k1) = H(k1, k2);
|
||||
|
||||
if (test > 0)
|
||||
{
|
||||
// The variance-covariance matrix of the measurement errors is not definite positive.
|
||||
// We have to compute the eigenvalues of this matrix in order to build the penalty.
|
||||
//a = diag(eig(H));
|
||||
double delta = 0;
|
||||
eigH.calculate(H); // get eigenvalues
|
||||
//k = find(a < 0);
|
||||
if (eigH.hasConverged())
|
||||
{
|
||||
const Vector &evH = eigH.getD();
|
||||
for (i = 0; i < evH.getSize(); ++i)
|
||||
if (evH(i) < 0)
|
||||
delta -= evH(i);
|
||||
}
|
||||
throw UpdateParamsException(delta);
|
||||
} // end if
|
||||
break;
|
||||
//[CholH,testH] = chol(H);
|
||||
test = lapack::choleskyDecomp(H, "L");
|
||||
assert(test >= 0);
|
||||
|
||||
//if estim_params_.np > 0 // i.e. num of deep parameters >0
|
||||
case EstimatedParameter::deepPar:
|
||||
k = estiParDesc.estParams[i].ID1;
|
||||
deepParams(k) = estParams(i);
|
||||
break;
|
||||
default:
|
||||
if (test > 0)
|
||||
{
|
||||
// The variance-covariance matrix of the measurement errors is not definite positive.
|
||||
// We have to compute the eigenvalues of this matrix in order to build the penalty.
|
||||
//a = diag(eig(H));
|
||||
double delta = 0;
|
||||
eigH.calculate(H); // get eigenvalues
|
||||
//k = find(a < 0);
|
||||
if (eigH.hasConverged())
|
||||
{
|
||||
const Vector &evH = eigH.getD();
|
||||
for (i = 0; i < evH.getSize(); ++i)
|
||||
if (evH(i) < 0)
|
||||
delta -= evH(i);
|
||||
}
|
||||
throw UpdateParamsException(delta);
|
||||
} // end if
|
||||
break;
|
||||
|
||||
//if estim_params_.np > 0 // i.e. num of deep parameters >0
|
||||
case EstimatedParameter::deepPar:
|
||||
k = estiParDesc.estParams[i].ID1;
|
||||
deepParams(k) = estParams(i);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
} // end switch
|
||||
} // end found
|
||||
} // end switch
|
||||
} // end found
|
||||
} //end for
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // !defined(DF8B7AF5_8169_4587_9037_2CD2C82E2DDF__INCLUDED_)
|
||||
|
|
|
@ -41,7 +41,6 @@ LogPosteriorDensity::LogPosteriorDensity(const std::string &modName, EstimatedPa
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* vector of log likelihoods for each Kalman step
|
||||
*/
|
||||
|
@ -50,4 +49,3 @@ LogPosteriorDensity::getLikVector()
|
|||
{
|
||||
return logLikelihoodMain.getVll();
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,8 @@ private:
|
|||
LogLikelihoodMain logLikelihoodMain;
|
||||
|
||||
public:
|
||||
virtual ~LogPosteriorDensity();
|
||||
virtual
|
||||
~LogPosteriorDensity();
|
||||
|
||||
LogPosteriorDensity(const std::string &modName, EstimatedParametersDescription &estParamsDesc, size_t n_endo, size_t n_exo,
|
||||
const std::vector<size_t> &zeta_fwrd_arg, const std::vector<size_t> &zeta_back_arg, const std::vector<size_t> &zeta_mixed_arg,
|
||||
|
|
|
@ -35,18 +35,20 @@ class LogPriorDensity
|
|||
|
||||
public:
|
||||
LogPriorDensity(EstimatedParametersDescription &estParsDesc);
|
||||
virtual ~LogPriorDensity();
|
||||
virtual
|
||||
~LogPriorDensity();
|
||||
|
||||
template<class VEC>
|
||||
double compute(VEC &ep)
|
||||
double
|
||||
compute(VEC &ep)
|
||||
{
|
||||
assert(estParsDesc.estParams.size() == ep.getSize());
|
||||
double logPriorDensity = 0;
|
||||
for (size_t i = 0; i < ep.getSize(); ++i)
|
||||
{
|
||||
logPriorDensity += log(((*(estParsDesc.estParams[i]).prior)).pdf(ep(i)));
|
||||
if (std::isinf(fabs(logPriorDensity)))
|
||||
return logPriorDensity;
|
||||
logPriorDensity += log(((*(estParsDesc.estParams[i]).prior)).pdf(ep(i)));
|
||||
if (std::isinf(fabs(logPriorDensity)))
|
||||
return logPriorDensity;
|
||||
}
|
||||
return logPriorDensity;
|
||||
};
|
||||
|
|
|
@ -51,5 +51,3 @@ ModelSolution::ModelSolution(const std::string &basename, size_t n_endo_arg, si
|
|||
zeta_mixed_arg.begin(), zeta_mixed_arg.end(),
|
||||
back_inserter(zeta_back_mixed));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -42,9 +42,12 @@ public:
|
|||
ModelSolution(const std::string &basename, size_t n_endo, size_t n_exo, const std::vector<size_t> &zeta_fwrd_arg,
|
||||
const std::vector<size_t> &zeta_back_arg, const std::vector<size_t> &zeta_mixed_arg,
|
||||
const std::vector<size_t> &zeta_static_arg, double qz_criterium);
|
||||
virtual ~ModelSolution() {};
|
||||
virtual ~ModelSolution()
|
||||
{
|
||||
};
|
||||
template <class Vec1, class Vec2, class Mat1, class Mat2>
|
||||
void compute(Vec1 &steadyState, const Vec2 &deepParams, Mat1 &ghx, Mat2 &ghu) throw (DecisionRules::BlanchardKahnException, GeneralizedSchurDecomposition::GSDException, SteadyStateSolver::SteadyStateException)
|
||||
void
|
||||
compute(Vec1 &steadyState, const Vec2 &deepParams, Mat1 &ghx, Mat2 &ghu) throw (DecisionRules::BlanchardKahnException, GeneralizedSchurDecomposition::GSDException, SteadyStateSolver::SteadyStateException)
|
||||
{
|
||||
// compute Steady State
|
||||
steadyStateSolver.compute(steadyState, Mx, deepParams);
|
||||
|
@ -69,8 +72,9 @@ private:
|
|||
Vector llXsteadyState;
|
||||
//Matrix jacobian;
|
||||
template <class Vec1, class Vec2, class Mat1, class Mat2>
|
||||
void ComputeModelSolution(Vec1 &steadyState, const Vec2 &deepParams,
|
||||
Mat1 &ghx, Mat2 &ghu)
|
||||
void
|
||||
ComputeModelSolution(Vec1 &steadyState, const Vec2 &deepParams,
|
||||
Mat1 &ghx, Mat2 &ghu)
|
||||
throw (DecisionRules::BlanchardKahnException, GeneralizedSchurDecomposition::GSDException)
|
||||
{
|
||||
// set extended Steady State
|
||||
|
|
|
@ -47,17 +47,18 @@ struct Prior
|
|||
public:
|
||||
//! probablity density functions
|
||||
enum pShape
|
||||
{
|
||||
Beta = 1,
|
||||
Gamma = 2,
|
||||
Gaussian = 3, // i.e. Normal density
|
||||
Inv_gamma_1 = 4, // Inverse gamma (type 1) density
|
||||
Uniform = 5,
|
||||
Inv_gamma_2 = 6 //Inverse gamma (type 2) density
|
||||
};
|
||||
{
|
||||
Beta = 1,
|
||||
Gamma = 2,
|
||||
Gaussian = 3, // i.e. Normal density
|
||||
Inv_gamma_1 = 4, // Inverse gamma (type 1) density
|
||||
Uniform = 5,
|
||||
Inv_gamma_2 = 6 //Inverse gamma (type 2) density
|
||||
};
|
||||
|
||||
Prior(double mean, double standard, double lower_bound, double upper_bound, double fhp, double shp);
|
||||
virtual ~Prior();
|
||||
virtual
|
||||
~Prior();
|
||||
|
||||
const double mean;
|
||||
const double standard;
|
||||
|
@ -100,7 +101,9 @@ public:
|
|||
distribution(fhp, shp)
|
||||
{
|
||||
};
|
||||
virtual ~BetaPrior(){};
|
||||
virtual ~BetaPrior()
|
||||
{
|
||||
};
|
||||
virtual pShape
|
||||
getShape()
|
||||
{
|
||||
|
@ -134,7 +137,9 @@ public:
|
|||
distribution(fhp, shp)
|
||||
{
|
||||
};
|
||||
virtual ~GammaPrior(){};
|
||||
virtual ~GammaPrior()
|
||||
{
|
||||
};
|
||||
virtual pShape
|
||||
getShape()
|
||||
{
|
||||
|
@ -164,7 +169,9 @@ public:
|
|||
distribution(shp/2, 2/fhp)
|
||||
{
|
||||
};
|
||||
virtual ~InvGamma1_Prior(){};
|
||||
virtual ~InvGamma1_Prior()
|
||||
{
|
||||
};
|
||||
virtual pShape
|
||||
getShape()
|
||||
{
|
||||
|
@ -199,7 +206,9 @@ public:
|
|||
distribution(shp/2, 2/fhp)
|
||||
{
|
||||
};
|
||||
virtual ~InvGamma2_Prior(){};
|
||||
virtual ~InvGamma2_Prior()
|
||||
{
|
||||
};
|
||||
virtual pShape
|
||||
getShape()
|
||||
{
|
||||
|
@ -239,7 +248,9 @@ public:
|
|||
distribution(fhp, shp) //pdf distribution(mean, standard)
|
||||
{
|
||||
};
|
||||
virtual ~GaussianPrior(){};
|
||||
virtual ~GaussianPrior()
|
||||
{
|
||||
};
|
||||
virtual pShape
|
||||
getShape()
|
||||
{
|
||||
|
@ -277,7 +288,9 @@ public:
|
|||
distribution(fhp, shp) //pdf distribution(lower_bound, upper_bound)
|
||||
{
|
||||
};
|
||||
virtual ~UniformPrior(){};
|
||||
virtual ~UniformPrior()
|
||||
{
|
||||
};
|
||||
virtual pShape
|
||||
getShape()
|
||||
{
|
||||
|
|
|
@ -88,4 +88,3 @@ Proposal::selectionTestDraw()
|
|||
{
|
||||
return uniformVrng();
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,9 @@ public:
|
|||
|
||||
public:
|
||||
Proposal(const VectorConstView &vJscale, const MatrixConstView &covariance);
|
||||
virtual ~Proposal() {};
|
||||
virtual ~Proposal()
|
||||
{
|
||||
};
|
||||
virtual void draw(Vector &mean, Vector &draw);
|
||||
virtual Matrix&getVar();
|
||||
virtual int seed();
|
||||
|
|
|
@ -42,13 +42,16 @@ public:
|
|||
parDraw(size), newParDraw(size)
|
||||
{
|
||||
};
|
||||
virtual ~RandomWalkMetropolisHastings() {};
|
||||
virtual ~RandomWalkMetropolisHastings()
|
||||
{
|
||||
};
|
||||
|
||||
template<class VEC1>
|
||||
double compute(VectorView &mhLogPostDens, MatrixView &mhParams, VEC1 &steadyState,
|
||||
Vector &estParams, VectorView &deepParams, const MatrixConstView &data, MatrixView &Q, Matrix &H,
|
||||
const size_t presampleStart, const size_t startDraw, size_t nMHruns,
|
||||
LogPosteriorDensity &lpd, Proposal &pDD, EstimatedParametersDescription &epd)
|
||||
double
|
||||
compute(VectorView &mhLogPostDens, MatrixView &mhParams, VEC1 &steadyState,
|
||||
Vector &estParams, VectorView &deepParams, const MatrixConstView &data, MatrixView &Q, Matrix &H,
|
||||
const size_t presampleStart, const size_t startDraw, size_t nMHruns,
|
||||
LogPosteriorDensity &lpd, Proposal &pDD, EstimatedParametersDescription &epd)
|
||||
{
|
||||
//streambuf *likbuf, *drawbuf *backup;
|
||||
std::ofstream urandfilestr, drawfilestr;
|
||||
|
@ -64,46 +67,46 @@ public:
|
|||
|
||||
for (size_t run = startDraw - 1; run < nMHruns; ++run)
|
||||
{
|
||||
overbound = false;
|
||||
pDD.draw(parDraw, newParDraw);
|
||||
for (count = 0; count < parDraw.getSize(); ++count)
|
||||
{
|
||||
overbound = (newParDraw(count) < epd.estParams[count].lower_bound || newParDraw(count) > epd.estParams[count].upper_bound);
|
||||
if (overbound)
|
||||
{
|
||||
newLogpost = -INFINITY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!overbound)
|
||||
{
|
||||
try
|
||||
{
|
||||
newLogpost = -lpd.compute(steadyState, newParDraw, deepParams, data, Q, H, presampleStart);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
throw; // for now handle the system and other errors higher-up
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
newLogpost = -INFINITY;
|
||||
}
|
||||
}
|
||||
urand = pDD.selectionTestDraw();
|
||||
if ((newLogpost > -INFINITY) && log(urand) < newLogpost-logpost)
|
||||
{
|
||||
parDraw = newParDraw;
|
||||
logpost = newLogpost;
|
||||
accepted++;
|
||||
}
|
||||
mat::get_row(mhParams, run) = parDraw;
|
||||
mhLogPostDens(run) = logpost;
|
||||
overbound = false;
|
||||
pDD.draw(parDraw, newParDraw);
|
||||
for (count = 0; count < parDraw.getSize(); ++count)
|
||||
{
|
||||
overbound = (newParDraw(count) < epd.estParams[count].lower_bound || newParDraw(count) > epd.estParams[count].upper_bound);
|
||||
if (overbound)
|
||||
{
|
||||
newLogpost = -INFINITY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!overbound)
|
||||
{
|
||||
try
|
||||
{
|
||||
newLogpost = -lpd.compute(steadyState, newParDraw, deepParams, data, Q, H, presampleStart);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
throw; // for now handle the system and other errors higher-up
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
newLogpost = -INFINITY;
|
||||
}
|
||||
}
|
||||
urand = pDD.selectionTestDraw();
|
||||
if ((newLogpost > -INFINITY) && log(urand) < newLogpost-logpost)
|
||||
{
|
||||
parDraw = newParDraw;
|
||||
logpost = newLogpost;
|
||||
accepted++;
|
||||
}
|
||||
mat::get_row(mhParams, run) = parDraw;
|
||||
mhLogPostDens(run) = logpost;
|
||||
|
||||
urandfilestr << urand << "\n"; //","
|
||||
for (size_t c = 0; c < newParDraw.getSize()-1; ++c)
|
||||
drawfilestr << newParDraw(c) << ",";
|
||||
drawfilestr << newParDraw(newParDraw.getSize()-1) << "\n";
|
||||
urandfilestr << urand << "\n"; //","
|
||||
for (size_t c = 0; c < newParDraw.getSize()-1; ++c)
|
||||
drawfilestr << newParDraw(c) << ",";
|
||||
drawfilestr << newParDraw(newParDraw.getSize()-1) << "\n";
|
||||
}
|
||||
|
||||
urandfilestr.close();
|
||||
|
|
|
@ -33,12 +33,12 @@ SteadyStateSolver::static_f(const gsl_vector *yy, void *p, gsl_vector *F)
|
|||
params *pp = (params *) p;
|
||||
VectorConstView deepParams(pp->deepParams, pp->n_params, 1);
|
||||
MatrixConstView x(pp->x, 1, pp->n_exo, 1);
|
||||
|
||||
|
||||
VectorView y(yy->data, yy->size, yy->stride);
|
||||
VectorView residual(F->data, F->size, F->stride);
|
||||
|
||||
pp->static_dll->eval(y, x, deepParams, residual, NULL, NULL);
|
||||
|
||||
|
||||
return GSL_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -48,11 +48,11 @@ SteadyStateSolver::static_df(const gsl_vector *yy, void *p, gsl_matrix *J)
|
|||
params *pp = (params *) p;
|
||||
VectorConstView deepParams(pp->deepParams, pp->n_params, 1);
|
||||
MatrixConstView x(pp->x, 1, pp->n_exo, 1);
|
||||
|
||||
|
||||
VectorView y(yy->data, yy->size, yy->stride);
|
||||
|
||||
pp->static_dll->eval(y, x, deepParams, *pp->residual, pp->g1, NULL);
|
||||
|
||||
|
||||
assert(J->size1 == J->size2 && J->size1 == J->tda);
|
||||
MatrixView g1t(J->data, J->size1, J->size2, J->tda);
|
||||
mat::transpose(g1t, *pp->g1); // GSL wants row-major order
|
||||
|
@ -66,16 +66,15 @@ SteadyStateSolver::static_fdf(const gsl_vector *yy, void *p, gsl_vector *F, gsl_
|
|||
params *pp = (params *) p;
|
||||
VectorConstView deepParams(pp->deepParams, pp->n_params, 1);
|
||||
MatrixConstView x(pp->x, 1, pp->n_exo, 1);
|
||||
|
||||
|
||||
VectorView y(yy->data, yy->size, yy->stride);
|
||||
VectorView residual(F->data, F->size, F->stride);
|
||||
|
||||
pp->static_dll->eval(y, x, deepParams, residual, pp->g1, NULL);
|
||||
|
||||
|
||||
assert(J->size1 == J->size2 && J->size1 == J->tda);
|
||||
MatrixView g1t(J->data, J->size1, J->size2, J->tda);
|
||||
mat::transpose(g1t, *pp->g1); // GSL wants row-major order
|
||||
|
||||
return GSL_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
{
|
||||
public:
|
||||
std::string message;
|
||||
SteadyStateException(const std::string &message_arg) : message(message_arg)
|
||||
SteadyStateException(const std::string &message_arg) : message(message_arg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -63,7 +63,8 @@ public:
|
|||
SteadyStateSolver(const std::string &basename, size_t n_endo_arg);
|
||||
|
||||
template <class Vec1, class Mat, class Vec2>
|
||||
void compute(Vec1 &steadyState, const Mat &Mx, const Vec2 &deepParams) throw (SteadyStateException)
|
||||
void
|
||||
compute(Vec1 &steadyState, const Mat &Mx, const Vec2 &deepParams) throw (SteadyStateException)
|
||||
{
|
||||
assert(steadyState.getStride() == 1);
|
||||
assert(deepParams.getStride() == 1);
|
||||
|
@ -97,7 +98,7 @@ public:
|
|||
|
||||
status = gsl_multiroot_test_residual(s->f, tolerance);
|
||||
}
|
||||
while(status == GSL_CONTINUE && iter < max_iterations);
|
||||
while (status == GSL_CONTINUE && iter < max_iterations);
|
||||
|
||||
if (status != GSL_SUCCESS)
|
||||
throw SteadyStateException(std::string(gsl_strerror(status)));
|
||||
|
@ -107,5 +108,3 @@ public:
|
|||
gsl_multiroot_fdfsolver_free(s);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -60,7 +60,9 @@ public:
|
|||
{
|
||||
mat::set_identity(I);
|
||||
};
|
||||
virtual ~DiscLyapFast() {};
|
||||
virtual ~DiscLyapFast()
|
||||
{
|
||||
};
|
||||
template <class MatG, class MatV, class MatX >
|
||||
void solve_lyap(const MatG &G, const MatV &V, MatX &X, double tol = 1e-16, size_t flag_ch = 0) throw (DLPException);
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ GeneralizedSchurDecomposition::~GeneralizedSchurDecomposition()
|
|||
lapack_int
|
||||
GeneralizedSchurDecomposition::selctg(const double *alphar, const double *alphai, const double *beta)
|
||||
{
|
||||
return ((*alphar * *alphar + *alphai * *alphai) < criterium_static * *beta * *beta);
|
||||
return ((*alphar **alphar + *alphai **alphai) < criterium_static **beta **beta);
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
|
|
|
@ -37,11 +37,14 @@ public:
|
|||
{
|
||||
public:
|
||||
const lapack_int info, n;
|
||||
GSDException(lapack_int info_arg, lapack_int n_arg) : info(info_arg), n(n_arg) {};
|
||||
GSDException(lapack_int info_arg, lapack_int n_arg) : info(info_arg), n(n_arg)
|
||||
{
|
||||
};
|
||||
};
|
||||
//! \todo Replace heuristic choice for workspace size by a query to determine the optimal size
|
||||
GeneralizedSchurDecomposition(size_t n_arg, double criterium_arg);
|
||||
virtual ~GeneralizedSchurDecomposition();
|
||||
virtual
|
||||
~GeneralizedSchurDecomposition();
|
||||
//! \todo Add a lock around the modification of criterium_static for making it thread-safe
|
||||
template<class Mat1, class Mat2, class Mat3>
|
||||
void compute(Mat1 &S, Mat2 &T, Mat3 &Z, size_t &sdim) throw (GSDException);
|
||||
|
|
|
@ -32,10 +32,13 @@ public:
|
|||
{
|
||||
public:
|
||||
const lapack_int info;
|
||||
LUException(lapack_int info_arg) : info(info_arg) {};
|
||||
LUException(lapack_int info_arg) : info(info_arg)
|
||||
{
|
||||
};
|
||||
};
|
||||
LUSolver(size_t dim_arg);
|
||||
virtual ~LUSolver();
|
||||
virtual
|
||||
~LUSolver();
|
||||
/*!
|
||||
Computes A^(-1)*B (possibly transposing A).
|
||||
The output is stored in B.
|
||||
|
|
|
@ -69,19 +69,52 @@ public:
|
|||
Matrix(size_t rows_arg, size_t cols_arg);
|
||||
Matrix(size_t size_arg);
|
||||
Matrix(const Matrix &arg);
|
||||
virtual ~Matrix();
|
||||
inline size_t getRows() const { return rows; }
|
||||
inline size_t getCols() const { return cols; }
|
||||
inline size_t getLd() const { return rows; }
|
||||
inline double *getData() { return data; }
|
||||
inline const double *getData() const { return data; }
|
||||
inline void setAll(double val) { std::fill_n(data, rows*cols, val); }
|
||||
inline double &operator() (size_t i, size_t j) { return data[i+j*rows]; }
|
||||
inline const double &operator() (size_t i, size_t j) const { return data[i+j*rows]; }
|
||||
virtual
|
||||
~Matrix();
|
||||
inline size_t
|
||||
getRows() const
|
||||
{
|
||||
return rows;
|
||||
}
|
||||
inline size_t
|
||||
getCols() const
|
||||
{
|
||||
return cols;
|
||||
}
|
||||
inline size_t
|
||||
getLd() const
|
||||
{
|
||||
return rows;
|
||||
}
|
||||
inline double *
|
||||
getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
inline const double *
|
||||
getData() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
inline void
|
||||
setAll(double val)
|
||||
{
|
||||
std::fill_n(data, rows*cols, val);
|
||||
}
|
||||
inline double &
|
||||
operator()(size_t i, size_t j)
|
||||
{
|
||||
return data[i+j*rows];
|
||||
}
|
||||
inline const double &
|
||||
operator()(size_t i, size_t j) const
|
||||
{
|
||||
return data[i+j*rows];
|
||||
}
|
||||
//! Assignment operator, only works for matrices of same dimension
|
||||
template<class Mat>
|
||||
Matrix &
|
||||
operator= (const Mat &arg)
|
||||
operator=(const Mat &arg)
|
||||
{
|
||||
assert(rows == arg.getRows() && cols == arg.getCols());
|
||||
for (size_t j = 0; j < cols; j++)
|
||||
|
@ -112,23 +145,54 @@ public:
|
|||
&& col_offset < arg.getCols()
|
||||
&& col_offset + cols_arg <= arg.getCols());
|
||||
}
|
||||
virtual ~MatrixView(){};
|
||||
inline size_t getRows() const { return rows; }
|
||||
inline size_t getCols() const { return cols; }
|
||||
inline size_t getLd() const { return ld; }
|
||||
inline double *getData() { return data; }
|
||||
inline const double *getData() const { return data; }
|
||||
inline void setAll(double val)
|
||||
virtual ~MatrixView()
|
||||
{
|
||||
};
|
||||
inline size_t
|
||||
getRows() const
|
||||
{
|
||||
return rows;
|
||||
}
|
||||
inline size_t
|
||||
getCols() const
|
||||
{
|
||||
return cols;
|
||||
}
|
||||
inline size_t
|
||||
getLd() const
|
||||
{
|
||||
return ld;
|
||||
}
|
||||
inline double *
|
||||
getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
inline const double *
|
||||
getData() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
inline void
|
||||
setAll(double val)
|
||||
{
|
||||
for (double *p = data; p < data + cols*ld; p += ld)
|
||||
std::fill_n(p, rows, val);
|
||||
}
|
||||
inline double &operator() (size_t i, size_t j) { return data[i+j*ld]; }
|
||||
inline const double &operator() (size_t i, size_t j) const { return data[i+j*ld]; }
|
||||
inline double &
|
||||
operator()(size_t i, size_t j)
|
||||
{
|
||||
return data[i+j*ld];
|
||||
}
|
||||
inline const double &
|
||||
operator()(size_t i, size_t j) const
|
||||
{
|
||||
return data[i+j*ld];
|
||||
}
|
||||
//! Assignment operator, only works for matrices of same dimension
|
||||
template<class Mat>
|
||||
MatrixView &
|
||||
operator= (const Mat &arg)
|
||||
operator=(const Mat &arg)
|
||||
{
|
||||
assert(rows == arg.getRows() && cols == arg.getCols());
|
||||
for (size_t j = 0; j < cols; j++)
|
||||
|
@ -158,12 +222,34 @@ public:
|
|||
&& col_offset < arg.getCols()
|
||||
&& col_offset + cols_arg <= arg.getCols());
|
||||
}
|
||||
virtual ~MatrixConstView(){};
|
||||
inline size_t getRows() const { return rows; }
|
||||
inline size_t getCols() const { return cols; }
|
||||
inline size_t getLd() const { return ld; }
|
||||
inline const double *getData() const { return data; }
|
||||
inline const double &operator() (size_t i, size_t j) const { return data[i+j*ld]; }
|
||||
virtual ~MatrixConstView()
|
||||
{
|
||||
};
|
||||
inline size_t
|
||||
getRows() const
|
||||
{
|
||||
return rows;
|
||||
}
|
||||
inline size_t
|
||||
getCols() const
|
||||
{
|
||||
return cols;
|
||||
}
|
||||
inline size_t
|
||||
getLd() const
|
||||
{
|
||||
return ld;
|
||||
}
|
||||
inline const double *
|
||||
getData() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
inline const double &
|
||||
operator()(size_t i, size_t j) const
|
||||
{
|
||||
return data[i+j*ld];
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const Matrix &M);
|
||||
|
@ -561,9 +647,9 @@ namespace mat
|
|||
|
||||
if (vToRows.size() == 0 && vToCols.size() == 0 && vrows.size() == 0 && vcols.size() == 0)
|
||||
a = b;
|
||||
else if (vToRows.size() == 0 && vrows.size() == 0) // just reorder columns
|
||||
else if (vToRows.size() == 0 && vrows.size() == 0) // just reorder columns
|
||||
reorderColumnsByVectors(a, vToCols, b, vcols);
|
||||
else if (vToCols.size() == 0 && vcols.size() == 0) // just reorder rows
|
||||
else if (vToCols.size() == 0 && vcols.size() == 0) // just reorder rows
|
||||
reorderRowsByVectors(a, vToRows, b, vrows);
|
||||
else
|
||||
{
|
||||
|
|
|
@ -41,7 +41,8 @@ public:
|
|||
\param[in] cols2_arg Number of columns of the matrix to be multiplied by Q
|
||||
*/
|
||||
QRDecomposition(size_t rows_arg, size_t cols_arg, size_t cols2_arg);
|
||||
virtual ~QRDecomposition();
|
||||
virtual
|
||||
~QRDecomposition();
|
||||
//! Performs the QR decomposition of a matrix, and left-multiplies another matrix by Q
|
||||
/*!
|
||||
\param[in,out] A On input, the matrix to be decomposed. On output, equals to the output of dgeqrf
|
||||
|
|
|
@ -63,17 +63,47 @@ private:
|
|||
public:
|
||||
Vector(size_t size_arg);
|
||||
Vector(const Vector &arg);
|
||||
virtual ~Vector();
|
||||
inline size_t getSize() const { return size; }
|
||||
inline size_t getStride() const { return 1; }
|
||||
inline double *getData() { return data; }
|
||||
inline const double *getData() const { return data; }
|
||||
inline void setAll(double val) { std::fill_n(data, size, val); }
|
||||
inline double &operator() (size_t i) { return data[i]; }
|
||||
inline const double &operator() (size_t i) const { return data[i]; }
|
||||
virtual
|
||||
~Vector();
|
||||
inline size_t
|
||||
getSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
inline size_t
|
||||
getStride() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
inline double *
|
||||
getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
inline const double *
|
||||
getData() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
inline void
|
||||
setAll(double val)
|
||||
{
|
||||
std::fill_n(data, size, val);
|
||||
}
|
||||
inline double &
|
||||
operator()(size_t i)
|
||||
{
|
||||
return data[i];
|
||||
}
|
||||
inline const double &
|
||||
operator()(size_t i) const
|
||||
{
|
||||
return data[i];
|
||||
}
|
||||
//! Assignment operator, only works for vectors of same size
|
||||
template<class Vec>
|
||||
Vector &operator=(const Vec &arg)
|
||||
Vector &
|
||||
operator=(const Vec &arg)
|
||||
{
|
||||
assert(size == arg.getSize());
|
||||
const double *p2 = arg.getData();
|
||||
|
@ -99,25 +129,52 @@ private:
|
|||
public:
|
||||
VectorView(double *data_arg, size_t size_arg, size_t stride_arg);
|
||||
/* Can't use a template for the 2 constructors below: this would override the
|
||||
constructor which uses a pointer, because the argument list is the same */
|
||||
constructor which uses a pointer, because the argument list is the same */
|
||||
VectorView(Vector &arg, size_t offset, size_t size_arg);
|
||||
VectorView(VectorView &arg, size_t offset, size_t size_arg);
|
||||
virtual ~VectorView(){};
|
||||
inline size_t getSize() const { return size; }
|
||||
inline size_t getStride() const { return stride; }
|
||||
inline double *getData() { return data; }
|
||||
inline const double *getData() const { return data; }
|
||||
inline void setAll(double val)
|
||||
virtual ~VectorView()
|
||||
{
|
||||
};
|
||||
inline size_t
|
||||
getSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
inline size_t
|
||||
getStride() const
|
||||
{
|
||||
return stride;
|
||||
}
|
||||
inline double *
|
||||
getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
inline const double *
|
||||
getData() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
inline void
|
||||
setAll(double val)
|
||||
{
|
||||
for (double *p = data; p < data + size*stride; p += stride)
|
||||
*p = val;
|
||||
}
|
||||
inline double &operator() (size_t i) { return data[i*stride]; }
|
||||
inline const double &operator() (size_t i) const { return data[i*stride]; }
|
||||
inline double &
|
||||
operator()(size_t i)
|
||||
{
|
||||
return data[i*stride];
|
||||
}
|
||||
inline const double &
|
||||
operator()(size_t i) const
|
||||
{
|
||||
return data[i*stride];
|
||||
}
|
||||
//! Assignment operator, only works for vectors of same size
|
||||
template<class Vec>
|
||||
VectorView &
|
||||
operator= (const Vec &arg)
|
||||
operator=(const Vec &arg)
|
||||
{
|
||||
assert(size == arg.getSize());
|
||||
double *p1;
|
||||
|
@ -145,11 +202,29 @@ public:
|
|||
VectorConstView(const VectorView &arg, size_t offset, size_t size_arg);
|
||||
VectorConstView(const VectorConstView &arg, size_t offset, size_t size_arg);
|
||||
|
||||
virtual ~VectorConstView() {};
|
||||
inline size_t getSize() const { return size; }
|
||||
inline size_t getStride() const { return stride; }
|
||||
inline const double *getData() const { return data; }
|
||||
inline const double &operator() (size_t i) const { return data[i*stride]; }
|
||||
virtual ~VectorConstView()
|
||||
{
|
||||
};
|
||||
inline size_t
|
||||
getSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
inline size_t
|
||||
getStride() const
|
||||
{
|
||||
return stride;
|
||||
}
|
||||
inline const double *
|
||||
getData() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
inline const double &
|
||||
operator()(size_t i) const
|
||||
{
|
||||
return data[i*stride];
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const Vector &V);
|
||||
|
|
|
@ -47,7 +47,11 @@ public:
|
|||
LogMHMCMCposteriorMexErrMsgTxtException(const std::string &msg) : errMsg(msg)
|
||||
{
|
||||
}
|
||||
inline const char *getErrMsg() { return errMsg.c_str(); }
|
||||
inline const char *
|
||||
getErrMsg()
|
||||
{
|
||||
return errMsg.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -279,7 +283,7 @@ sampleMHMC(LogPosteriorDensity &lpd, RandomWalkMetropolisHastings &rwmh,
|
|||
// new or different size result arrays/matrices
|
||||
currInitSizeArray = (size_t) InitSizeArray(b-1);
|
||||
if (mxMhLogPostDensPtr)
|
||||
mxDestroyArray(mxMhLogPostDensPtr); // log post density array
|
||||
mxDestroyArray(mxMhLogPostDensPtr); // log post density array
|
||||
mxMhLogPostDensPtr = mxCreateDoubleMatrix(currInitSizeArray, 1, mxREAL);
|
||||
if (mxMhLogPostDensPtr == NULL)
|
||||
{
|
||||
|
@ -287,7 +291,7 @@ sampleMHMC(LogPosteriorDensity &lpd, RandomWalkMetropolisHastings &rwmh,
|
|||
return (-1);
|
||||
}
|
||||
if (mxMhParamDrawsPtr)
|
||||
mxDestroyArray(mxMhParamDrawsPtr); // accepted MCMC MH draws
|
||||
mxDestroyArray(mxMhParamDrawsPtr); // accepted MCMC MH draws
|
||||
mxMhParamDrawsPtr = mxCreateDoubleMatrix(currInitSizeArray, npar, mxREAL);
|
||||
if (mxMhParamDrawsPtr == NULL)
|
||||
{
|
||||
|
@ -375,7 +379,7 @@ sampleMHMC(LogPosteriorDensity &lpd, RandomWalkMetropolisHastings &rwmh,
|
|||
// new or different size result arrays/matrices
|
||||
currInitSizeArray = (size_t) InitSizeArray(b-1);
|
||||
if (mxMhLogPostDensPtr)
|
||||
mxDestroyArray(mxMhLogPostDensPtr); // log post density array
|
||||
mxDestroyArray(mxMhLogPostDensPtr); // log post density array
|
||||
mxMhLogPostDensPtr = mxCreateDoubleMatrix(currInitSizeArray, 1, mxREAL);
|
||||
if (mxMhLogPostDensPtr == NULL)
|
||||
{
|
||||
|
@ -383,7 +387,7 @@ sampleMHMC(LogPosteriorDensity &lpd, RandomWalkMetropolisHastings &rwmh,
|
|||
return (-1);
|
||||
}
|
||||
if (mxMhParamDrawsPtr)
|
||||
mxDestroyArray(mxMhParamDrawsPtr); // accepted MCMC MH draws
|
||||
mxDestroyArray(mxMhParamDrawsPtr); // accepted MCMC MH draws
|
||||
mxMhParamDrawsPtr = mxCreateDoubleMatrix(currInitSizeArray, npar, mxREAL);
|
||||
if (mxMhParamDrawsPtr == NULL)
|
||||
{
|
||||
|
@ -603,9 +607,9 @@ sampleMHMC(LogPosteriorDensity &lpd, RandomWalkMetropolisHastings &rwmh,
|
|||
|
||||
cleanup:
|
||||
if (mxMhLogPostDensPtr)
|
||||
mxDestroyArray(mxMhLogPostDensPtr); // delete log post density array
|
||||
mxDestroyArray(mxMhLogPostDensPtr); // delete log post density array
|
||||
if (mxMhParamDrawsPtr)
|
||||
mxDestroyArray(mxMhParamDrawsPtr); // delete accepted MCMC MH draws
|
||||
mxDestroyArray(mxMhParamDrawsPtr); // delete accepted MCMC MH draws
|
||||
|
||||
#ifdef MATLAB_MEX_FILE
|
||||
// Waitbar
|
||||
|
@ -631,7 +635,7 @@ sampleMHMC(LogPosteriorDensity &lpd, RandomWalkMetropolisHastings &rwmh,
|
|||
int
|
||||
logMCMCposterior(VectorConstView &estParams, const MatrixConstView &data,
|
||||
const size_t fblock, const size_t nBlocks, const VectorConstView &nMHruns, const MatrixConstView &D,
|
||||
VectorView &steadyState, VectorView &deepParams, MatrixView &Q, Matrix &H)
|
||||
VectorView &steadyState, VectorView &deepParams, MatrixView &Q, Matrix &H)
|
||||
{
|
||||
// Retrieve pointers to global variables
|
||||
const mxArray *M_ = mexGetVariablePtr("global", "M_");
|
||||
|
@ -712,7 +716,6 @@ logMCMCposterior(VectorConstView &estParams, const MatrixConstView &data,
|
|||
estParamsInfo);
|
||||
EstimatedParametersDescription epd(estSubsamples, estParamsInfo);
|
||||
|
||||
|
||||
bool noconstant = (bool) *mxGetPr(mxGetField(options_, 0, "noconstant"));
|
||||
|
||||
// Allocate LogPosteriorDensity object
|
||||
|
@ -771,20 +774,20 @@ mexFunction(int nlhs, mxArray *plhs[],
|
|||
|
||||
assert(nMHruns.getSize() == nBlocks);
|
||||
|
||||
mxArray *dataset_data = mxGetField(dataset,0,"data");
|
||||
mxArray *dataset_data = mxGetField(dataset, 0, "data");
|
||||
MatrixConstView data(mxGetPr(dataset_data), mxGetM(dataset_data), mxGetN(dataset_data), mxGetM(dataset_data));
|
||||
|
||||
int endo_nbr = *(int*)mxGetPr(mxGetField(M_, 0, "endo_nbr"));
|
||||
int exo_nbr = *(int*)mxGetPr(mxGetField(M_, 0, "exo_nbr"));
|
||||
int param_nbr = *(int*)mxGetPr(mxGetField(M_, 0, "param_nbr"));
|
||||
int endo_nbr = *(int *) mxGetPr(mxGetField(M_, 0, "endo_nbr"));
|
||||
int exo_nbr = *(int *) mxGetPr(mxGetField(M_, 0, "exo_nbr"));
|
||||
int param_nbr = *(int *) mxGetPr(mxGetField(M_, 0, "param_nbr"));
|
||||
int varobs_nbr = mxGetN(mxGetField(options_, 0, "varobs"));
|
||||
|
||||
VectorView steadyState(mxGetPr(mxGetField(oo_,0,"steady_state")),endo_nbr, 1);
|
||||
VectorView deepParams(mxGetPr(mxGetField(M_, 0, "params")),param_nbr,1);
|
||||
VectorView steadyState(mxGetPr(mxGetField(oo_, 0, "steady_state")), endo_nbr, 1);
|
||||
VectorView deepParams(mxGetPr(mxGetField(M_, 0, "params")), param_nbr, 1);
|
||||
|
||||
MatrixView Q(mxGetPr(mxGetField(M_, 0, "Sigma_e")), exo_nbr, exo_nbr, exo_nbr);
|
||||
|
||||
Matrix H(varobs_nbr,varobs_nbr);
|
||||
Matrix H(varobs_nbr, varobs_nbr);
|
||||
const mxArray *H_mx = mxGetField(M_, 0, "H");
|
||||
if (mxGetM(H_mx) == 1 && mxGetN(H_mx) == 1 && *mxGetPr(H_mx) == 0)
|
||||
H.setAll(0.0);
|
||||
|
|
|
@ -36,7 +36,11 @@ public:
|
|||
LogposteriorMexErrMsgTxtException(const std::string &msg) : errMsg(msg)
|
||||
{
|
||||
}
|
||||
inline const char *getErrMsg() { return errMsg.c_str(); }
|
||||
inline const char *
|
||||
getErrMsg()
|
||||
{
|
||||
return errMsg.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -103,8 +107,8 @@ template <class VEC1, class VEC2>
|
|||
double
|
||||
logposterior(VEC1 &estParams, const MatrixConstView &data,
|
||||
const mxArray *options_, const mxArray *M_, const mxArray *estim_params_,
|
||||
const mxArray *bayestopt_, const mxArray *oo_, VEC2 &steadyState, double *trend_coeff,
|
||||
VectorView &deepParams, Matrix &H, MatrixView &Q)
|
||||
const mxArray *bayestopt_, const mxArray *oo_, VEC2 &steadyState, double *trend_coeff,
|
||||
VectorView &deepParams, Matrix &H, MatrixView &Q)
|
||||
{
|
||||
double loglinear = *mxGetPr(mxGetField(options_, 0, "loglinear"));
|
||||
if (loglinear == 1)
|
||||
|
@ -203,10 +207,10 @@ void
|
|||
mexFunction(int nlhs, mxArray *plhs[],
|
||||
int nrhs, const mxArray *prhs[])
|
||||
{
|
||||
if (nrhs != 7 )
|
||||
if (nrhs != 7)
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT("logposterior: exactly 7 input arguments are required.");
|
||||
|
||||
if (nlhs > 9 )
|
||||
if (nlhs > 9)
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT("logposterior returns 8 output arguments at the most.");
|
||||
|
||||
// Check and retrieve the RHS arguments
|
||||
|
@ -219,9 +223,9 @@ mexFunction(int nlhs, mxArray *plhs[],
|
|||
for (int i = 1; i < 7; ++i)
|
||||
if (!mxIsStruct(prhs[i]))
|
||||
{
|
||||
std::stringstream msg;
|
||||
msg << "logposterior: argument " << i+1 << " must be a Matlab structure";
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(msg.str().c_str());
|
||||
std::stringstream msg;
|
||||
msg << "logposterior: argument " << i+1 << " must be a Matlab structure";
|
||||
DYN_MEX_FUNC_ERR_MSG_TXT(msg.str().c_str());
|
||||
}
|
||||
|
||||
const mxArray *dataset = prhs[1];
|
||||
|
@ -231,7 +235,7 @@ mexFunction(int nlhs, mxArray *plhs[],
|
|||
const mxArray *bayestopt_ = prhs[5];
|
||||
const mxArray *oo_ = prhs[6];
|
||||
|
||||
const mxArray *dataset_data = mxGetField(dataset,0,"data");
|
||||
const mxArray *dataset_data = mxGetField(dataset, 0, "data");
|
||||
MatrixConstView data(mxGetPr(dataset_data), mxGetM(dataset_data), mxGetN(dataset_data), mxGetM(dataset_data));
|
||||
|
||||
// Creaete LHS arguments
|
||||
|
@ -251,12 +255,12 @@ mexFunction(int nlhs, mxArray *plhs[],
|
|||
double *lik = mxGetPr(plhs[0]);
|
||||
double *exit_flag = mxGetPr(plhs[1]);
|
||||
|
||||
VectorView steadyState(mxGetPr(mxGetField(oo_,0,"steady_state")),endo_nbr, 1);
|
||||
VectorView deepParams(mxGetPr(mxGetField(M_, 0, "params")),param_nbr,1);
|
||||
VectorView steadyState(mxGetPr(mxGetField(oo_, 0, "steady_state")), endo_nbr, 1);
|
||||
VectorView deepParams(mxGetPr(mxGetField(M_, 0, "params")), param_nbr, 1);
|
||||
|
||||
MatrixView Q(mxGetPr(mxGetField(M_, 0, "Sigma_e")), exo_nbr, exo_nbr, exo_nbr);
|
||||
|
||||
Matrix H(varobs_nbr,varobs_nbr);
|
||||
Matrix H(varobs_nbr, varobs_nbr);
|
||||
const mxArray *H_mx = mxGetField(M_, 0, "H");
|
||||
if (mxGetM(H_mx) == 1 && mxGetN(H_mx) == 1 && *mxGetPr(H_mx) == 0)
|
||||
H.setAll(0.0);
|
||||
|
@ -270,7 +274,7 @@ mexFunction(int nlhs, mxArray *plhs[],
|
|||
try
|
||||
{
|
||||
*lik = logposterior(estParams, data, options_, M_, estim_params_, bayestopt_, oo_,
|
||||
steadyState, trend_coeff, deepParams, H, Q);
|
||||
steadyState, trend_coeff, deepParams, H, Q);
|
||||
*info_mx = 0;
|
||||
*exit_flag = 0;
|
||||
}
|
||||
|
|
|
@ -147,4 +147,3 @@ main(int argc, char **argv)
|
|||
std::cout << "Matrix Pinf: " << std::endl << Pinf << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -130,4 +130,3 @@ main(int argc, char **argv)
|
|||
|
||||
std::cout << "ll: " << std::endl << ll << std::endl;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,4 +88,3 @@ DynamicModelDLL::~DynamicModelDLL()
|
|||
dlclose(dynamicHinstance);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue