Fixed indentation of c/h/cc/hh files.

time-shift
Stéphane Adjemian (Charybdis) 2017-05-16 16:30:27 +02:00
parent 2f07c6f1db
commit b4448937cc
164 changed files with 11756 additions and 9110 deletions

View File

@ -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;
};
};

View File

@ -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;
};
};
};

View File

@ -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

View File

@ -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);
};
};

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
};
};

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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);
};
};

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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 */

View File

@ -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);

View File

@ -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:

View File

@ -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 */

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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);
}

View File

@ -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);

View File

@ -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());
}
}
};

View File

@ -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;
}

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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" */

View File

@ -213,4 +213,3 @@ operator<<(std::ostream &out, const DecisionRules::BlanchardKahnException &e)
out << "The Blanchard Kahn rank condition is not satisfied";
return out;
}

View File

@ -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.

View File

@ -44,4 +44,3 @@ DetrendData::detrend(const VectorView &SteadyState, const MatrixConstView &dataV
detrendedDataView(i, j) = dataView(i, j) - SteadyState(varobs[i]);
}
};

View File

@ -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);

View File

@ -37,4 +37,3 @@ EstimatedParameter::EstimatedParameter(const EstimatedParameter::pType type_arg,
EstimatedParameter::~EstimatedParameter()
{
}

View File

@ -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;

View File

@ -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;

View File

@ -33,4 +33,3 @@ EstimationSubsample::EstimationSubsample(size_t INstartPeriod, size_t INendPerio
EstimationSubsample::~EstimationSubsample()
{
}

View File

@ -59,7 +59,8 @@ class EstimationSubsample
{
public:
EstimationSubsample(size_t startPeriod, size_t endPeriod);
virtual ~EstimationSubsample();
virtual
~EstimationSubsample();
size_t startPeriod;
size_t endPeriod;

View File

@ -74,4 +74,3 @@ InitializeKalmanFilter::setPstar(Matrix &Pstar, Matrix &Pinf, const Matrix &T, c
Pinf.setAll(0.0);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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:

View File

@ -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()
{
}

View File

@ -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_)

View File

@ -38,4 +38,3 @@ LogLikelihoodSubSample::LogLikelihoodSubSample(const std::string &basename, Esti
varobs, riccati_tol, lyapunov_tol, noconstant_arg), eigQ(n_exo), eigH(varobs.size())
{
};

View File

@ -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_)

View File

@ -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();
}

View File

@ -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,

View File

@ -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;
};

View File

@ -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));
}

View File

@ -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

View File

@ -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()
{

View File

@ -88,4 +88,3 @@ Proposal::selectionTestDraw()
{
return uniformVrng();
}

View File

@ -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();

View File

@ -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();

View File

@ -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;
}

View File

@ -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);
}
};

View File

@ -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);

View File

@ -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 &

View File

@ -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);

View File

@ -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.

View File

@ -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
{

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -147,4 +147,3 @@ main(int argc, char **argv)
std::cout << "Matrix Pinf: " << std::endl << Pinf << std::endl;
}

View File

@ -130,4 +130,3 @@ main(int argc, char **argv)
std::cout << "ll: " << std::endl << ll << std::endl;
}

View File

@ -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