Dynare++: various simplifications

time-shift
Sébastien Villemot 2019-04-24 14:52:30 +02:00
parent e490bee3e0
commit 0b9b69f638
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
49 changed files with 631 additions and 1240 deletions

View File

@ -29,7 +29,7 @@ struct QuadParams
QuadParams(int argc, char **argv); QuadParams(int argc, char **argv);
void check_consistency() const; void check_consistency() const;
private: private:
enum {opt_max_level, opt_discard_weight, opt_vcov}; enum class opt {max_level, discard_weight, vcov};
}; };
QuadParams::QuadParams(int argc, char **argv) QuadParams::QuadParams(int argc, char **argv)
@ -45,9 +45,9 @@ QuadParams::QuadParams(int argc, char **argv)
argc--; argc--;
struct option const opts [] = { struct option const opts [] = {
{"max-level", required_argument, nullptr, opt_max_level}, {"max-level", required_argument, nullptr, static_cast<int>(opt::max_level)},
{"discard-weight", required_argument, nullptr, opt_discard_weight}, {"discard-weight", required_argument, nullptr, static_cast<int>(opt::discard_weight)},
{"vcov", required_argument, nullptr, opt_vcov}, {"vcov", required_argument, nullptr, static_cast<int>(opt::vcov)},
{nullptr, 0, nullptr, 0} {nullptr, 0, nullptr, 0}
}; };
@ -55,29 +55,35 @@ QuadParams::QuadParams(int argc, char **argv)
int index; int index;
while (-1 != (ret = getopt_long(argc, argv, "", opts, &index))) while (-1 != (ret = getopt_long(argc, argv, "", opts, &index)))
{ {
switch (ret) if (ret == '?')
{ {
case opt_max_level: std::cerr << "Unknown option, ignored\n";
continue;
}
switch (static_cast<opt>(ret))
{
case opt::max_level:
try try
{ {
max_level = std::stoi(std::string{optarg}); max_level = std::stoi(optarg);
} }
catch (const std::invalid_argument &e) catch (const std::invalid_argument &e)
{ {
std::cerr << "Couldn't parse integer " << optarg << ", ignored" << std::endl; std::cerr << "Couldn't parse integer " << optarg << ", ignored" << std::endl;
} }
break; break;
case opt_discard_weight: case opt::discard_weight:
try try
{ {
discard_weight = std::stod(std::string{optarg}); discard_weight = std::stod(optarg);
} }
catch (const std::invalid_argument &e) catch (const std::invalid_argument &e)
{ {
std::cerr << "Couldn't parse float " << optarg << ", ignored" << std::endl; std::cerr << "Couldn't parse float " << optarg << ", ignored" << std::endl;
} }
break; break;
case opt_vcov: case opt::vcov:
vcovname = optarg; vcovname = optarg;
break; break;
} }
@ -124,7 +130,7 @@ main(int argc, char **argv)
// parse the vcov matrix // parse the vcov matrix
ogp::MatrixParser mp; ogp::MatrixParser mp;
mp.parse(contents.length(), contents.c_str()); mp.parse(contents);
if (mp.nrows() != mp.ncols()) if (mp.nrows() != mp.ncols())
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
"VCOV matrix not square"); "VCOV matrix not square");

View File

@ -105,7 +105,7 @@ SimResults::writeMat(const std::string &base, const std::string &lname) const
mat_t *matfd = Mat_Create(matfile_name.c_str(), nullptr); mat_t *matfd = Mat_Create(matfile_name.c_str(), nullptr);
if (matfd) if (matfd)
{ {
writeMat(matfd, lname.c_str()); writeMat(matfd, lname);
Mat_Close(matfd); Mat_Close(matfd);
} }
} }

View File

@ -186,8 +186,8 @@ Journal::printHeader()
<< "Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under\n" << "Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under\n"
<< "GPL: modules integ, tl, kord, sylv, src, extern and documentation\n" << "GPL: modules integ, tl, kord, sylv, src, extern and documentation\n"
<< "LGPL: modules parser, utils\n" << "LGPL: modules parser, utils\n"
<< " for GPL see http://www.gnu.org/licenses/gpl.html\n" << " for GPL see https://www.gnu.org/licenses/gpl.html\n"
<< " for LGPL see http://www.gnu.org/licenses/lgpl.html\n" << " for LGPL see https://www.gnu.org/licenses/lgpl.html\n"
<< "\n\n" << "\n\n"
<< "System info: "; << "System info: ";
#ifndef _WIN32 #ifndef _WIN32

View File

@ -1,16 +1,13 @@
noinst_LIBRARIES = libparser.a noinst_LIBRARIES = libparser.a
GENERATED_FILES = assign_tab.cc csv_tab.cc formula_tab.cc matrix_tab.cc namelist_tab.cc assign_tab.hh csv_tab.hh formula_tab.hh matrix_tab.hh namelist_tab.hh assign_ll.cc csv_ll.cc formula_ll.cc matrix_ll.cc namelist_ll.cc GENERATED_FILES = assign_tab.cc formula_tab.cc matrix_tab.cc assign_tab.hh formula_tab.hh matrix_tab.hh assign_ll.cc formula_ll.cc matrix_ll.cc
libparser_a_SOURCES = \ libparser_a_SOURCES = \
location.hh \ location.hh \
namelist.hh \
atom_assignings.cc \ atom_assignings.cc \
atom_assignings.hh \ atom_assignings.hh \
atom_substitutions.cc \ atom_substitutions.cc \
atom_substitutions.hh \ atom_substitutions.hh \
csv_parser.cc \
csv_parser.hh \
dynamic_atoms.cc \ dynamic_atoms.cc \
dynamic_atoms.hh \ dynamic_atoms.hh \
fine_atoms.cc \ fine_atoms.cc \
@ -33,7 +30,7 @@ libparser_a_CPPFLAGS = -I../.. $(BOOST_CPPFLAGS)
BUILT_SOURCES = $(GENERATED_FILES) BUILT_SOURCES = $(GENERATED_FILES)
EXTRA_DIST = assign.yy csv.yy formula.yy matrix.yy namelist.yy assign.ll csv.ll formula.ll matrix.ll namelist.ll EXTRA_DIST = assign.yy formula.yy matrix.yy assign.ll formula.ll matrix.ll
%_tab.cc %_tab.hh: %.yy %_tab.cc %_tab.hh: %.yy
$(YACC) -W -o$*_tab.cc $< $(YACC) -W -o$*_tab.cc $<

View File

@ -10,8 +10,9 @@
%code %code
{ {
#include "atom_assignings.hh" #include "atom_assignings.hh"
#include <string>
void asgn_error(const char*); void asgn_error(std::string);
int asgn_lex(); int asgn_lex();
extern ogp::AtomAssignings* aparser; extern ogp::AtomAssignings* aparser;
} }
@ -51,7 +52,7 @@ space : space BLANK | BLANK;
%% %%
void void
asgn_error(const char* mes) asgn_error(std::string mes)
{ {
aparser->error(mes); aparser->error(std::move(mes));
} }

View File

@ -10,17 +10,15 @@
#include <limits> #include <limits>
#include <iostream> #include <iostream>
#include <algorithm> #include <sstream>
#include <iomanip>
using namespace ogp; using namespace ogp;
AtomAssignings::AtomAssignings(const AtomAssignings &aa, ogp::StaticAtoms &a) AtomAssignings::AtomAssignings(const AtomAssignings &aa, ogp::StaticAtoms &a)
: atoms(a), expr(aa.expr, atoms), left_names(aa.left_names), : atoms(a), expr(aa.expr, atoms), left_names(aa.left_names),
order(aa.order) lname2expr(aa.lname2expr), order(aa.order)
{ {
// fill the lname2expr
for (auto it : aa.lname2expr)
lname2expr.emplace(left_names.query(it.first), it.second);
} }
/** A global symbol for passing info to the AtomAssignings from /** A global symbol for passing info to the AtomAssignings from
@ -29,34 +27,30 @@ AtomAssignings *aparser;
/** The declaration of functions defined in asgn_ll.cc and asgn_tab.cc /** The declaration of functions defined in asgn_ll.cc and asgn_tab.cc
* generated from assign.lex assign.y */ * generated from assign.lex assign.y */
void *asgn__scan_buffer(char *, size_t); void *asgn__scan_string(const char *);
void asgn__destroy_buffer(void *); void asgn__destroy_buffer(void *);
void asgn_parse(); void asgn_parse();
extern location_type asgn_lloc; extern location_type asgn_lloc;
void void
AtomAssignings::parse(int length, const char *stream) AtomAssignings::parse(const string &stream)
{ {
auto buffer = std::make_unique<char[]>(length+2);
std::copy_n(stream, length, buffer.get());
buffer[length] = '\0';
buffer[length+1] = '\0';
asgn_lloc.off = 0; asgn_lloc.off = 0;
asgn_lloc.ll = 0; asgn_lloc.ll = 0;
void *p = asgn__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2); void *p = asgn__scan_string(stream.c_str());
aparser = this; aparser = this;
asgn_parse(); asgn_parse();
asgn__destroy_buffer(p); asgn__destroy_buffer(p);
} }
void void
AtomAssignings::error(const char *mes) AtomAssignings::error(string mes)
{ {
throw ParserException(mes, asgn_lloc.off); throw ParserException(std::move(mes), asgn_lloc.off);
} }
void void
AtomAssignings::add_assignment_to_double(const char *name, double val) AtomAssignings::add_assignment_to_double(string name, double val)
{ {
// if left hand side is a registered atom, insert it to tree // if left hand side is a registered atom, insert it to tree
int t; int t;
@ -75,25 +69,26 @@ AtomAssignings::add_assignment_to_double(const char *name, double val)
order.push_back(t); order.push_back(t);
// add the double to the tree // add the double to the tree
char tmp[100]; std::ostringstream buf;
sprintf(tmp, "%30.25g", val); buf << std::setprecision(std::numeric_limits<double>::max_digits10)
<< val;
try try
{ {
expr.parse(strlen(tmp), tmp); expr.parse(buf.str());
} }
catch (const ParserException &e) catch (const ParserException &e)
{ {
// should never happen // should never happen
throw ParserException(string("Error parsing double ")+tmp+": "+e.message(), 0); throw ParserException(string("Error parsing double ")+buf.str()+": "+e.message(), 0);
} }
// register name of the left hand side and put to lname2expr // register name of the left hand side and put to lname2expr
const char *ss = left_names.insert(name); left_names.insert(name);
lname2expr.emplace(ss, order.size()-1); lname2expr.emplace(std::move(name), order.size()-1);
} }
void void
AtomAssignings::add_assignment(int asgn_off, const char *str, int name_len, AtomAssignings::add_assignment(int asgn_off, const string &str, int name_len,
int right_off, int right_len) int right_off, int right_len)
{ {
// the order of doing things here is important: since the // the order of doing things here is important: since the
@ -102,23 +97,21 @@ AtomAssignings::add_assignment(int asgn_off, const char *str, int name_len,
// nulary term for the left hand side, it must be inserted to the // nulary term for the left hand side, it must be inserted to the
// expression tree before the expression is parsed. // expression tree before the expression is parsed.
// find the name in the atoms, make copy of name to be able to put // find the name in the atoms
// '\0' at the end string name = str.substr(0, name_len);
auto *buf = new char[name_len+1];
strncpy(buf, str, name_len);
buf[name_len] = '\0';
// if left hand side is a registered atom, insert it to tree // if left hand side is a registered atom, insert it to tree
int t; int t;
try try
{ {
t = atoms.check(buf); t = atoms.check(name);
if (t == -1) if (t == -1)
t = expr.add_nulary(buf); t = expr.add_nulary(name);
} }
catch (const ParserException &e) catch (const ParserException &e)
{ {
atoms.register_name(buf); atoms.register_name(name);
t = expr.add_nulary(buf); t = expr.add_nulary(name);
} }
// register left hand side in order // register left hand side in order
order.push_back(t); order.push_back(t);
@ -126,7 +119,7 @@ AtomAssignings::add_assignment(int asgn_off, const char *str, int name_len,
// parse expression on the right // parse expression on the right
try try
{ {
expr.parse(right_len, str+right_off); expr.parse(str.substr(right_off, right_len));
} }
catch (const ParserException &e) catch (const ParserException &e)
{ {
@ -134,17 +127,14 @@ AtomAssignings::add_assignment(int asgn_off, const char *str, int name_len,
} }
// register name of the left hand side and put to lname2expr // register name of the left hand side and put to lname2expr
const char *ss = left_names.insert(buf); left_names.insert(name);
if (lname2expr.find(ss) != lname2expr.end()) if (lname2expr.find(name) != lname2expr.end())
{ {
// Prevent the occurrence of #415 // Prevent the occurrence of #415
std::cerr << "Changing the value of " << ss << " is not supported. Aborting." << std::endl; std::cerr << "Changing the value of " << name << " is not supported. Aborting." << std::endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
lname2expr[ss] = order.size()-1; lname2expr[name] = order.size()-1;
// delete name
delete [] buf;
} }
void void
@ -154,7 +144,7 @@ AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm)
// variables // variables
for (const auto & it : mm) for (const auto & it : mm)
{ {
const char *oldname = it.first; const string &oldname = it.first;
const AtomSubstitutions::Tshiftnameset &sset = it.second; const AtomSubstitutions::Tshiftnameset &sset = it.second;
if (!sset.empty()) if (!sset.empty())
{ {
@ -171,9 +161,9 @@ AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm)
// reference to the newly added formula // reference to the newly added formula
for (const auto & itt : sset) for (const auto & itt : sset)
{ {
const char *newname = itt.first; const string &newname = itt.first;
const char *nn = left_names.insert(newname); left_names.insert(newname);
lname2expr.emplace(nn, expr.nformulas()-1); lname2expr.emplace(newname, expr.nformulas()-1);
} }
} }
} }
@ -199,7 +189,7 @@ AtomAsgnEvaluator::setValues(EvalTree &et) const
double nan = std::numeric_limits<double>::quiet_NaN(); double nan = std::numeric_limits<double>::quiet_NaN();
for (int i = 0; i < aa.atoms.nvar(); i++) for (int i = 0; i < aa.atoms.nvar(); i++)
{ {
const char *ss = aa.atoms.name(i); const string &ss = aa.atoms.name(i);
int t = aa.atoms.index(ss); int t = aa.atoms.index(ss);
if (t >= 0) if (t >= 0)
{ {
@ -213,7 +203,7 @@ AtomAsgnEvaluator::setValues(EvalTree &et) const
} }
void void
AtomAsgnEvaluator::set_user_value(const char *name, double val) AtomAsgnEvaluator::set_user_value(const string &name, double val)
{ {
int t = aa.atoms.index(name); int t = aa.atoms.index(name);
if (t >= 0) if (t >= 0)
@ -238,7 +228,7 @@ AtomAsgnEvaluator::load(int i, double res)
} }
double double
AtomAsgnEvaluator::get_value(const char *name) const AtomAsgnEvaluator::get_value(const string &name) const
{ {
auto it = aa.lname2expr.find(name); auto it = aa.lname2expr.find(name);
if (it == aa.lname2expr.end()) if (it == aa.lname2expr.end())

View File

@ -14,7 +14,6 @@
namespace ogp namespace ogp
{ {
class AtomAsgnEvaluator; class AtomAsgnEvaluator;
/** This class represents atom assignments used in parameters /** This class represents atom assignments used in parameters
@ -26,7 +25,7 @@ namespace ogp
{ {
friend class AtomAsgnEvaluator; friend class AtomAsgnEvaluator;
protected: protected:
using Tvarintmap = std::map<const char *, int, ltstr>; using Tvarintmap = std::map<string, int>;
/** All atoms which should be sufficient for formulas at the /** All atoms which should be sufficient for formulas at the
* right hand sides. The atoms should be filled with names * right hand sides. The atoms should be filled with names
* (preregistered). This is a responsibility of the caller. */ * (preregistered). This is a responsibility of the caller. */
@ -53,14 +52,14 @@ namespace ogp
AtomAssignings(const AtomAssignings &aa, StaticAtoms &a); AtomAssignings(const AtomAssignings &aa, StaticAtoms &a);
virtual ~AtomAssignings() = default; virtual ~AtomAssignings() = default;
/** Parse the assignments from the given string. */ /** Parse the assignments from the given string. */
void parse(int length, const char *stream); void parse(const string &stream);
/** Process a syntax error from bison. */ /** Process a syntax error from bison. */
void error(const char *mes); void error(string mes);
/** Add an assignment of the given name to the given /** Add an assignment of the given name to the given
* double. Can be called by a user, anytime. */ * double. Can be called by a user, anytime. */
void add_assignment_to_double(const char *name, double val); void add_assignment_to_double(string name, double val);
/** Add an assignment. Called from assign.y. */ /** Add an assignment. Called from assign.y. */
void add_assignment(int asgn_off, const char *str, int name_len, void add_assignment(int asgn_off, const string &str, int name_len,
int right_off, int right_len); int right_off, int right_len);
/** This applies old2new map (possibly from atom /** This applies old2new map (possibly from atom
* substitutions) to this object. It registers new variables * substitutions) to this object. It registers new variables
@ -107,7 +106,7 @@ namespace ogp
* parameters are known and should be set to their values. In * parameters are known and should be set to their values. In
* constrast endogenous variables are set initially to NaNs by * constrast endogenous variables are set initially to NaNs by
* AtomValues::setValues. */ * AtomValues::setValues. */
void set_user_value(const char *name, double val); void set_user_value(const string &name, double val);
/** This sets the result of i-th expression in aa to res, and /** 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, * also checks whether the i-th expression is an atom. If so,
* it sets the value of the atom in ogp::EvalTree * it sets the value of the atom in ogp::EvalTree
@ -126,9 +125,8 @@ namespace ogp
/** This returns a value for a given name. If the name is not /** This returns a value for a given name. If the name is not
* found among atoms, or there is no assignment for the atom, * found among atoms, or there is no assignment for the atom,
* NaN is returned. */ * NaN is returned. */
double get_value(const char *name) const; double get_value(const string &name) const;
}; };
}; };
#endif #endif

View File

@ -9,46 +9,24 @@ using namespace ogp;
AtomSubstitutions::AtomSubstitutions(const AtomSubstitutions &as, const FineAtoms &oa, AtomSubstitutions::AtomSubstitutions(const AtomSubstitutions &as, const FineAtoms &oa,
FineAtoms &na) FineAtoms &na)
: old_atoms(oa), new_atoms(na) : new2old(as.new2old), old2new(as.old2new), old_atoms(oa), new_atoms(na)
{ {
const NameStorage &ns = na.get_name_storage();
// fill new2old
for (const auto & it : as.new2old)
new2old.emplace(ns.query(it.first),
Tshiftname(ns.query(it.second.first),
it.second.second));
// fill old2new
for (const auto & it : as.old2new)
{
Tshiftnameset sset;
for (const auto & itt : it.second)
sset.emplace(ns.query(itt.first), itt.second);
old2new.emplace(ns.query(it.first), sset);
}
} }
void void
AtomSubstitutions::add_substitution(const char *newname, const char *oldname, int tshift) AtomSubstitutions::add_substitution(string newname, string oldname, int tshift)
{ {
// make sure the storage is from the new_atoms
newname = new_atoms.get_name_storage().query(newname);
oldname = new_atoms.get_name_storage().query(oldname);
if (!newname || !oldname)
throw ogu::Exception(__FILE__, __LINE__,
"Bad newname or oldname in AtomSubstitutions::add_substitution");
// insert to new2old map // insert to new2old map
new2old.emplace(newname, Tshiftname(oldname, tshift)); new2old.emplace(newname, Tshiftname(oldname, tshift));
// insert to old2new map // insert to old2new map
auto it = old2new.find(oldname); auto it = old2new.find(oldname);
if (it != old2new.end()) if (it != old2new.end())
it->second.emplace(newname, -tshift); it->second.emplace(std::move(newname), -tshift);
else else
{ {
Tshiftnameset snset; Tshiftnameset snset;
snset.emplace(newname, -tshift); snset.emplace(std::move(newname), -tshift);
old2new.emplace(oldname, snset); old2new.emplace(std::move(oldname), snset);
} }
// put to info // put to info
@ -59,14 +37,14 @@ void
AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot) AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot)
{ {
// create an external ordering of new_atoms from old_atoms // create an external ordering of new_atoms from old_atoms
const vector<const char *> &oa_ext = old_atoms.get_allvar(); const vector<string> &oa_ext = old_atoms.get_allvar();
vector<const char *> na_ext; vector<string> na_ext;
for (auto oname : oa_ext) for (const auto &oname : oa_ext)
{ {
// add the old name itself // add the old name itself
na_ext.push_back(oname); na_ext.push_back(oname);
// add all new names derived from the old name // add all new names derived from the old name
Toldnamemap::const_iterator it = old2new.find(oname); auto it = old2new.find(oname);
if (it != old2new.end()) if (it != old2new.end())
for (const auto & itt : it->second) for (const auto & itt : it->second)
na_ext.push_back(itt.first); na_ext.push_back(itt.first);
@ -76,8 +54,8 @@ AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot)
new_atoms.parsing_finished(ot, na_ext); new_atoms.parsing_finished(ot, na_ext);
} }
const char * string
AtomSubstitutions::get_new4old(const char *oldname, int tshift) const AtomSubstitutions::get_new4old(const string &oldname, int tshift) const
{ {
auto it = old2new.find(oldname); auto it = old2new.find(oldname);
if (it != old2new.end()) if (it != old2new.end())
@ -87,7 +65,7 @@ AtomSubstitutions::get_new4old(const char *oldname, int tshift) const
if (itt.second == -tshift) if (itt.second == -tshift)
return itt.first; return itt.first;
} }
return nullptr; return "";
} }
void void
@ -106,25 +84,25 @@ AtomSubstitutions::print() const
void void
SAtoms::substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as) SAtoms::substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as)
{ {
const char *name; string name;
int mlead, mlag; int mlead, mlag;
endovarspan(mlead, mlag); endovarspan(mlead, mlag);
// substitute all endo lagged more than 1 // substitute all endo lagged more than 1
while (name = findEndoWithLeadInInterval(mlag, -2)) while (!(name = findEndoWithLeadInInterval(mlag, -2)).empty())
makeAuxVariables(name, -1, -2, mlag, fp, as); makeAuxVariables(name, -1, -2, mlag, fp, as);
// substitute all endo leaded more than 1 // substitute all endo leaded more than 1
while (name = findEndoWithLeadInInterval(2, mlead)) while (!(name = findEndoWithLeadInInterval(2, mlead)).empty())
makeAuxVariables(name, 1, 2, mlead, fp, as); makeAuxVariables(name, 1, 2, mlead, fp, as);
exovarspan(mlead, mlag); exovarspan(mlead, mlag);
// substitute all lagged exo // substitute all lagged exo
while (name = findExoWithLeadInInterval(mlag, -1)) while (!(name = findExoWithLeadInInterval(mlag, -1)).empty())
makeAuxVariables(name, -1, -1, mlag, fp, as); makeAuxVariables(name, -1, -1, mlag, fp, as);
// substitute all leaded exo // substitute all leaded exo
while (name = findExoWithLeadInInterval(1, mlead)) while (!(name = findExoWithLeadInInterval(1, mlead)).empty())
makeAuxVariables(name, 1, 1, mlead, fp, as); makeAuxVariables(name, 1, 1, mlead, fp, as);
// notify that substitution have been finished // notify that substitution have been finished
@ -134,30 +112,30 @@ SAtoms::substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as)
void void
SAtoms::substituteAllLagsAndExo1Leads(FormulaParser &fp, AtomSubstitutions &as) SAtoms::substituteAllLagsAndExo1Leads(FormulaParser &fp, AtomSubstitutions &as)
{ {
const char *name; string name;
int mlead, mlag; int mlead, mlag;
endovarspan(mlead, mlag); endovarspan(mlead, mlag);
// substitute all endo lagged more than 1 // substitute all endo lagged more than 1
while (name = findEndoWithLeadInInterval(mlag, -2)) while (!(name = findEndoWithLeadInInterval(mlag, -2)).empty())
makeAuxVariables(name, -1, -2, mlag, fp, as); makeAuxVariables(name, -1, -2, mlag, fp, as);
exovarspan(mlead, mlag); exovarspan(mlead, mlag);
// substitute all lagged exo // substitute all lagged exo
while (name = findExoWithLeadInInterval(mlag, -1)) while (!(name = findExoWithLeadInInterval(mlag, -1)).empty())
makeAuxVariables(name, -1, -1, mlag, fp, as); makeAuxVariables(name, -1, -1, mlag, fp, as);
// substitute all leaded exo by 1 // substitute all leaded exo by 1
while (name = findExoWithLeadInInterval(1, 1)) while (!(name = findExoWithLeadInInterval(1, 1)).empty())
makeAuxVariables(name, 1, 1, 1, fp, as); makeAuxVariables(name, 1, 1, 1, fp, as);
// notify that substitution have been finished // notify that substitution have been finished
as.substitutions_finished(order_type); as.substitutions_finished(order_type);
} }
const char * string
SAtoms::findNameWithLeadInInterval(const vector<const char *> &names, SAtoms::findNameWithLeadInInterval(const vector<string> &names,
int ll1, int ll2) const int ll1, int ll2) const
{ {
for (auto name : names) for (auto name : names)
@ -165,7 +143,7 @@ SAtoms::findNameWithLeadInInterval(const vector<const char *> &names,
auto it = vars.find(name); auto it = vars.find(name);
if (it != vars.end()) if (it != vars.end())
{ {
const DynamicAtoms::Tlagmap &lmap = (*it).second; const DynamicAtoms::Tlagmap &lmap = it->second;
for (auto itt : lmap) for (auto itt : lmap)
if (itt.first >= ll1 && itt.first <= ll2) if (itt.first >= ll1 && itt.first <= ll2)
return name; return name;
@ -173,29 +151,29 @@ SAtoms::findNameWithLeadInInterval(const vector<const char *> &names,
} }
// nothing found // nothing found
return nullptr; return "";
} }
void void
SAtoms::attemptAuxName(const char *str, int ll, string &out) const SAtoms::attemptAuxName(const string &str, int ll, string &out) const
{ {
char c = (ll >= 0) ? ((ll == 0) ? 'e' : 'p') : 'm'; char c = (ll >= 0) ? ((ll == 0) ? 'e' : 'p') : 'm';
string absll = std::to_string(std::abs(ll)); string absll = std::to_string(std::abs(ll));
int iter = 1; int iter = 1;
do do
{ {
out = string(str) + '_'; out = str + '_';
for (int i = 0; i < iter; i++) for (int i = 0; i < iter; i++)
out += c; out += c;
if (ll != 0) if (ll != 0)
out += absll; out += absll;
iter++; iter++;
} }
while (varnames.query(out.c_str())); while (varnames.query(out));
} }
void void
SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead, SAtoms::makeAuxVariables(const string &name, int step, int start, int limit_lead,
FormulaParser &fp, AtomSubstitutions &as) FormulaParser &fp, AtomSubstitutions &as)
{ {
if (!(step == 1 || step == -1)) if (!(step == 1 || step == -1))
@ -220,10 +198,7 @@ SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead,
// index of atom "a(-2)" // index of atom "a(-2)"
int tprev = index(name, start-step); int tprev = index(name, start-step);
if (tprev == -1) if (tprev == -1)
{ tprev = fp.add_nulary(name + '(' + std::to_string(start-step) + ')');
string tmp = string{name} + '(' + std::to_string(start-step) + ')';
tprev = fp.add_nulary(tmp.c_str());
}
int ll = start; int ll = start;
do do
@ -234,17 +209,15 @@ SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead,
// check if "a_m2(0)" has not been already created (with // check if "a_m2(0)" has not been already created (with
// different step), in this case do not add equation "a_m2(0) // different step), in this case do not add equation "a_m2(0)
// = a(-2)" // = a(-2)"
const char *newname; string newname, newname_str;
string newname_str;
int taux; int taux;
if (!(newname = as.get_new4old(name, ll-step))) if ((newname = as.get_new4old(name, ll-step)).empty())
{ {
attemptAuxName(name, ll-step, newname_str); attemptAuxName(name, ll-step, newname_str);
newname = newname_str.c_str(); newname = newname_str;
register_uniq_endo(newname); register_uniq_endo(newname);
newname = varnames.query(newname); newname = varnames.query(newname);
string tmp = string{newname} + "(0)"; taux = fp.add_nulary(newname + "(0)");
taux = fp.add_nulary(tmp.c_str());
// add to substitutions // add to substitutions
as.add_substitution(newname, name, ll-step); as.add_substitution(newname, name, ll-step);
@ -269,8 +242,7 @@ SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead,
if (t == -1) if (t == -1)
{ {
// no "a(-3)", make t <-> a_m2(-1) // no "a(-3)", make t <-> a_m2(-1)
string tmp = string{newname} + '(' + std::to_string(step) + ')'; t = fp.add_nulary(newname + '(' + std::to_string(step) + ')');
t = fp.add_nulary(tmp.c_str());
} }
else else
{ {

View File

@ -30,10 +30,10 @@ namespace ogp
class AtomSubstitutions class AtomSubstitutions
{ {
public: public:
using Tshiftname = pair<const char *, int>; using Tshiftname = pair<string, int>;
using Tshiftmap = map<const char *, Tshiftname, ltstr>; using Tshiftmap = map<string, Tshiftname>;
using Tshiftnameset = set<Tshiftname>; using Tshiftnameset = set<Tshiftname>;
using Toldnamemap = map<const char *, Tshiftnameset, ltstr>; using Toldnamemap = map<string, Tshiftnameset>;
protected: protected:
/** This maps a new name to a shifted old name. This is, one /** This maps a new name to a shifted old name. This is, one
* entry looks as "a_m3 ==> a(-3)", saying that a variable * entry looks as "a_m3 ==> a(-3)", saying that a variable
@ -76,15 +76,15 @@ namespace ogp
* substitution method of the new atoms. This says that the * substitution method of the new atoms. This says that the
* new name, say "a_m3" is a substitution of old name "a" * new name, say "a_m3" is a substitution of old name "a"
* shifted by -3. */ * shifted by -3. */
void add_substitution(const char *newname, const char *oldname, int tshift); void add_substitution(string newname, string oldname, int tshift);
/** This is called when all substitutions are finished. This /** This is called when all substitutions are finished. This
* forms the new external ordering of the new atoms and calls * forms the new external ordering of the new atoms and calls
* parsing_finished() for the new atoms with the given ordering type. */ * parsing_finished() for the new atoms with the given ordering type. */
void substitutions_finished(VarOrdering::ord_type ot); void substitutions_finished(VarOrdering::ord_type ot);
/** Returns a new name for old name and given tshift. For "a" /** Returns a new name for old name and given tshift. For "a"
* and tshift=-3, it returns "a_m3". If there is no such * and tshift=-3, it returns "a_m3". If there is no such
* substitution, it returns NULL. */ * substitution, it returns an empty string. */
const char *get_new4old(const char *oldname, int tshift) const; string get_new4old(const string &oldname, int tshift) const;
/** Return new2old. */ /** Return new2old. */
const Tshiftmap & const Tshiftmap &
get_new2old() const get_new2old() const
@ -127,7 +127,6 @@ namespace ogp
{ {
} }
SAtoms(const SAtoms &sa) = default; SAtoms(const SAtoms &sa) = default;
~SAtoms() override = default;
/** This substitutes all lags and leads for all exogenous and /** This substitutes all lags and leads for all exogenous and
* all lags and leads greater than 1 for all endogenous * all lags and leads greater than 1 for all endogenous
* variables. This is useful for perfect foresight problems * variables. This is useful for perfect foresight problems
@ -140,14 +139,14 @@ namespace ogp
protected: protected:
/** This finds an endogenous variable name which occurs between /** This finds an endogenous variable name which occurs between
* ll1 and ll2 included. */ * ll1 and ll2 included. */
const char * string
findEndoWithLeadInInterval(int ll1, int ll2) const findEndoWithLeadInInterval(int ll1, int ll2) const
{ {
return findNameWithLeadInInterval(get_endovars(), ll1, ll2); return findNameWithLeadInInterval(get_endovars(), ll1, ll2);
} }
/** This finds an exogenous variable name which occurs between /** This finds an exogenous variable name which occurs between
* ll1 and ll2 included. */ * ll1 and ll2 included. */
const char * string
findExoWithLeadInInterval(int ll1, int ll2) const findExoWithLeadInInterval(int ll1, int ll2) const
{ {
return findNameWithLeadInInterval(get_exovars(), ll1, ll2); return findNameWithLeadInInterval(get_exovars(), ll1, ll2);
@ -159,7 +158,7 @@ namespace ogp
* such form is already registered, one more character (either * such form is already registered, one more character (either
* 'p' or 'm') is added and the test is performed again. The * 'p' or 'm') is added and the test is performed again. The
* resulting name is returned in a string out. */ * resulting name is returned in a string out. */
void attemptAuxName(const char *str, int ll, string &out) const; void attemptAuxName(const string &str, int ll, string &out) const;
/** This makes auxiliary variables to eliminate all leads/lags /** This makes auxiliary variables to eliminate all leads/lags
* greater/less than or equal to start up to the limit_lead * greater/less than or equal to start up to the limit_lead
@ -170,13 +169,13 @@ namespace ogp
* atoms are created in this object. The auxiliary equations * atoms are created in this object. The auxiliary equations
* are created in the given FormulaParser. The value of step * are created in the given FormulaParser. The value of step
* is allowed to be either -1 (lags) or +1 (leads). */ * is allowed to be either -1 (lags) or +1 (leads). */
void makeAuxVariables(const char *name, int step, int start, int limit_lead, void makeAuxVariables(const string &name, int step, int start, int limit_lead,
FormulaParser &fp, AtomSubstitutions &as); FormulaParser &fp, AtomSubstitutions &as);
private: private:
/** This is a worker routine for findEndoWithLeadInInterval /** This is a worker routine for findEndoWithLeadInInterval
* and findExoWithLeadInInterval. */ * and findExoWithLeadInInterval. */
const char *findNameWithLeadInInterval(const vector<const char *> &names, string findNameWithLeadInInterval(const vector<string> &names,
int ll1, int ll2) const; int ll1, int ll2) const;
}; };

View File

@ -1,36 +0,0 @@
/* -*- C++ -*- */
%{
// Copyright © 2007-2011, Ondra Kamenik
#include "location.hh"
#include "csv_tab.hh"
#define YY_USER_ACTION SET_LLOC(csv_);
%}
%option nounput
%option noyy_top_state
%option yylineno
%option prefix="csv_"
%option never-interactive
%%
, {return COMMA;}
\n {return NEWLINE;}
\r\n {return NEWLINE;}
[^,\n\r]+ {return ITEM;}
%%
int
csv_wrap()
{
return 1;
}
void
csv__destroy_buffer(void* p)
{
csv__delete_buffer(static_cast<YY_BUFFER_STATE>(p));
}

View File

@ -1,53 +0,0 @@
// -*- C++ -*-
%code requires
{
#include "location.hh"
#define CSV_LTYPE ogp::location_type
}
%code
{
#include "csv_parser.hh"
void csv_error(const char*);
int csv_lex();
extern ogp::CSVParser* csv_parser;
}
%union
{
char* string;
int integer;
}
%token COMMA NEWLINE BOGUS
%token <string> ITEM
%define api.prefix {csv_};
%locations
%defines
%define parse.error verbose
%%
csv_file : line_list | line_list line;
line_list : line_list line newline | line newline | line_list newline | newline;
line : line comma | line item | item | comma;
comma : COMMA {csv_parser->nextcol();};
newline : NEWLINE {csv_parser->nextrow();};
item : ITEM {csv_parser->item(@1.off, @1.ll);};
%%
void
csv_error(const char* mes)
{
csv_parser->csv_error(mes);
}

View File

@ -1,45 +0,0 @@
#include "csv_parser.hh"
#include "parser_exception.hh"
#include "location.hh"
#include "csv_tab.hh"
#include <memory>
#include <algorithm>
using namespace ogp;
/** A global symbol for passing info to the CSVParser from
* csv_parse(). */
CSVParser *csv_parser;
/** The declaration of functions defined in csv_ll.cc and
* csv_tab.cc generated from csv.lex and csv.y. */
void *csv__scan_buffer(char *, unsigned int);
void csv__destroy_buffer(void *);
int csv_parse();
extern ogp::location_type csv_lloc;
void
CSVParser::csv_error(const char *mes)
{
throw ParserException(mes, csv_lloc.off);
}
void
CSVParser::csv_parse(int length, const char *str)
{
// allocate temporary buffer and parse
auto buffer = std::make_unique<char[]>(length+2);
std::copy_n(str, length, buffer.get());
buffer[length] = '\0';
buffer[length+1] = '\0';
csv_lloc.off = 0;
csv_lloc.ll = 0;
parsed_string = buffer.get();
void *p = csv__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
csv_parser = this;
::csv_parse();
csv__destroy_buffer(p);
parsed_string = nullptr;
}

View File

@ -1,58 +0,0 @@
// Copyright © 2007, Ondra Kamenik
// $Id$
#ifndef OGP_CSV_PARSER
#define OGP_CSV_PARSER
namespace ogp
{
class CSVParserPeer
{
public:
virtual ~CSVParserPeer()
= default;
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(nullptr)
{
}
CSVParser(const CSVParser &csvp)
= default;
virtual ~CSVParser()
= default;
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);
}
};
};
#endif

View File

@ -7,51 +7,13 @@
using namespace ogp; using namespace ogp;
NameStorage::NameStorage(const NameStorage &stor) void
NameStorage::insert(string name)
{ {
for (auto i : stor.name_store) if (!query(name))
{ {
auto *str = new char[strlen(i)+1]; name_store.push_back(name);
strcpy(str, i); name_set.insert(std::move(name));
name_store.push_back(str);
name_set.insert(str);
}
}
NameStorage::~NameStorage()
{
while (name_store.size() > 0)
{
delete [] name_store.back();
name_store.pop_back();
}
}
const char *
NameStorage::query(const char *name) const
{
auto it = name_set.find(name);
if (it == name_set.end())
return nullptr;
else
return (*it);
}
const char *
NameStorage::insert(const char *name)
{
auto it = name_set.find(name);
if (it == name_set.end())
{
auto *str = new char[strlen(name)+1];
strcpy(str, name);
name_store.push_back(str);
name_set.insert(str);
return str;
}
else
{
return (*it);
} }
} }
@ -104,15 +66,12 @@ Constants::get_constant_value(int t) const
if (it != cmap.end()) if (it != cmap.end())
return it->second; return it->second;
else else
{ throw ogu::Exception(__FILE__, __LINE__,
throw ogu::Exception(__FILE__, __LINE__, "Tree index is not constant in Constants::get_constant_value");
"Tree index is not constant in Constants::get_constant_value");
return 0;
}
} }
int int
Constants::check(const char *str) const Constants::check(const string &str) const
{ {
double d = std::stod(str); double d = std::stod(str);
auto it = cinvmap.find(d); auto it = cinvmap.find(d);
@ -126,26 +85,11 @@ void
Constants::print() const Constants::print() const
{ {
for (const auto &it : cmap) for (const auto &it : cmap)
printf("$%d: %8.4g\n", it.first, it.second); std::cout << "$" << it.first << ": " << it.second << "\n";
}
DynamicAtoms::DynamicAtoms() = default;
DynamicAtoms::DynamicAtoms(const DynamicAtoms &da)
: Constants(da),
varnames(da.varnames), vars(), indices(),
nv(da.nv), minlag(da.minlag), maxlead(da.maxlead)
{
// copy vars
for (const auto & var : da.vars)
vars.emplace(varnames.query(var.first), var.second);
// copy indices
for (auto indice : da.indices)
indices.emplace(indice.first, varnames.query(indice.second));
} }
int int
DynamicAtoms::check(const char *name) const DynamicAtoms::check(const string &name) const
{ {
if (is_string_constant(name)) if (is_string_constant(name))
return Constants::check(name); return Constants::check(name);
@ -154,12 +98,12 @@ DynamicAtoms::check(const char *name) const
} }
int int
DynamicAtoms::check_variable(const char *name) const DynamicAtoms::check_variable(const string &name) const
{ {
string str; string str;
int ll; int ll;
parse_variable(name, str, ll); parse_variable(name, str, ll);
auto it = vars.find(str.c_str()); auto it = vars.find(str);
if (it != vars.end()) if (it != vars.end())
{ {
@ -172,7 +116,7 @@ DynamicAtoms::check_variable(const char *name) const
} }
void void
DynamicAtoms::assign(const char *name, int t) DynamicAtoms::assign(const string &name, int t)
{ {
if (is_string_constant(name)) if (is_string_constant(name))
assign_constant(name, t); assign_constant(name, t);
@ -181,7 +125,7 @@ DynamicAtoms::assign(const char *name, int t)
} }
void void
DynamicAtoms::assign_constant(const char *name, int t) DynamicAtoms::assign_constant(const string &name, int t)
{ {
double val = std::stod(name); double val = std::stod(name);
add_constant(t, val); add_constant(t, val);
@ -190,19 +134,19 @@ DynamicAtoms::assign_constant(const char *name, int t)
// parse the name and then call assing_variable(varname, ll, t) // parse the name and then call assing_variable(varname, ll, t)
void void
DynamicAtoms::assign_variable(const char *name, int t) DynamicAtoms::assign_variable(const string &name, int t)
{ {
int ll; int ll;
string str; string str;
parse_variable(name, str, ll); parse_variable(name, str, ll);
// here str is just name without lead/lag // here str is just name without lead/lag
const char *ss = varnames.insert(str.c_str()); varnames.insert(str);
assign_variable(ss, ll, t); assign_variable(str, ll, t);
} }
void void
DynamicAtoms::assign_variable(const char *varname, int ll, int t) DynamicAtoms::assign_variable(const string &varname, int ll, int t)
{ {
if (indices.end() != indices.find(t)) if (indices.end() != indices.find(t))
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
@ -226,14 +170,12 @@ DynamicAtoms::assign_variable(const char *varname, int ll, int t)
indices.emplace(t, varname); indices.emplace(t, varname);
nv++; nv++;
if (ll < minlag) minlag = std::min(ll, minlag);
minlag = ll; maxlead = std::max(ll, maxlead);
if (ll > maxlead)
maxlead = ll;
} }
void void
DynamicAtoms::unassign_variable(const char *varname, int ll, int t) DynamicAtoms::unassign_variable(const string &varname, int ll, int t)
{ {
auto it = vars.find(varname); auto it = vars.find(varname);
if (it != vars.end()) if (it != vars.end())
@ -315,7 +257,7 @@ DynamicAtoms::varspan(int t, int &mlead, int &mlag) const
} }
void void
DynamicAtoms::varspan(const char *name, int &mlead, int &mlag) const DynamicAtoms::varspan(const string &name, int &mlead, int &mlag) const
{ {
auto it = vars.find(name); auto it = vars.find(name);
if (vars.end() == it) if (vars.end() == it)
@ -332,11 +274,11 @@ DynamicAtoms::varspan(const char *name, int &mlead, int &mlag) const
} }
void void
DynamicAtoms::varspan(const vector<const char *> &names, int &mlead, int &mlag) const DynamicAtoms::varspan(const vector<string> &names, int &mlead, int &mlag) const
{ {
mlead = std::numeric_limits<int>::min(); mlead = std::numeric_limits<int>::min();
mlag = std::numeric_limits<int>::max(); mlag = std::numeric_limits<int>::max();
for (auto name : names) for (const auto &name : names)
{ {
int lag, lead; int lag, lead;
varspan(name, lead, lag); varspan(name, lead, lag);
@ -348,11 +290,11 @@ DynamicAtoms::varspan(const vector<const char *> &names, int &mlead, int &mlag)
bool bool
DynamicAtoms::is_named_atom(int t) const DynamicAtoms::is_named_atom(int t) const
{ {
return (indices.end() != indices.find(t)); return indices.end() != indices.find(t);
} }
int int
DynamicAtoms::index(const char *name, int ll) const DynamicAtoms::index(const string &name, int ll) const
{ {
auto it = vars.find(name); auto it = vars.find(name);
if (vars.end() != it) if (vars.end() != it)
@ -366,14 +308,13 @@ DynamicAtoms::index(const char *name, int ll) const
} }
bool bool
DynamicAtoms::is_referenced(const char *name) const DynamicAtoms::is_referenced(const string &name) const
{ {
auto it = vars.find(name); return vars.find(name) != vars.end();
return it != vars.end();
} }
const DynamicAtoms::Tlagmap & const DynamicAtoms::Tlagmap &
DynamicAtoms::lagmap(const char *name) const DynamicAtoms::lagmap(const string &name) const
{ {
auto it = vars.find(name); auto it = vars.find(name);
if (vars.end() == it) if (vars.end() == it)
@ -383,7 +324,7 @@ DynamicAtoms::lagmap(const char *name) const
return it->second; return it->second;
} }
const char * const string &
DynamicAtoms::name(int t) const DynamicAtoms::name(int t) const
{ {
auto it = indices.find(t); auto it = indices.find(t);
@ -396,7 +337,7 @@ DynamicAtoms::name(int t) const
int int
DynamicAtoms::lead(int t) const DynamicAtoms::lead(int t) const
{ {
const char *nam = name(t); const string &nam = name(t);
const Tlagmap &lmap = lagmap(nam); const Tlagmap &lmap = lagmap(nam);
auto it = lmap.begin(); auto it = lmap.begin();
while (it != lmap.end() && it->second != t) while (it != lmap.end() && it->second != t)
@ -410,32 +351,32 @@ DynamicAtoms::lead(int t) const
void void
DynamicAtoms::print() const DynamicAtoms::print() const
{ {
printf("names:\n"); std::cout << "names:\n";
varnames.print(); varnames.print();
printf("constants:\n"); std::cout << "constants:\n";
Constants::print(); Constants::print();
printf("variables:\n"); std::cout << "variables:\n";
for (const auto & var : vars) for (const auto & var : vars)
{ {
const Tlagmap &lmap = var.second; const Tlagmap &lmap = var.second;
for (auto itt : lmap) for (auto itt : lmap)
printf("$%d: %s(%d)\n", itt.second, var.first, itt.first); std::cout << "$" << itt.second << ": " << var.first << "(" << itt.first << ")\n";
} }
printf("indices:\n"); std::cout << "indices:\n";
for (auto indice : indices) for (auto indice : indices)
printf(u8"t=%d ⇒ %s\n", indice.first, indice.second); std::cout << "t=" << indice.first << u8"" << indice.second << "\n";
} }
/** Note that the str has been parsed by the lexicographic /** Note that the str has been parsed by the lexicographic
* analyzer. It can be either a variable or a double. So it is easy to * analyzer. It can be either a variable or a double. So it is easy to
* recognize it by the first character. */ * recognize it by the first character. */
bool bool
DynamicAtoms::is_string_constant(const char *str) DynamicAtoms::is_string_constant(const string &str)
{ {
return str[0] == '.' || str[0] == '-' || (str[0] >= '0' && str[0] <= '9'); return str[0] == '.' || str[0] == '-' || (str[0] >= '0' && str[0] <= '9');
} }
VarOrdering::VarOrdering(const VarOrdering &vo, const vector<const char *> &vnames, VarOrdering::VarOrdering(const VarOrdering &vo, const vector<string> &vnames,
const DynamicAtoms &a) const DynamicAtoms &a)
: n_stat(vo.n_stat), n_pred(vo.n_pred), n_both(vo.n_both), n_forw(vo.n_forw), : n_stat(vo.n_stat), n_pred(vo.n_pred), n_both(vo.n_both), n_forw(vo.n_forw),
der_atoms(vo.der_atoms), positions(vo.positions), der_atoms(vo.der_atoms), positions(vo.positions),
@ -446,8 +387,7 @@ VarOrdering::VarOrdering(const VarOrdering &vo, const vector<const char *> &vnam
bool bool
VarOrdering::check(int t) const VarOrdering::check(int t) const
{ {
auto it = positions.find(t); return positions.find(t) != positions.end();
return it != positions.end();
} }
int int
@ -455,15 +395,10 @@ VarOrdering::get_pos_of(int t) const
{ {
auto it = positions.find(t); auto it = positions.find(t);
if (it != positions.end()) if (it != positions.end())
{ return it->second;
return it->second;
}
else else
{ throw ogu::Exception(__FILE__, __LINE__,
throw ogu::Exception(__FILE__, __LINE__, "Couldn't find the tree index in VarOrdering::get_pos_of");
"Couldn't find the tree index in VarOrdering::get_pos_of");
return -1;
}
} }
void void
@ -487,7 +422,7 @@ VarOrdering::do_general(ord_type ordering)
for (unsigned int i = 0; i < varnames.size(); i++) for (unsigned int i = 0; i < varnames.size(); i++)
{ {
const char *ss = varnames[i]; const string &ss = varnames[i];
int lead; int lead;
int lag; int lag;
atoms.varspan(ss, lead, lag); atoms.varspan(ss, lead, lag);
@ -516,10 +451,8 @@ VarOrdering::do_general(ord_type ordering)
y2o_both.push_back(i); y2o_both.push_back(i);
} }
else else
{ throw ogu::Exception(__FILE__, __LINE__,
throw ogu::Exception(__FILE__, __LINE__, "A wrong lag/lead of a variable in VarOrdering::do_pbspbfbf");
"A wrong lag/lead of a variable in VarOrdering::do_pbspbfbf");
}
} }
// here we fill ords according to ordering // here we fill ords according to ordering
@ -546,11 +479,9 @@ VarOrdering::do_general(ord_type ordering)
ords[6] = &pred_minus; ords[6] = &pred_minus;
ords[7] = &both_minus; ords[7] = &both_minus;
} }
else // BEWARE: when implementing a new ordering, check also a else // BEWARE: when implementing a new ordering, check also the code below setting y2outer
{// code below setting y2outer throw ogu::Exception(__FILE__, __LINE__,
throw ogu::Exception(__FILE__, __LINE__, "Ordering not implemented in VarOrdering::do_general");
"Ordering not implemented in VarOrdering::do_general");
}
// make der_atoms and positions // make der_atoms and positions
int off = 0; int off = 0;
@ -652,18 +583,19 @@ VarOrdering::do_increasing_time()
void void
VarOrdering::print() const VarOrdering::print() const
{ {
printf("nstat=%d, npred=%d, nboth=%d, nforw=%d\n", n_stat, n_pred, n_both, n_forw); std::cout << "nstat=" << n_stat << ", npred=" << n_pred << ", nboth=" << n_both
printf("der_atoms:\n"); << ", nforw=" << n_forw << "\n"
<< "der_atoms:\n";
for (int der_atom : der_atoms) for (int der_atom : der_atoms)
printf(" %d", der_atom); std::cout << " " << der_atom;
printf("\nmap:\n"); std::cout << "\nmap:\n";
for (auto position : positions) for (auto position : positions)
printf(u8" [%d→%d]", position.first, position.second); std::cout << " [" << position.first << u8"" << position.second << "]";
printf("\ny2outer:\n"); std::cout << "\ny2outer:\n";
for (int i : y2outer) for (int i : y2outer)
printf(" %d", i); std::cout << " " << i;
printf("\nouter2y:\n"); std::cout << "\nouter2y:\n";
for (int i : outer2y) for (int i : outer2y)
printf(" %d", i); std::cout << " " << i;
printf("\n"); std::cout << "\n";
} }

View File

@ -11,7 +11,6 @@
#include <map> #include <map>
#include <set> #include <set>
#include <string> #include <string>
#include <cstring>
#include <limits> #include <limits>
#include <memory> #include <memory>
@ -22,15 +21,6 @@ namespace ogp
using std::set; using std::set;
using std::string; using std::string;
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 /** Class storing names. We will keep names of variables in
* various places, and all these pointers will point to one * various places, and all these pointers will point to one
* storage, which will be responsible for allocation and * storage, which will be responsible for allocation and
@ -41,26 +31,26 @@ namespace ogp
{ {
protected: protected:
/** Vector of names allocated, this is the storage. */ /** Vector of names allocated, this is the storage. */
vector<char *> name_store; vector<string> name_store;
/** Map useful to quickly decide if the name is already /** Map useful to quickly decide if the name is already
* allocated or not. */ * allocated or not. */
set<const char *, ltstr> name_set; set<string> name_set;
public: public:
NameStorage() = default;
NameStorage(const NameStorage &stor);
virtual ~NameStorage();
/** Query for the name. If the name has been stored, it /** Query for the name. If the name has been stored, it
* returns its address, otherwise 0. */ * true, otherwise false. */
const char *query(const char *name) const; bool
/** Insert the name if it has not been inserted yet, and query(const string &name) const
* return its new or old allocation. */ {
const char *insert(const char *name); return name_set.find(name) != name_set.end();
}
/** Insert the name if it has not been inserted yet. */
void insert(string name);
int int
num() const num() const
{ {
return static_cast<int>(name_store.size()); return static_cast<int>(name_store.size());
} }
const char * const string &
get_name(int i) const get_name(int i) const
{ {
return name_store[i]; return name_store[i];
@ -112,7 +102,7 @@ namespace ogp
/** Return -1 if the given string representation of a constant /** Return -1 if the given string representation of a constant
* is not among the constants (double represenations). If it * is not among the constants (double represenations). If it
* is, its tree index is returned. */ * is, its tree index is returned. */
int check(const char *str) const; int check(const string &str) const;
/** Debug print. */ /** Debug print. */
void print() const; void print() const;
const Tconstantmap & const Tconstantmap &
@ -141,9 +131,9 @@ namespace ogp
using Tlagmap = map<int, int>; using Tlagmap = map<int, int>;
protected: protected:
/** Definition of a type mapping names of the atoms to Tlagmap. */ /** Definition of a type mapping names of the atoms to Tlagmap. */
using Tvarmap = map<const char *, Tlagmap, ltstr>; using Tvarmap = map<string, Tlagmap>;
/** Definition of a type mapping indices of variables to the variable names. */ /** Definition of a type mapping indices of variables to the variable names. */
using Tindexmap = map<int, const char *>; using Tindexmap = map<int, string>;
/** This is just a storage for variable names, since all other /** This is just a storage for variable names, since all other
* instances of a variable name just point to the memory * instances of a variable name just point to the memory
* allocated by this object. */ * allocated by this object. */
@ -165,9 +155,7 @@ namespace ogp
int maxlead{std::numeric_limits<int>::min()}; int maxlead{std::numeric_limits<int>::min()};
public: public:
/** Construct empty DynamicAtoms. */ /** Construct empty DynamicAtoms. */
DynamicAtoms(); DynamicAtoms() = default;
DynamicAtoms(const DynamicAtoms &da);
~DynamicAtoms() override = default;
/** Check the nulary term identified by its string /** Check the nulary term identified by its string
* representation. The nulary term can be either a constant or * representation. The nulary term can be either a constant or
* a variable. If constant, -1 is returned so that it could be * a variable. If constant, -1 is returned so that it could be
@ -175,11 +163,11 @@ namespace ogp
* appeared or not. If variable, then -1 is returned only if * appeared or not. If variable, then -1 is returned only if
* the variable has not been assigned an index, otherwise the * the variable has not been assigned an index, otherwise the
* assigned index is returned. */ * assigned index is returned. */
int check(const char *name) const override; int check(const string &name) const override;
/** Assign the nulary term identified by its string /** Assign the nulary term identified by its string
* representation. This method should be called when check() * representation. This method should be called when check()
* returns -1. */ * returns -1. */
void assign(const char *name, int t) override; void assign(const string &name, int t) override;
/** Return a number of all variables. */ /** Return a number of all variables. */
int int
nvar() const override nvar() const override
@ -196,9 +184,9 @@ namespace ogp
/** Return max lead and min lag for a variable given by the /** Return max lead and min lag for a variable given by the
* name (without lead, lag). The same is valid if the variable * name (without lead, lag). The same is valid if the variable
* name cannot be found. */ * name cannot be found. */
void varspan(const char *name, int &mlead, int &mlag) const; void varspan(const string &name, int &mlead, int &mlag) const;
/** Return max lead and min lag for a vector of variables given by the names. */ /** 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; void varspan(const vector<string> &names, int &mlead, int &mlag) const;
/** Return true for all tree indices corresponding to a /** Return true for all tree indices corresponding to a
* variable in the sense of this class. (This is parameters, * variable in the sense of this class. (This is parameters,
* exo and endo). Since the semantics of 'variable' will be * exo and endo). Since the semantics of 'variable' will be
@ -207,15 +195,15 @@ namespace ogp
bool is_named_atom(int t) const; bool is_named_atom(int t) const;
/** Return index of the variable described by the variable /** Return index of the variable described by the variable
* name and lag/lead. If it doesn't exist, return -1. */ * name and lag/lead. If it doesn't exist, return -1. */
int index(const char *name, int ll) const; int index(const string &name, int ll) const;
/** Return true if a variable is referenced, i.e. it has lag /** Return true if a variable is referenced, i.e. it has lag
* map. */ * map. */
bool is_referenced(const char *name) const; bool is_referenced(const string &name) const;
/** Return the lag map for the variable name. */ /** Return the lag map for the variable name. */
const Tlagmap&lagmap(const char *name) const; const Tlagmap &lagmap(const string &name) const;
/** Return the variable name for the tree index. It throws an /** Return the variable name for the tree index. It throws an
* exception if the tree index t is not a named atom. */ * exception if the tree index t is not a named atom. */
const char *name(int t) const; const string &name(int t) const;
/** Return the lead/lag for the tree index. It throws an /** Return the lead/lag for the tree index. It throws an
* exception if the tree index t is not a named atom. */ * exception if the tree index t is not a named atom. */
int lead(int t) const; int lead(int t) const;
@ -242,25 +230,25 @@ namespace ogp
* from the varnames storage. The method checks if the * from the varnames storage. The method checks if the
* variable iwht the given lead/lag is not assigned. If so, an * variable iwht the given lead/lag is not assigned. If so, an
* exception is thrown. */ * exception is thrown. */
void assign_variable(const char *varname, int ll, int t); void assign_variable(const string &varname, int ll, int t);
/** Unassign the variable with a given lead and given tree /** Unassign the variable with a given lead and given tree
* index. The tree index is only provided as a check. An * index. The tree index is only provided as a check. An
* exception is thrown if the name, ll, and the tree index t * exception is thrown if the name, ll, and the tree index t
* are not consistent. The method also updates nv, indices, * are not consistent. The method also updates nv, indices,
* maxlead and minlag. The varname must be from the varnames * maxlead and minlag. The varname must be from the varnames
* storage. */ * storage. */
void unassign_variable(const char *varname, int ll, int t); void unassign_variable(const string &varname, int ll, int t);
/** Debug print. */ /** Debug print. */
void print() const override; void print() const override;
protected: protected:
/** Do the check for the variable. A subclass may need to /** Do the check for the variable. A subclass may need to
* reimplement this so that it could raise an error if the * reimplement this so that it could raise an error if the
* variable is not among a given list. */ * variable is not among a given list. */
virtual int check_variable(const char *name) const; virtual int check_variable(const string &name) const;
/** Assign the constant. */ /** Assign the constant. */
void assign_constant(const char *name, int t); void assign_constant(const string &name, int t);
/** Assign the variable. */ /** Assign the variable. */
void assign_variable(const char *name, int t); void assign_variable(const string &name, int t);
/** The method just updates minlag or/and maxlead. Note that /** The method just updates minlag or/and maxlead. Note that
* when assigning variables, the update is done when inserting * when assigning variables, the update is done when inserting
* to the maps, however, if removing a variable, we need to * to the maps, however, if removing a variable, we need to
@ -268,10 +256,10 @@ namespace ogp
void update_minmaxll(); void update_minmaxll();
/** The method parses the string to recover a variable name /** The method parses the string to recover a variable name
* and lag/lead ll. The variable name doesn't contain a lead/lag. */ * 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; virtual void parse_variable(const string &in, string &out, int &ll) const = 0;
public: public:
/** Return true if the str represents a double.*/ /** Return true if the str represents a double.*/
static bool is_string_constant(const char *str); static bool is_string_constant(const string &str);
}; };
/** This class is a parent of all orderings of the dynamic atoms /** This class is a parent of all orderings of the dynamic atoms
@ -336,7 +324,7 @@ namespace ogp
vector<int> y2outer; vector<int> y2outer;
/** This is just a reference for variable names to keep it /** This is just a reference for variable names to keep it
* from constructor to do_ordering() implementations. */ * from constructor to do_ordering() implementations. */
const vector<const char *> &varnames; const vector<string> &varnames;
/** This is just a reference to atoms to keep it from /** This is just a reference to atoms to keep it from
* constructor to do_ordering() implementations. */ * constructor to do_ordering() implementations. */
const DynamicAtoms &atoms; const DynamicAtoms &atoms;
@ -348,14 +336,14 @@ namespace ogp
* with their dynamic occurrences defined by the atoms. It * with their dynamic occurrences defined by the atoms. It
* calls the virtual method do_ordering which can be * calls the virtual method do_ordering which can be
* reimplemented. */ * reimplemented. */
VarOrdering(const vector<const char *> &vnames, const DynamicAtoms &a) VarOrdering(const vector<string> &vnames, const DynamicAtoms &a)
: n_stat(0), n_pred(0), n_both(0), n_forw(0), varnames(vnames), atoms(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, VarOrdering(const VarOrdering &vo, const vector<string> &vnames,
const DynamicAtoms &a); const DynamicAtoms &a);
VarOrdering(const VarOrdering &vo) = delete; VarOrdering(const VarOrdering &vo) = delete;
virtual std::unique_ptr<VarOrdering> clone(const vector<const char *> &vnames, virtual std::unique_ptr<VarOrdering> clone(const vector<string> &vnames,
const DynamicAtoms &a) const = 0; const DynamicAtoms &a) const = 0;
/** Destructor does nothing here. */ /** Destructor does nothing here. */
virtual ~VarOrdering() = default; virtual ~VarOrdering() = default;

View File

@ -9,21 +9,20 @@
using namespace ogp; using namespace ogp;
AllvarOuterOrdering::AllvarOuterOrdering(const vector<const char *> &allvar_outer, AllvarOuterOrdering::AllvarOuterOrdering(const vector<string> &allvar_outer,
const FineAtoms &a) const FineAtoms &a)
: atoms(a), allvar(), : atoms(a), allvar(),
endo2all(a.get_endovars().size(), -1), endo2all(a.get_endovars().size(), -1),
exo2all(a.get_exovars().size(), -1) exo2all(a.get_exovars().size(), -1)
{ {
// fill in the allvar from allvar_outer // fill in the allvar from allvar_outer
for (auto i : allvar_outer) for (const auto &s : allvar_outer)
{ {
const char *s = atoms.varnames.query(i); if (atoms.varnames.query(s))
if (s)
allvar.push_back(s); allvar.push_back(s);
else else
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
string("Variable ") + i + " is not a declared symbol in AllvarOuterOrdering constructor"); string("Variable ") + s + " is not a declared symbol in AllvarOuterOrdering constructor");
} }
// fill in endo2all and exo2all // fill in endo2all and exo2all
@ -62,54 +61,44 @@ AllvarOuterOrdering::AllvarOuterOrdering(const vector<const char *> &allvar_oute
AllvarOuterOrdering::AllvarOuterOrdering(const AllvarOuterOrdering &avo, AllvarOuterOrdering::AllvarOuterOrdering(const AllvarOuterOrdering &avo,
const FineAtoms &a) const FineAtoms &a)
: atoms(a), allvar(), : atoms(a), allvar(avo.allvar),
endo2all(avo.endo2all), endo2all(avo.endo2all),
exo2all(avo.exo2all) exo2all(avo.exo2all)
{ {
// fill in the allvar from avo.allvar
for (auto i : avo.allvar)
{
const char *s = atoms.varnames.query(i);
allvar.push_back(s);
}
} }
FineAtoms::FineAtoms(const FineAtoms &fa) FineAtoms::FineAtoms(const FineAtoms &fa)
: DynamicAtoms(fa), params(), endovars(), exovars(), : DynamicAtoms(fa), params(), endovars(), exovars(),
endo_order(nullptr), exo_order(nullptr), allvar_order(nullptr),
der_atoms(fa.der_atoms), der_atoms(fa.der_atoms),
endo_atoms_map(fa.endo_atoms_map), endo_atoms_map(fa.endo_atoms_map),
exo_atoms_map(fa.exo_atoms_map) exo_atoms_map(fa.exo_atoms_map)
{ {
// fill in params // fill in params
for (auto param : fa.params) for (const auto &param : fa.params)
{ {
const char *s = varnames.query(param); if (!varnames.query(param))
if (!s)
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
string("Parameter ") + param + " does not exist in FineAtoms copy cosntructor"); string("Parameter ") + param + " does not exist in FineAtoms copy cosntructor");
params.push_back(s); params.push_back(param);
param_outer_map.emplace(s, params.size()-1); param_outer_map.emplace(param, params.size()-1);
} }
// fill in endovars // fill in endovars
for (auto endovar : fa.endovars) for (const auto &endovar : fa.endovars)
{ {
const char *s = varnames.query(endovar); if (!varnames.query(endovar))
if (!s)
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
string("Endo variable ") + endovar + " does not exist in FineAtoms copy constructor"); string("Endo variable ") + endovar + " does not exist in FineAtoms copy constructor");
endovars.push_back(s); endovars.push_back(endovar);
endo_outer_map.emplace(s, endovars.size()-1); endo_outer_map.emplace(endovar, endovars.size()-1);
} }
// fill in exovars // fill in exovars
for (auto exovar : fa.exovars) for (const auto &exovar : fa.exovars)
{ {
const char *s = varnames.query(exovar); if (!varnames.query(exovar))
if (!s)
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
string("Exo variable ") + exovar + " does not exist in FineAtoms copy cosntructor"); string("Exo variable ") + exovar + " does not exist in FineAtoms copy cosntructor");
exovars.push_back(s); exovars.push_back(exovar);
exo_outer_map.emplace(s, exovars.size()-1); exo_outer_map.emplace(exovar, exovars.size()-1);
} }
if (fa.endo_order) if (fa.endo_order)
@ -123,12 +112,12 @@ FineAtoms::FineAtoms(const FineAtoms &fa)
} }
int int
FineAtoms::check_variable(const char *name) const FineAtoms::check_variable(const string &name) const
{ {
string str; string str;
int ll; int ll;
parse_variable(name, str, ll); parse_variable(name, str, ll);
if (varnames.query(str.c_str())) if (varnames.query(str))
return DynamicAtoms::check_variable(name); return DynamicAtoms::check_variable(name);
else else
{ {
@ -152,7 +141,7 @@ FineAtoms::parsing_finished(VarOrdering::ord_type ot)
// by default, concatenate outer endo and outer exo and make it as // by default, concatenate outer endo and outer exo and make it as
// allvar outer: // allvar outer:
vector<const char *> allvar_tmp; vector<string> allvar_tmp;
allvar_tmp.insert(allvar_tmp.end(), endovars.begin(), endovars.end()); allvar_tmp.insert(allvar_tmp.end(), endovars.begin(), endovars.end());
allvar_tmp.insert(allvar_tmp.end(), exovars.begin(), exovars.end()); allvar_tmp.insert(allvar_tmp.end(), exovars.begin(), exovars.end());
@ -161,13 +150,13 @@ FineAtoms::parsing_finished(VarOrdering::ord_type ot)
void void
FineAtoms::parsing_finished(VarOrdering::ord_type ot, FineAtoms::parsing_finished(VarOrdering::ord_type ot,
const vector<const char *> allvar) const vector<string> &allvar)
{ {
make_internal_orderings(ot); make_internal_orderings(ot);
allvar_order = std::make_unique<AllvarOuterOrdering>(allvar, *this); allvar_order = std::make_unique<AllvarOuterOrdering>(allvar, *this);
} }
const vector<const char *> & const vector<string> &
FineAtoms::get_allvar() const FineAtoms::get_allvar() const
{ {
if (!allvar_order) if (!allvar_order)
@ -367,7 +356,7 @@ FineAtoms::get_exo_atoms_map() const
} }
int int
FineAtoms::name2outer_param(const char *name) const FineAtoms::name2outer_param(const string &name) const
{ {
auto it = param_outer_map.find(name); auto it = param_outer_map.find(name);
if (it == param_outer_map.end()) if (it == param_outer_map.end())
@ -377,7 +366,7 @@ FineAtoms::name2outer_param(const char *name) const
} }
int int
FineAtoms::name2outer_endo(const char *name) const FineAtoms::name2outer_endo(const string &name) const
{ {
auto it = endo_outer_map.find(name); auto it = endo_outer_map.find(name);
if (it == endo_outer_map.end()) if (it == endo_outer_map.end())
@ -387,7 +376,7 @@ FineAtoms::name2outer_endo(const char *name) const
} }
int int
FineAtoms::name2outer_exo(const char *name) const FineAtoms::name2outer_exo(const string &name) const
{ {
auto it = exo_outer_map.find(name); auto it = exo_outer_map.find(name);
if (it == exo_outer_map.end()) if (it == exo_outer_map.end())
@ -397,7 +386,7 @@ FineAtoms::name2outer_exo(const char *name) const
} }
int int
FineAtoms::name2outer_allvar(const char *name) const FineAtoms::name2outer_allvar(const string &name) const
{ {
if (!allvar_order) if (!allvar_order)
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
@ -419,33 +408,33 @@ FineAtoms::name2outer_allvar(const char *name) const
} }
void void
FineAtoms::register_uniq_endo(const char *name) FineAtoms::register_uniq_endo(string name)
{ {
if (varnames.query(name)) if (varnames.query(name))
throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.", 0); throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.", 0);
const char *ss = varnames.insert(name); varnames.insert(name);
endovars.push_back(ss); endovars.push_back(name);
endo_outer_map.emplace(ss, endovars.size()-1); endo_outer_map.emplace(std::move(name), endovars.size()-1);
} }
void void
FineAtoms::register_uniq_exo(const char *name) FineAtoms::register_uniq_exo(string name)
{ {
if (varnames.query(name)) if (varnames.query(name))
throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.", 0); throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.", 0);
const char *ss = varnames.insert(name); varnames.insert(name);
exovars.push_back(ss); exovars.push_back(name);
exo_outer_map.emplace(ss, exovars.size()-1); exo_outer_map.emplace(std::move(name), exovars.size()-1);
} }
void void
FineAtoms::register_uniq_param(const char *name) FineAtoms::register_uniq_param(string name)
{ {
if (varnames.query(name)) if (varnames.query(name))
throw ogp::ParserException(string("Parameter <")+name+"> is not unique.", 0); throw ogp::ParserException(string("Parameter <")+name+"> is not unique.", 0);
const char *ss = varnames.insert(name); varnames.insert(name);
params.push_back(ss); params.push_back(name);
param_outer_map.emplace(ss, params.size()-1); param_outer_map.emplace(std::move(name), params.size()-1);
} }
void void
@ -508,24 +497,24 @@ FineAtoms::print() const
DynamicAtoms::print(); DynamicAtoms::print();
if (endo_order) if (endo_order)
{ {
printf("Endo ordering:\n"); std::cout << "Endo ordering:\n";
endo_order->print(); endo_order->print();
} }
else else
printf("Endo ordering not created.\n"); std::cout << "Endo ordering not created.\n";
if (exo_order) if (exo_order)
{ {
printf("Exo ordering:\n"); std::cout << "Exo ordering:\n";
exo_order->print(); exo_order->print();
} }
else else
printf("Exo ordering not created.\n"); std::cout << "Exo ordering not created.\n";
printf("endo atoms map:\n"); std::cout << "endo atoms map:\n";
for (unsigned int i = 0; i < endo_atoms_map.size(); i++) for (unsigned int i = 0; i < endo_atoms_map.size(); i++)
printf(u8"%d → %d\n", i, endo_atoms_map[i]); std::cout << i << u8"" << endo_atoms_map[i] << "\n";
printf("exo atoms map:\n"); std::cout << "exo atoms map:\n";
for (unsigned int i = 0; i < exo_atoms_map.size(); i++) for (unsigned int i = 0; i < exo_atoms_map.size(); i++)
printf(u8"%d → %d\n", i, exo_atoms_map[i]); std::cout << i << u8"" << exo_atoms_map[i] << "\n";
} }

View File

@ -23,17 +23,17 @@ namespace ogp
class EndoVarOrdering1 : public VarOrdering class EndoVarOrdering1 : public VarOrdering
{ {
public: public:
EndoVarOrdering1(const vector<const char *> &vnames, const DynamicAtoms &a) EndoVarOrdering1(const vector<string> &vnames, const DynamicAtoms &a)
: VarOrdering(vnames, a) : VarOrdering(vnames, a)
{ {
} }
EndoVarOrdering1(const EndoVarOrdering1 &vo, const vector<const char *> &vnames, EndoVarOrdering1(const EndoVarOrdering1 &vo, const vector<string> &vnames,
const DynamicAtoms &a) const DynamicAtoms &a)
: VarOrdering(vo, vnames, a) : VarOrdering(vo, vnames, a)
{ {
} }
std::unique_ptr<VarOrdering> std::unique_ptr<VarOrdering>
clone(const vector<const char *> &vnames, const DynamicAtoms &a) const override clone(const vector<string> &vnames, const DynamicAtoms &a) const override
{ {
return std::make_unique<EndoVarOrdering1>(*this, vnames, a); return std::make_unique<EndoVarOrdering1>(*this, vnames, a);
} }
@ -51,17 +51,17 @@ namespace ogp
class EndoVarOrdering2 : public VarOrdering class EndoVarOrdering2 : public VarOrdering
{ {
public: public:
EndoVarOrdering2(const vector<const char *> &vnames, const DynamicAtoms &a) EndoVarOrdering2(const vector<string> &vnames, const DynamicAtoms &a)
: VarOrdering(vnames, a) : VarOrdering(vnames, a)
{ {
} }
EndoVarOrdering2(const EndoVarOrdering2 &vo, const vector<const char *> &vnames, EndoVarOrdering2(const EndoVarOrdering2 &vo, const vector<string> &vnames,
const DynamicAtoms &a) const DynamicAtoms &a)
: VarOrdering(vo, vnames, a) : VarOrdering(vo, vnames, a)
{ {
} }
std::unique_ptr<VarOrdering> std::unique_ptr<VarOrdering>
clone(const vector<const char *> &vnames, const DynamicAtoms &a) const override clone(const vector<string> &vnames, const DynamicAtoms &a) const override
{ {
return std::make_unique<EndoVarOrdering2>(*this, vnames, a); return std::make_unique<EndoVarOrdering2>(*this, vnames, a);
} }
@ -78,17 +78,17 @@ namespace ogp
class ExoVarOrdering : public VarOrdering class ExoVarOrdering : public VarOrdering
{ {
public: public:
ExoVarOrdering(const vector<const char *> &vnames, const DynamicAtoms &a) ExoVarOrdering(const vector<string> &vnames, const DynamicAtoms &a)
: VarOrdering(vnames, a) : VarOrdering(vnames, a)
{ {
} }
ExoVarOrdering(const ExoVarOrdering &vo, const vector<const char *> &vnames, ExoVarOrdering(const ExoVarOrdering &vo, const vector<string> &vnames,
const DynamicAtoms &a) const DynamicAtoms &a)
: VarOrdering(vo, vnames, a) : VarOrdering(vo, vnames, a)
{ {
} }
std::unique_ptr<VarOrdering> std::unique_ptr<VarOrdering>
clone(const vector<const char *> &vnames, const DynamicAtoms &a) const override clone(const vector<string> &vnames, const DynamicAtoms &a) const override
{ {
return std::make_unique<ExoVarOrdering>(*this, vnames, a); return std::make_unique<ExoVarOrdering>(*this, vnames, a);
} }
@ -109,12 +109,12 @@ namespace ogp
{ {
protected: protected:
/** Type for a map mapping a variable name to an integer. */ /** Type for a map mapping a variable name to an integer. */
using Tvarintmap = map<const char *, int, ltstr>; using Tvarintmap = map<string, int>;
/** Reference to atoms. */ /** Reference to atoms. */
const FineAtoms &atoms; const FineAtoms &atoms;
/** The vector of all endo and exo variables in outer /** The vector of all endo and exo variables in outer
* ordering. The pointers point to storage in atoms. */ * ordering. The pointers point to storage in atoms. */
vector<const char *> allvar; vector<string> allvar;
/** The mapping from outer endogenous to outer all. For /** The mapping from outer endogenous to outer all. For
* example endo2all[0] is the order of the first outer * example endo2all[0] is the order of the first outer
* endogenous variable in the allvar ordering. */ * endogenous variable in the allvar ordering. */
@ -129,7 +129,7 @@ namespace ogp
* arbitrary storage, the storage is transformed to the atoms * arbitrary storage, the storage is transformed to the atoms
* storage. An exception is thrown if either the list is not * storage. An exception is thrown if either the list is not
* exhaustive, or some string is not a variable. */ * exhaustive, or some string is not a variable. */
AllvarOuterOrdering(const vector<const char *> &allvar_outer, const FineAtoms &a); AllvarOuterOrdering(const vector<string> &allvar_outer, const FineAtoms &a);
/** Copy constructor using the storage of provided atoms. */ /** Copy constructor using the storage of provided atoms. */
AllvarOuterOrdering(const AllvarOuterOrdering &allvar_outer, const FineAtoms &a); AllvarOuterOrdering(const AllvarOuterOrdering &allvar_outer, const FineAtoms &a);
/** Return endo2all mapping. */ /** Return endo2all mapping. */
@ -145,7 +145,7 @@ namespace ogp
return exo2all; return exo2all;
} }
/** Return the allvar ordering. */ /** Return the allvar ordering. */
const vector<const char *> & const vector<string> &
get_allvar() const get_allvar() const
{ {
return allvar; return allvar;
@ -175,23 +175,23 @@ namespace ogp
{ {
friend class AllvarOuterOrdering; friend class AllvarOuterOrdering;
protected: protected:
using Tvarintmap = map<const char *, int, ltstr>; using Tvarintmap = map<string, int>;
private: private:
/** The vector of parameters names. The order gives the order /** The vector of parameters names. The order gives the order
* the data is communicated with outside world. */ * the data is communicated with outside world. */
vector<const char *> params; vector<string> params;
/** A map mapping a name of a parameter to an index in the outer /** A map mapping a name of a parameter to an index in the outer
* ordering. */ * ordering. */
Tvarintmap param_outer_map; Tvarintmap param_outer_map;
/** The vector of endogenous variables. This defines the order /** The vector of endogenous variables. This defines the order
* like parameters. */ * like parameters. */
vector<const char *> endovars; vector<string> endovars;
/** A map mapping a name of an endogenous variable to an index /** A map mapping a name of an endogenous variable to an index
* in the outer ordering. */ * in the outer ordering. */
Tvarintmap endo_outer_map; Tvarintmap endo_outer_map;
/** The vector of exogenous variables. Also defines the order /** The vector of exogenous variables. Also defines the order
* like parameters and endovars. */ * like parameters and endovars. */
vector<const char *> exovars; vector<string> exovars;
/** A map mapping a name of an exogenous variable to an index /** A map mapping a name of an exogenous variable to an index
* in the outer ordering. */ * in the outer ordering. */
Tvarintmap exo_outer_map; Tvarintmap exo_outer_map;
@ -237,7 +237,7 @@ namespace ogp
* variable is declared by inserting it to * variable is declared by inserting it to
* DynamicAtoms::varnames. This is a responsibility of a * DynamicAtoms::varnames. This is a responsibility of a
* subclass. */ * subclass. */
int check_variable(const char *name) const override; int check_variable(const string &name) const override;
/** This calculates min lag and max lead of endogenous variables. */ /** This calculates min lag and max lead of endogenous variables. */
void void
endovarspan(int &mlead, int &mlag) const endovarspan(int &mlead, int &mlag) const
@ -254,19 +254,19 @@ namespace ogp
* one exogenous variable occurs. */ * one exogenous variable occurs. */
int num_exo_periods() const; int num_exo_periods() const;
/** Return an (external) ordering of parameters. */ /** Return an (external) ordering of parameters. */
const vector<const char *> & const vector<string> &
get_params() const get_params() const
{ {
return params; return params;
} }
/** Return an external ordering of endogenous variables. */ /** Return an external ordering of endogenous variables. */
const vector<const char *> & const vector<string> &
get_endovars() const get_endovars() const
{ {
return endovars; return endovars;
} }
/** Return an external ordering of exogenous variables. */ /** Return an external ordering of exogenous variables. */
const vector<const char *> & const vector<string> &
get_exovars() const get_exovars() const
{ {
return exovars; return exovars;
@ -282,20 +282,20 @@ namespace ogp
* inputing a different outer ordering of all variables. The * inputing a different outer ordering of all variables. The
* ordering is input as a list of strings, their storage can * ordering is input as a list of strings, their storage can
* be arbitrary. */ * be arbitrary. */
void parsing_finished(VarOrdering::ord_type ot, const vector<const char *> avo); void parsing_finished(VarOrdering::ord_type ot, const vector<string> &avo);
/** Return the external ordering of all variables (endo and /** Return the external ordering of all variables (endo and
* exo). This is either the second argument to * exo). This is either the second argument to
* parsing_finished or the default external ordering. This * parsing_finished or the default external ordering. This
* must be called only after parsing_finished. */ * must be called only after parsing_finished. */
const vector<const char *>&get_allvar() const; const vector<string> &get_allvar() const;
/** Return the map from outer ordering of endo variables to /** Return the map from outer ordering of endo variables to
* the allvar ordering. This must be called only after * the allvar ordering. This must be called only after
* parsing_finished. */ * parsing_finished. */
const vector<int>&outer_endo2all() const; const vector<int> &outer_endo2all() const;
/** Return the map from outer ordering of exo variables to /** Return the map from outer ordering of exo variables to
* the allvar ordering. This must be called only after * the allvar ordering. This must be called only after
* parsing_finished. */ * parsing_finished. */
const vector<int>&outer_exo2all() const; const vector<int> &outer_exo2all() const;
/** Return the atoms with respect to which we are going to /** Return the atoms with respect to which we are going to
* differentiate. This must be called after * differentiate. This must be called after
* parsing_finished. */ * parsing_finished. */
@ -340,20 +340,20 @@ namespace ogp
/** Return an index in the outer ordering of a given /** Return an index in the outer ordering of a given
* parameter. An exception is thrown if the name is not a * parameter. An exception is thrown if the name is not a
* parameter. */ * parameter. */
int name2outer_param(const char *name) const; int name2outer_param(const string &name) const;
/** Return an index in the outer ordering of a given /** Return an index in the outer ordering of a given
* endogenous variable. An exception is thrown if the name is not a * endogenous variable. An exception is thrown if the name is not a
* and endogenous variable. */ * and endogenous variable. */
int name2outer_endo(const char *name) const; int name2outer_endo(const string &name) const;
/** Return an index in the outer ordering of a given /** Return an index in the outer ordering of a given
* exogenous variable. An exception is thrown if the name is not a * exogenous variable. An exception is thrown if the name is not a
* and exogenous variable. */ * and exogenous variable. */
int name2outer_exo(const char *name) const; int name2outer_exo(const string &name) const;
/** Return an index in the outer ordering of all variables /** Return an index in the outer ordering of all variables
* (endo and exo) for a given name. An exception is thrown if * (endo and exo) for a given name. An exception is thrown if
* the name is not a variable. This must be called only after * the name is not a variable. This must be called only after
* parsing_finished(). */ * parsing_finished(). */
int name2outer_allvar(const char *name) const; int name2outer_allvar(const string &name) const;
/** Return the number of endogenous variables at time t-1, these are state /** Return the number of endogenous variables at time t-1, these are state
* variables. */ * variables. */
int int
@ -389,17 +389,17 @@ namespace ogp
* calls defines the endo outer ordering. The method is * calls defines the endo outer ordering. The method is
* virtual, since a superclass may want to do some additional * virtual, since a superclass may want to do some additional
* action. */ * action. */
virtual void register_uniq_endo(const char *name); virtual void register_uniq_endo(string name);
/** Register unique exogenous variable name. The order of /** Register unique exogenous variable name. The order of
* calls defines the exo outer ordering. The method is * calls defines the exo outer ordering. The method is
* virtual, since a superclass may want to do somem additional * virtual, since a superclass may want to do somem additional
* action. */ * action. */
virtual void register_uniq_exo(const char *name); virtual void register_uniq_exo(string name);
/** Register unique parameter name. The order of calls defines /** Register unique parameter name. The order of calls defines
* the param outer ordering. The method is * the param outer ordering. The method is
* virtual, since a superclass may want to do somem additional * virtual, since a superclass may want to do somem additional
* action. */ * action. */
virtual void register_uniq_param(const char *name); virtual void register_uniq_param(string name);
/** Debug print. */ /** Debug print. */
void print() const override; void print() const override;
private: private:

View File

@ -10,8 +10,9 @@
%code %code
{ {
#include "formula_parser.hh" #include "formula_parser.hh"
#include <string>
void fmla_error(const char*); void fmla_error(std::string);
int fmla_lex(); int fmla_lex();
extern ogp::FormulaParser* fparser; extern ogp::FormulaParser* fparser;
} }
@ -76,7 +77,7 @@ extern ogp::FormulaParser* fparser;
%% %%
void void
fmla_error(const char* s) fmla_error(std::string s)
{ {
fparser->error(s); fparser->error(std::move(s));
} }

View File

@ -65,7 +65,7 @@ FormulaParser::add_unary(code_t code, int t)
} }
int int
FormulaParser::add_nulary(const char *str) FormulaParser::add_nulary(const string &str)
{ {
int t = -1; int t = -1;
try try
@ -116,7 +116,7 @@ FormulaParser *fparser;
/** The declarations of functions defined in formula_ll.cc and /** The declarations of functions defined in formula_ll.cc and
* formula_tab.cc generated from formula.lex and formula.y */ * formula_tab.cc generated from formula.lex and formula.y */
void *fmla__scan_buffer(char *, size_t); void *fmla__scan_string(const char *);
void fmla__destroy_buffer(void *); void fmla__destroy_buffer(void *);
int fmla_parse(); int fmla_parse();
extern location_type fmla_lloc; extern location_type fmla_lloc;
@ -126,24 +126,20 @@ extern location_type fmla_lloc;
* the pointer returned from fmla_scan_buffer must be freed at the * the pointer returned from fmla_scan_buffer must be freed at the
* end. */ * end. */
void void
FormulaParser::parse(int length, const char *stream) FormulaParser::parse(const string &stream)
{ {
auto buffer = std::make_unique<char[]>(length+2);
std::copy_n(stream, length, buffer.get());
buffer[length] = '\0';
buffer[length+1] = '\0';
fmla_lloc.off = 0; fmla_lloc.off = 0;
fmla_lloc.ll = 0; fmla_lloc.ll = 0;
void *p = fmla__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2); void *p = fmla__scan_string(stream.c_str());
fparser = this; fparser = this;
fmla_parse(); fmla_parse();
fmla__destroy_buffer(p); fmla__destroy_buffer(p);
} }
void void
FormulaParser::error(const char *mes) const FormulaParser::error(string mes) const
{ {
throw ParserException(mes, fmla_lloc.off); throw ParserException(std::move(mes), fmla_lloc.off);
} }
int int
@ -173,12 +169,12 @@ FormulaParser::print() const
atoms.print(); atoms.print();
for (int formula : formulas) for (int formula : formulas)
{ {
printf("formula %d:\n", formula); std::cout << "formula " << formula << ":\n";
otree.print_operation(formula); otree.print_operation(formula);
} }
for (unsigned int i = 0; i < ders.size(); i++) for (unsigned int i = 0; i < ders.size(); i++)
{ {
printf("derivatives for the formula %d:\n", formulas[i]); std::cout << "derivatives for the formula " << formulas[i] << ":\n";
ders[i]->print(otree); ders[i]->print(otree);
} }
} }
@ -261,9 +257,9 @@ FormulaDerivatives::print(const OperationTree &otree) const
{ {
for (const auto & it : ind2der) for (const auto & it : ind2der)
{ {
printf("derivative "); std::cout << "derivative ";
it.first.print(); it.first.print();
printf(" is formula %d\n", tder[it.second]); std::cout << " is formula " << tder[it.second] << '\n';
otree.print_operation(tder[it.second]); otree.print_operation(tder[it.second]);
} }
} }
@ -409,10 +405,10 @@ FoldMultiIndex::offset() const
void void
FoldMultiIndex::print() const FoldMultiIndex::print() const
{ {
printf("["); std::cout << "[";
for (int i = 0; i < ord; i++) for (int i = 0; i < ord; i++)
printf("%d ", data[i]); std::cout << data[i] << ' ';
printf("]"); std::cout << "]";
} }
int int

View File

@ -25,11 +25,11 @@ namespace ogp
* yet. The method can raise an exception, if the Atoms * yet. The method can raise an exception, if the Atoms
* implementation is strict and the name is not among * implementation is strict and the name is not among
* prescribed possible values. */ * prescribed possible values. */
virtual int check(const char *name) const = 0; virtual int check(const std::string &name) const = 0;
/** This method assigns an internal index to the nulary term /** This method assigns an internal index to the nulary term
* described by the name. The internal index is allocated by * described by the name. The internal index is allocated by
* OperationTree class. */ * OperationTree class. */
virtual void assign(const char *name, int t) = 0; virtual void assign(const std::string &name, int t) = 0;
/** Returns a number of variables which will be used for /** Returns a number of variables which will be used for
* differentiations. */ * differentiations. */
virtual int nvar() const = 0; virtual int nvar() const = 0;
@ -174,7 +174,7 @@ namespace ogp
* string. The Atoms are consulted for uniquness and are given * string. The Atoms are consulted for uniquness and are given
* an internal index generated by the OperationTree. This is * an internal index generated by the OperationTree. This is
* the channel through which the Atoms are filled. */ * the channel through which the Atoms are filled. */
int add_nulary(const char *str); int add_nulary(const std::string &str);
/** Adds a derivative to the tree. This just calls /** Adds a derivative to the tree. This just calls
* OperationTree::add_derivative. */ * OperationTree::add_derivative. */
@ -228,9 +228,9 @@ namespace ogp
/** Parse a given string containing one or more formulas. The /** Parse a given string containing one or more formulas. The
* formulas are parsed and added to the OperationTree and to * formulas are parsed and added to the OperationTree and to
* the formulas vector. */ * the formulas vector. */
void parse(int length, const char *stream); void parse(const std::string &stream);
/** Processes a syntax error from bison. */ /** Processes a syntax error from bison. */
void error(const char *mes) const; void error(std::string mes) const;
/** Differentiate all the formulas up to the given order. The /** Differentiate all the formulas up to the given order. The
* variables with respect to which the derivatives are taken * variables with respect to which the derivatives are taken
* are obtained by Atoms::variables(). If the derivates exist, * are obtained by Atoms::variables(). If the derivates exist,

View File

@ -2,10 +2,12 @@
%{ %{
// Copyright © 2006-2011, Ondra Kamenik // Copyright © 2006-2011, Ondra Kamenik
#include <string>
#include "location.hh" #include "location.hh"
#include "matrix_tab.hh" #include "matrix_tab.hh"
extern void matrix_error(const char*); extern void matrix_error(std::string);
#define YY_USER_ACTION SET_LLOC(matrix_); #define YY_USER_ACTION SET_LLOC(matrix_);
%} %}
@ -43,9 +45,7 @@ extern void matrix_error(const char*);
} }
. { . {
char mes[300]; matrix_error(std::string{"Unrecognized character "} + matrix_text);
sprintf(mes, "Unrecognized character %s", matrix_text);
matrix_error(mes);
} }
%% %%

View File

@ -11,7 +11,7 @@
{ {
#include "matrix_parser.hh" #include "matrix_parser.hh"
void matrix_error(const char*); void matrix_error(std::string);
int matrix_lex(); int matrix_lex();
extern ogp::MatrixParser* mparser; extern ogp::MatrixParser* mparser;
} }
@ -63,9 +63,9 @@ one_row : NEW_ROW {mparser->start_row();} lod;
%% %%
void void
matrix_error(const char* s) matrix_error(std::string s)
{ {
mparser->error(s); mparser->error(std::move(s));
} }

View File

@ -7,7 +7,6 @@
#include "location.hh" #include "location.hh"
#include "matrix_tab.hh" #include "matrix_tab.hh"
#include <memory>
#include <algorithm> #include <algorithm>
using namespace ogp; using namespace ogp;
@ -18,26 +17,22 @@ MatrixParser *mparser;
/** The declaration of functions defined in matrix_ll.cc and /** The declaration of functions defined in matrix_ll.cc and
* matrix_tab.cc generated from matrix.lex and matrix.y. */ * matrix_tab.cc generated from matrix.lex and matrix.y. */
void *matrix__scan_buffer(char *, size_t); void *matrix__scan_string(const char *);
void matrix__destroy_buffer(void *); void matrix__destroy_buffer(void *);
int matrix_parse(); int matrix_parse();
extern ogp::location_type matrix_lloc; extern ogp::location_type matrix_lloc;
void void
MatrixParser::parse(int length, const char *stream) MatrixParser::parse(const string &stream)
{ {
// reinitialize the object // reinitialize the object
data.clear(); data.clear();
row_lengths.clear(); row_lengths.clear();
nc = 0; nc = 0;
// allocate temporary buffer and parse // allocate temporary buffer and parse
auto buffer = std::make_unique<char[]>(length+2);
std::copy_n(stream, length, buffer.get());
buffer[length] = '\0';
buffer[length+1] = '\0';
matrix_lloc.off = 0; matrix_lloc.off = 0;
matrix_lloc.ll = 0; matrix_lloc.ll = 0;
void *p = matrix__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2); void *p = matrix__scan_string(stream.c_str());
mparser = this; mparser = this;
matrix_parse(); matrix_parse();
matrix__destroy_buffer(p); matrix__destroy_buffer(p);
@ -60,9 +55,9 @@ MatrixParser::start_row()
} }
void void
MatrixParser::error(const char *mes) const MatrixParser::error(string mes) const
{ {
throw ParserException(mes, matrix_lloc.off); throw ParserException(std::move(mes), matrix_lloc.off);
} }
int int

View File

@ -6,6 +6,7 @@
#define OGP_MATRIX_PARSER #define OGP_MATRIX_PARSER
#include <vector> #include <vector>
#include <string>
namespace ogp namespace ogp
{ {
@ -48,7 +49,7 @@ namespace ogp
return nc; return nc;
} }
/** Parses a given data. This initializes the object data. */ /** Parses a given data. This initializes the object data. */
void parse(int length, const char *stream); void parse(const std::string &stream);
/** Adds newly read item. This should be called from bison /** Adds newly read item. This should be called from bison
* parser. */ * parser. */
void add_item(double v); void add_item(double v);
@ -56,7 +57,7 @@ namespace ogp
* parser. */ * parser. */
void start_row(); void start_row();
/** Process a parse error from the parser. */ /** Process a parse error from the parser. */
void error(const char *mes) const; void error(std::string mes) const;
/** Return begin iterator. */ /** Return begin iterator. */
MPIterator begin() const; MPIterator begin() const;
/** Return end iterator. */ /** Return end iterator. */

View File

@ -1,31 +0,0 @@
// Copyright © 2006, Ondra Kamenik
// $Id: namelist.cpp 42 2007-01-22 21:53:24Z ondra $
#include "namelist.hh"
#include <memory>
#include <algorithm>
using namespace ogp;
/** A global symbol for passing info to NameListParser from its
* parser. */
NameListParser *name_list_parser;
void *namelist__scan_buffer(char *, unsigned int);
void namelist__destroy_buffer(void *);
void namelist_parse();
void
NameListParser::namelist_parse(int length, const char *stream)
{
auto buffer = std::make_unique<char[]>(length+2);
std::copy_n(str, length, buffer.get());
buffer[length] = '\0';
buffer[length+1] = '\0';
void *p = namelist__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
name_list_parser = this;
::namelist_parse();
namelist__destroy_buffer(p);
}

View File

@ -1,29 +0,0 @@
// Copyright © 2007, Ondra Kamenik
// $Id: namelist.h 107 2007-05-10 22:35:04Z ondra $
#ifndef OGP_NAMELIST
#define OGP_NAMELIST
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() = default;
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

@ -1,53 +0,0 @@
/* -*- C++ -*- */
%{
#include "location.hh"
#include "namelist_tab.hh"
#define YY_USER_ACTION SET_LLOC(namelist_);
%}
%option nounput
%option noyy_top_state
%option stack
%option prefix="namelist_"
%option never-interactive
%x CMT
%%
/* comments */
<*>"/*" {yy_push_state(CMT);}
<CMT>[^*\n]*
<CMT>"*"+[^*/\n]*
<CMT>"*"+"/" {yy_pop_state();}
<CMT>[\n]
"//".*\n
/* initial spaces or tabs are ignored */
[ \t\r\n\0]
/* names */
[A-Za-z_][A-Za-z0-9_]* {
namelist_lval.string = namelist_text;
return NAME;
}
, {return COMMA;}
. {
namelist_lval.character = namelist_text[0];
return CHARACTER;
}
%%
int
namelist_wrap()
{
return 1;
}
void
namelist__destroy_buffer(void* p)
{
namelist__delete_buffer(static_cast<YY_BUFFER_STATE>(p));
}

View File

@ -1,48 +0,0 @@
// -*- C++ -*-
// Copyright © 2007-2011, Ondra Kamenik
%code requires
{
#include "location.hh"
#define NAMELIST_LTYPE ogp::location_type
}
%code
{
#include "namelist.hh"
void namelist_error(const char*);
int namelist_lex();
extern ogp::NameListParser* name_list_parser;
}
%union
{
int integer;
char *string;
char character;
}
%token COMMA CHARACTER
%token <string> NAME;
%define api.prefix {namelist_}
%locations
%defines
%define parse.error verbose
%%
namelist : namelist NAME {name_list_parser->add_name($2);}
| namelist COMMA NAME {name_list_parser->add_name($3);}
| NAME {name_list_parser->add_name($1);}
;
%%
void
namelist_error(const char* mes)
{
name_list_parser->namelist_error(mes);
}

View File

@ -7,32 +7,6 @@
using namespace ogp; using namespace ogp;
StaticAtoms::StaticAtoms(const StaticAtoms &a)
: Atoms(), Constants(a), varnames(a.varnames),
varorder(), vars(), indices()
{
// fill varorder
for (auto i : a.varorder)
{
const char *s = varnames.query(i);
varorder.push_back(s);
}
// fill vars
for (auto var : a.vars)
{
const char *s = varnames.query(var.first);
vars.emplace(s, var.second);
}
// fill indices
for (auto indice : a.indices)
{
const char *s = varnames.query(indice.second);
indices.emplace(indice.first, s);
}
}
void void
StaticAtoms::import_atoms(const DynamicAtoms &da, OperationTree &otree, Tintintmap &tmap) StaticAtoms::import_atoms(const DynamicAtoms &da, OperationTree &otree, Tintintmap &tmap)
{ {
@ -40,14 +14,14 @@ StaticAtoms::import_atoms(const DynamicAtoms &da, OperationTree &otree, Tintintm
for (int i = 0; i < da.get_name_storage().num(); i++) for (int i = 0; i < da.get_name_storage().num(); i++)
{ {
const char *name = da.get_name_storage().get_name(i); const string &name = da.get_name_storage().get_name(i);
register_name(name); register_name(name);
int tnew = otree.add_nulary(); int tnew = otree.add_nulary();
assign(name, tnew); assign(name, tnew);
if (da.is_referenced(name)) if (da.is_referenced(name))
{ {
const DynamicAtoms::Tlagmap &lmap = da.lagmap(name); const DynamicAtoms::Tlagmap &lmap = da.lagmap(name);
for (auto it : lmap) for (const auto &it : lmap)
{ {
int told = it.second; int told = it.second;
tmap.emplace(told, tnew); tmap.emplace(told, tnew);
@ -57,7 +31,7 @@ StaticAtoms::import_atoms(const DynamicAtoms &da, OperationTree &otree, Tintintm
} }
int int
StaticAtoms::check(const char *name) const StaticAtoms::check(const string &name) const
{ {
if (DynamicAtoms::is_string_constant(name)) if (DynamicAtoms::is_string_constant(name))
return Constants::check(name); return Constants::check(name);
@ -66,7 +40,7 @@ StaticAtoms::check(const char *name) const
} }
int int
StaticAtoms::index(const char *name) const StaticAtoms::index(const string &name) const
{ {
auto it = vars.find(name); auto it = vars.find(name);
if (it == vars.end()) if (it == vars.end())
@ -75,18 +49,8 @@ StaticAtoms::index(const char *name) const
return it->second; return it->second;
} }
const char *
StaticAtoms::inv_index(int t) const
{
auto it = indices.find(t);
if (it == indices.end())
return nullptr;
else
return it->second;
}
void void
StaticAtoms::assign(const char *name, int t) StaticAtoms::assign(const string &name, int t)
{ {
if (DynamicAtoms::is_string_constant(name)) if (DynamicAtoms::is_string_constant(name))
{ {
@ -95,9 +59,9 @@ StaticAtoms::assign(const char *name, int t)
} }
else else
{ {
const char *ss = varnames.insert(name); varnames.insert(name);
vars.emplace(ss, t); vars.emplace(name, t);
indices.emplace(t, ss); indices.emplace(t, name);
} }
} }
@ -105,26 +69,26 @@ vector<int>
StaticAtoms::variables() const StaticAtoms::variables() const
{ {
vector<int> res; vector<int> res;
for (auto var : vars) for (const auto &var : vars)
res.push_back(var.second); res.push_back(var.second);
return res; return res;
} }
void void
StaticAtoms::register_name(const char *name) StaticAtoms::register_name(string name)
{ {
const char *ss = varnames.insert(name); varnames.insert(name);
varorder.push_back(ss); varorder.push_back(std::move(name));
} }
void void
StaticAtoms::print() const StaticAtoms::print() const
{ {
printf("constants:\n"); std::cout << "constants:\n";
Constants::print(); Constants::print();
printf("variable names:\n"); std::cout << "variable names:\n";
varnames.print(); varnames.print();
printf("map to tree indices:\n"); std::cout << "map to tree indices:\n";
for (auto var : vars) for (auto var : vars)
printf(u8"%s\t\t%d\n", var.first, var.second); std::cout << var.first << u8"\t\t" << var.second << "\n";
} }

View File

@ -12,12 +12,12 @@ namespace ogp
class StaticAtoms : public Atoms, public Constants class StaticAtoms : public Atoms, public Constants
{ {
protected: protected:
using Tvarmap = map<const char *, int, ltstr>; using Tvarmap = map<string, int>;
using Tinvmap = map<int, const char *>; using Tinvmap = map<int, string>;
/** Storage for names. */ /** Storage for names. */
NameStorage varnames; NameStorage varnames;
/** Outer order of variables. */ /** Outer order of variables. */
vector<const char *> varorder; vector<string> varorder;
/** This is the map mapping a variable name to the tree /** This is the map mapping a variable name to the tree
* index. */ * index. */
Tvarmap vars; Tvarmap vars;
@ -25,11 +25,7 @@ namespace ogp
* variable name. */ * variable name. */
Tinvmap indices; Tinvmap indices;
public: public:
StaticAtoms() : Atoms(), Constants(), varnames(), varorder(), vars() StaticAtoms() = default;
{
}
/* Copy constructor. */
StaticAtoms(const StaticAtoms &a);
/** Conversion from DynamicAtoms. This takes all atoms from /** Conversion from DynamicAtoms. This takes all atoms from
* the DynamicAtoms and adds its static version. The new tree * the DynamicAtoms and adds its static version. The new tree
* indices are allocated in the passed OperationTree. Whole * indices are allocated in the passed OperationTree. Whole
@ -51,10 +47,10 @@ namespace ogp
* constant is registered in Constants, it returns -1 * constant is registered in Constants, it returns -1
* otherwise. If the name is not constant, it returns result * otherwise. If the name is not constant, it returns result
* from check_variable, which is implemented by a subclass. */ * from check_variable, which is implemented by a subclass. */
int check(const char *name) const override; int check(const string &name) const override;
/** This assigns a given tree index to the variable name. The /** This assigns a given tree index to the variable name. The
* name should have been checked before the call. */ * name should have been checked before the call. */
void assign(const char *name, int t) override; void assign(const string &name, int t) override;
int int
nvar() const override nvar() const override
{ {
@ -63,12 +59,9 @@ namespace ogp
/** This returns a vector of all variables. */ /** This returns a vector of all variables. */
vector<int> variables() const override; vector<int> variables() const override;
/** This returns a tree index of the given variable. */ /** This returns a tree index of the given variable. */
int index(const char *name) const; int index(const string &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.) */ /** This returns a name in a outer ordering. (There is no other ordering.) */
const char * const string &
name(int i) const name(int i) const
{ {
return varorder[i]; return varorder[i];
@ -79,7 +72,7 @@ namespace ogp
* this, for example, to ensure uniqueness of the * this, for example, to ensure uniqueness of the
* name. However, this method should be always called in * name. However, this method should be always called in
* overriding methods to do the registering job. */ * overriding methods to do the registering job. */
virtual void register_name(const char *name); virtual void register_name(string name);
/** Return the name storage to allow querying to other /** Return the name storage to allow querying to other
* classes. */ * classes. */
const NameStorage & const NameStorage &
@ -91,7 +84,7 @@ namespace ogp
/** This checks the variable. The implementing subclass might /** This checks the variable. The implementing subclass might
* want to throw an exception if the variable has not been * want to throw an exception if the variable has not been
* registered. */ * registered. */
virtual int check_variable(const char *name) const = 0; virtual int check_variable(const string &name) const = 0;
}; };
}; };

View File

@ -9,37 +9,6 @@
using namespace ogp; using namespace ogp;
StaticFineAtoms::StaticFineAtoms(const StaticFineAtoms &sfa)
: StaticAtoms(sfa),
params(), param_outer_map(),
endovars(), endo_outer_map(),
exovars(), exo_outer_map(),
der_atoms(sfa.der_atoms),
endo_atoms_map(sfa.endo_atoms_map),
exo_atoms_map(sfa.exo_atoms_map)
{
for (unsigned int i = 0; i < sfa.params.size(); i++)
{
const char *name = varnames.query(sfa.params[i]);
params.push_back(name);
param_outer_map.emplace(name, i);
}
for (unsigned int i = 0; i < sfa.endovars.size(); i++)
{
const char *name = varnames.query(sfa.endovars[i]);
endovars.push_back(name);
endo_outer_map.emplace(name, i);
}
for (unsigned int i = 0; i < sfa.exovars.size(); i++)
{
const char *name = varnames.query(sfa.exovars[i]);
exovars.push_back(name);
exo_outer_map.emplace(name, i);
}
}
void void
StaticFineAtoms::import_atoms(const FineAtoms &fa, OperationTree &otree, Tintintmap &tmap) StaticFineAtoms::import_atoms(const FineAtoms &fa, OperationTree &otree, Tintintmap &tmap)
{ {
@ -49,18 +18,18 @@ StaticFineAtoms::import_atoms(const FineAtoms &fa, OperationTree &otree, Tintint
// respective vectors, the names are already in the storage // respective vectors, the names are already in the storage
// parameters // parameters
const vector<const char *> &fa_params = fa.get_params(); auto &fa_params = fa.get_params();
for (auto fa_param : fa_params) for (const auto &fa_param : fa_params)
register_param(fa_param); register_param(fa_param);
// endogenous // endogenous
const vector<const char *> &fa_endovars = fa.get_endovars(); auto &fa_endovars = fa.get_endovars();
for (auto fa_endovar : fa_endovars) for (const auto &fa_endovar : fa_endovars)
register_endo(fa_endovar); register_endo(fa_endovar);
// exogenous // exogenous
const vector<const char *> &fa_exovars = fa.get_exovars(); auto &fa_exovars = fa.get_exovars();
for (auto fa_exovar : fa_exovars) for (const auto &fa_exovar : fa_exovars)
register_exo(fa_exovar); register_exo(fa_exovar);
parsing_finished(); parsing_finished();
@ -76,17 +45,17 @@ StaticFineAtoms::import_atoms(const FineAtoms &fa, OperationTree &otree, Tintint
// respective vectors, the names are already in the storage // respective vectors, the names are already in the storage
// parameters // parameters
const vector<const char *> &fa_params = fa.get_params(); auto &fa_params = fa.get_params();
for (auto fa_param : fa_params) for (const auto &fa_param : fa_params)
register_param(fa_param); register_param(fa_param);
// endogenous // endogenous
const vector<const char *> &fa_endovars = fa.get_endovars(); auto &fa_endovars = fa.get_endovars();
for (unsigned int i = 0; i < fa_endovars.size(); i++) for (unsigned int i = 0; i < fa_endovars.size(); i++)
register_endo(fa_endovars[fa.y2outer_endo()[i]]); register_endo(fa_endovars[fa.y2outer_endo()[i]]);
// exogenous // exogenous
const vector<const char *> &fa_exovars = fa.get_exovars(); auto &fa_exovars = fa.get_exovars();
for (unsigned int i = 0; i < fa_exovars.size(); i++) for (unsigned int i = 0; i < fa_exovars.size(); i++)
register_exo(fa_exovars[fa.y2outer_exo()[i]]); register_exo(fa_exovars[fa.y2outer_exo()[i]]);
@ -94,10 +63,9 @@ StaticFineAtoms::import_atoms(const FineAtoms &fa, OperationTree &otree, Tintint
} }
int int
StaticFineAtoms::check_variable(const char *name) const StaticFineAtoms::check_variable(const string &name) const
{ {
const char *ss = varnames.query(name); if (!varnames.query(name))
if (!ss)
throw ParserException(string("Variable <")+name+"> not declared.", 0); throw ParserException(string("Variable <")+name+"> not declared.", 0);
return index(name); return index(name);
} }
@ -133,7 +101,7 @@ StaticFineAtoms::parsing_finished()
} }
int int
StaticFineAtoms::name2outer_param(const char *name) const StaticFineAtoms::name2outer_param(const string &name) const
{ {
auto it = param_outer_map.find(name); auto it = param_outer_map.find(name);
if (it == param_outer_map.end()) if (it == param_outer_map.end())
@ -143,7 +111,7 @@ StaticFineAtoms::name2outer_param(const char *name) const
} }
int int
StaticFineAtoms::name2outer_endo(const char *name) const StaticFineAtoms::name2outer_endo(const string &name) const
{ {
auto it = endo_outer_map.find(name); auto it = endo_outer_map.find(name);
if (it == endo_outer_map.end()) if (it == endo_outer_map.end())
@ -153,7 +121,7 @@ StaticFineAtoms::name2outer_endo(const char *name) const
} }
int int
StaticFineAtoms::name2outer_exo(const char *name) const StaticFineAtoms::name2outer_exo(const string &name) const
{ {
auto it = exo_outer_map.find(name); auto it = exo_outer_map.find(name);
if (it == exo_outer_map.end()) if (it == exo_outer_map.end())
@ -163,75 +131,72 @@ StaticFineAtoms::name2outer_exo(const char *name) const
} }
void void
StaticFineAtoms::register_uniq_endo(const char *name) StaticFineAtoms::register_uniq_endo(string name)
{ {
if (varnames.query(name)) if (varnames.query(name))
throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.", 0); throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.", 0);
const char *ss = varnames.insert(name); varnames.insert(name);
register_endo(ss); register_endo(std::move(name));
} }
void void
StaticFineAtoms::register_uniq_exo(const char *name) StaticFineAtoms::register_uniq_exo(string name)
{ {
if (varnames.query(name)) if (varnames.query(name))
throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.", 0); throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.", 0);
const char *ss = varnames.insert(name); varnames.insert(name);
register_exo(ss); register_exo(std::move(name));
} }
void void
StaticFineAtoms::register_uniq_param(const char *name) StaticFineAtoms::register_uniq_param(string name)
{ {
if (varnames.query(name)) if (varnames.query(name))
throw ogp::ParserException(string("Parameter <")+name+"> is not unique.", 0); throw ogp::ParserException(string("Parameter <")+name+"> is not unique.", 0);
const char *ss = varnames.insert(name); varnames.insert(name);
register_param(ss); register_param(std::move(name));
} }
void void
StaticFineAtoms::print() const StaticFineAtoms::print() const
{ {
StaticAtoms::print(); StaticAtoms::print();
printf("endo atoms map:\n"); std::cout << "endo atoms map:\n";
for (unsigned int i = 0; i < endo_atoms_map.size(); i++) for (unsigned int i = 0; i < endo_atoms_map.size(); i++)
printf(u8"%d → %d\n", i, endo_atoms_map[i]); std::cout << i << u8"" << endo_atoms_map[i] << "\n";
printf("exo atoms map:\n"); std::cout << "exo atoms map:\n";
for (unsigned int i = 0; i < exo_atoms_map.size(); i++) for (unsigned int i = 0; i < exo_atoms_map.size(); i++)
printf(u8"%d → %d\n", i, exo_atoms_map[i]); std::cout << i << u8"" << exo_atoms_map[i] << "\n";
printf("der atoms:\n"); std::cout << "der atoms:\n";
for (unsigned int i = 0; i < der_atoms.size(); i++) for (unsigned int i = 0; i < der_atoms.size(); i++)
printf("%d\t%d\n", i, der_atoms[i]); std::cout << i << "\t" << der_atoms[i] << "\n";
} }
void void
StaticFineAtoms::register_endo(const char *name) StaticFineAtoms::register_endo(string name)
{ {
const char *ss = varnames.query(name); if (!varnames.query(name))
if (!ss)
throw ogp::ParserException(string("Endogenous variable <") throw ogp::ParserException(string("Endogenous variable <")
+name+"> not found in storage.", 0); +name+"> not found in storage.", 0);
endovars.push_back(ss); endovars.push_back(name);
endo_outer_map.emplace(ss, endovars.size()-1); endo_outer_map.emplace(std::move(name), endovars.size()-1);
} }
void void
StaticFineAtoms::register_exo(const char *name) StaticFineAtoms::register_exo(string name)
{ {
const char *ss = varnames.query(name); if (!varnames.query(name))
if (!ss)
throw ogp::ParserException(string("Exogenous variable <") throw ogp::ParserException(string("Exogenous variable <")
+name+"> not found in storage.", 0); +name+"> not found in storage.", 0);
exovars.push_back(ss); exovars.push_back(name);
exo_outer_map.emplace(ss, exovars.size()-1); exo_outer_map.emplace(std::move(name), exovars.size()-1);
} }
void void
StaticFineAtoms::register_param(const char *name) StaticFineAtoms::register_param(string name)
{ {
const char *ss = varnames.query(name); if (!varnames.query(name))
if (!ss)
throw ogp::ParserException(string("Parameter <")+name+"> not found in storage.", 0); throw ogp::ParserException(string("Parameter <")+name+"> not found in storage.", 0);
params.push_back(ss); params.push_back(name);
param_outer_map.emplace(ss, params.size()-1); param_outer_map.emplace(std::move(name), params.size()-1);
} }

View File

@ -23,22 +23,22 @@ namespace ogp
public: public:
using Tintintmap = map<int, int>; using Tintintmap = map<int, int>;
protected: protected:
using Tvarintmap = map<const char *, int, ltstr>; using Tvarintmap = map<string, int>;
private: private:
/** The vector of parameter names, gives the parameter /** The vector of parameter names, gives the parameter
* ordering. */ * ordering. */
vector<const char *> params; vector<string> params;
/** A map mappping a parameter name to an index in the ordering. */ /** A map mappping a parameter name to an index in the ordering. */
Tvarintmap param_outer_map; Tvarintmap param_outer_map;
/** The vector of endogenous variables. This defines the order /** The vector of endogenous variables. This defines the order
* like parameters. */ * like parameters. */
vector<const char *> endovars; vector<string> endovars;
/** A map mapping a name of an endogenous variable to an index /** A map mapping a name of an endogenous variable to an index
* in the ordering. */ * in the ordering. */
Tvarintmap endo_outer_map; Tvarintmap endo_outer_map;
/** The vector of exogenous variables. Also defines the order /** The vector of exogenous variables. Also defines the order
* like parameters and endovars. */ * like parameters and endovars. */
vector<const char *> exovars; vector<string> exovars;
/** A map mapping a name of an exogenous variable to an index /** A map mapping a name of an exogenous variable to an index
* in the outer ordering. */ * in the outer ordering. */
Tvarintmap exo_outer_map; Tvarintmap exo_outer_map;
@ -61,8 +61,6 @@ namespace ogp
vector<int> exo_atoms_map; vector<int> exo_atoms_map;
public: public:
StaticFineAtoms() = default; StaticFineAtoms() = default;
/** Copy constructor making a new storage for atom names. */
StaticFineAtoms(const StaticFineAtoms &sfa);
/** Conversion from dynamic FineAtoms taking its outer /** Conversion from dynamic FineAtoms taking its outer
* ordering as ordering of parameters, endogenous and * ordering as ordering of parameters, endogenous and
* exogenous. A biproduct is an integer to integer map mapping * exogenous. A biproduct is an integer to integer map mapping
@ -99,21 +97,21 @@ namespace ogp
* variable is declared by inserting it to * variable is declared by inserting it to
* StaticAtoms::varnames, which is done with registering * StaticAtoms::varnames, which is done with registering
* methods. This a responsibility of a subclass. */ * methods. This a responsibility of a subclass. */
int check_variable(const char *name) const override; int check_variable(const string &name) const override;
/** Return an (external) ordering of parameters. */ /** Return an (external) ordering of parameters. */
const vector<const char *> & const vector<string> &
get_params() const get_params() const
{ {
return params; return params;
} }
/** Return an external ordering of endogenous variables. */ /** Return an external ordering of endogenous variables. */
const vector<const char *> & const vector<string> &
get_endovars() const get_endovars() const
{ {
return endovars; return endovars;
} }
/** Return an external ordering of exogenous variables. */ /** Return an external ordering of exogenous variables. */
const vector<const char *> & const vector<string> &
get_exovars() const get_exovars() const
{ {
return exovars; return exovars;
@ -144,15 +142,15 @@ namespace ogp
/** Return an index in the outer ordering of a given /** Return an index in the outer ordering of a given
* parameter. An exception is thrown if the name is not a * parameter. An exception is thrown if the name is not a
* parameter. */ * parameter. */
int name2outer_param(const char *name) const; int name2outer_param(const string &name) const;
/** Return an index in the outer ordering of a given /** Return an index in the outer ordering of a given
* endogenous variable. An exception is thrown if the name is not a * endogenous variable. An exception is thrown if the name is not a
* and endogenous variable. */ * and endogenous variable. */
int name2outer_endo(const char *name) const; int name2outer_endo(const string &name) const;
/** Return an index in the outer ordering of a given /** Return an index in the outer ordering of a given
* exogenous variable. An exception is thrown if the name is not a * exogenous variable. An exception is thrown if the name is not a
* and exogenous variable. */ * and exogenous variable. */
int name2outer_exo(const char *name) const; int name2outer_exo(const string &name) const;
/** Return the number of endogenous variables. */ /** Return the number of endogenous variables. */
int int
ny() const ny() const
@ -175,29 +173,29 @@ namespace ogp
* calls defines the endo outer ordering. The method is * calls defines the endo outer ordering. The method is
* virtual, since a superclass may want to do some additional * virtual, since a superclass may want to do some additional
* action. */ * action. */
virtual void register_uniq_endo(const char *name); virtual void register_uniq_endo(string name);
/** Register unique exogenous variable name. The order of /** Register unique exogenous variable name. The order of
* calls defines the exo outer ordering. The method is * calls defines the exo outer ordering. The method is
* virtual, since a superclass may want to do somem additional * virtual, since a superclass may want to do somem additional
* action. */ * action. */
virtual void register_uniq_exo(const char *name); virtual void register_uniq_exo(string name);
/** Register unique parameter name. The order of calls defines /** Register unique parameter name. The order of calls defines
* the param outer ordering. The method is * the param outer ordering. The method is
* virtual, since a superclass may want to do somem additional * virtual, since a superclass may want to do somem additional
* action. */ * action. */
virtual void register_uniq_param(const char *name); virtual void register_uniq_param(string name);
/** Debug print. */ /** Debug print. */
void print() const override; void print() const override;
private: private:
/** Add endogenous variable name, which is already in the name /** Add endogenous variable name, which is already in the name
* storage. */ * storage. */
void register_endo(const char *name); void register_endo(string name);
/** Add exogenous variable name, which is already in the name /** Add exogenous variable name, which is already in the name
* storage. */ * storage. */
void register_exo(const char *name); void register_exo(string name);
/** Add parameter name, which is already in the name /** Add parameter name, which is already in the name
* storage. */ * storage. */
void register_param(const char *name); void register_param(string name);
}; };
}; };

View File

@ -6,6 +6,8 @@
#include <cmath> #include <cmath>
#include <limits> #include <limits>
#include <sstream>
#include <iomanip>
using namespace ogp; using namespace ogp;
@ -539,7 +541,7 @@ EvalTree::EvalTree(const OperationTree &ot, int last)
flags[1] = true; flags[1] = true;
values[2] = std::numeric_limits<double>::quiet_NaN(); values[2] = std::numeric_limits<double>::quiet_NaN();
flags[2] = true; flags[2] = true;
values[3] = 2.0/sqrt(M_PI); values[3] = 2.0/std::sqrt(M_PI);
flags[3] = true; flags[3] = true;
// this sets from num_constants on // this sets from num_constants on
reset_all(); reset_all();
@ -688,32 +690,29 @@ EvalTree::eval(int t)
return values[t]; return values[t];
} }
// if (! std::isfinite(values[t]))
// printf("Tree value t=%d is not finite = %f\n", t, values[t]);
return values[t]; return values[t];
} }
void void
EvalTree::print() const EvalTree::print() const
{ {
printf("last_op=%d\n", last_operation); std::cout << "last_op=" << last_operation << '\n'
printf(" 0 1 2 3 4 5 6 7 8 9\n"); << " 0 1 2 3 4 5 6 7 8 9\n"
printf("----------------------------------------------------------------\n"); << u8"────────────────────────────────────────────────────────────────\n";
for (int i = 0; i <= (last_operation+1)/10; i++) for (int i = 0; i <= (last_operation+1)/10; i++)
{ {
printf("%-3d|", i); std::cout << std::setw(3) << i << u8"";
int j = 0; int j = 0;
while (j < 10 && 10*i+j < last_operation+1) while (j < 10 && 10*i+j < last_operation+1)
{ {
int k = 10*i+j; int k = 10*i+j;
if (flags[k]) if (flags[k])
printf(" %5.1g", values[k]); std::cout << " " << std::setw(5) << std::setprecision(1) << values[k];
else else
printf(" -----"); std::cout << u8" ─────";
j++; j++;
} }
printf("\n"); std::cout << "\n";
} }
} }
@ -868,21 +867,20 @@ OperationStringConvertor::convert(const Operation &op, int t) const
{ {
if (t < OperationTree::num_constants) if (t < OperationTree::num_constants)
if (t == OperationTree::zero) if (t == OperationTree::zero)
return std::string("0"); return "0";
else if (t == OperationTree::one) else if (t == OperationTree::one)
return std::string("1"); return "1";
else if (t == OperationTree::nan) else if (t == OperationTree::nan)
return std::string("NaN"); return "NaN";
else if (t == OperationTree::two_over_pi) else if (t == OperationTree::two_over_pi)
{ {
char buf[100]; std::ostringstream buf;
sprintf(buf, "%20.16g", 2.0/std::sqrt(M_PI)); buf << std::setprecision(std::numeric_limits<double>::max_digits10)
return std::string(buf); << 2.0/std::sqrt(M_PI);
return buf.str();
} }
else else
{ return "error!error";
return std::string("error!error");
}
else else
return nulsc.convert(t); return nulsc.convert(t);
} }
@ -890,7 +888,7 @@ OperationStringConvertor::convert(const Operation &op, int t) const
{ {
int t1 = op.getOp1(); int t1 = op.getOp1();
const Operation &op1 = otree.operation(t1); const Operation &op1 = otree.operation(t1);
const char *opname = "unknown"; std::string opname = "unknown";
switch (op.getCode()) switch (op.getCode())
{ {
case code_t::UMINUS: case code_t::UMINUS:
@ -924,7 +922,7 @@ OperationStringConvertor::convert(const Operation &op, int t) const
break; break;
} }
std::string s1 = convert(op1, t1); std::string s1 = convert(op1, t1);
return std::string(opname) + "(" + s1 + ")"; return opname + "(" + s1 + ")";
} }
else else
{ {
@ -932,7 +930,7 @@ OperationStringConvertor::convert(const Operation &op, int t) const
const Operation &op1 = otree.operation(t1); const Operation &op1 = otree.operation(t1);
int t2 = op.getOp2(); int t2 = op.getOp2();
const Operation &op2 = otree.operation(t2); const Operation &op2 = otree.operation(t2);
const char *opname = "unknown"; std::string opname = "unknown";
switch (op.getCode()) switch (op.getCode())
{ {
case code_t::PLUS: case code_t::PLUS:

View File

@ -54,7 +54,7 @@ Dynare::Dynare(const std::string &modname, int ord, double sstol, Journal &jr)
try try
{ {
model = std::make_unique<ogdyn::DynareParser>(contents.c_str(), contents.length(), ord); model = std::make_unique<ogdyn::DynareParser>(contents, ord);
} }
catch (const ogp::ParserException &pe) catch (const ogp::ParserException &pe)
{ {
@ -86,13 +86,13 @@ Dynare::Dynare(const std::string &modname, int ord, double sstol, Journal &jr)
Dynare::Dynare(const std::vector<std::string> &endo, Dynare::Dynare(const std::vector<std::string> &endo,
const std::vector<std::string> &exo, const std::vector<std::string> &exo,
const std::vector<std::string> &par, const std::vector<std::string> &par,
const char *equations, int len, int ord, const std::string &equations, int ord,
double sstol, Journal &jr) double sstol, Journal &jr)
: journal(jr), md(1), ss_tol(sstol) : journal(jr), md(1), ss_tol(sstol)
{ {
try try
{ {
model = std::make_unique<ogdyn::DynareSPModel>(endo, exo, par, equations, len, ord); model = std::make_unique<ogdyn::DynareSPModel>(endo, exo, par, equations, ord);
} }
catch (const ogp::ParserException &pe) catch (const ogp::ParserException &pe)
{ {
@ -142,9 +142,8 @@ Dynare::writeMat(mat_t *fd, const std::string &prefix) const
void void
Dynare::writeDump(const std::string &basename) const Dynare::writeDump(const std::string &basename) const
{ {
std::string fname(basename); std::string fname(basename + ".dump");
fname += ".dump"; std::ofstream out(fname);
std::ofstream out(fname.c_str());
model->dump_model(out); model->dump_model(out);
out.close(); out.close();
} }
@ -271,7 +270,7 @@ DynareNameList::DynareNameList(const Dynare &dynare)
for (int i = 0; i < dynare.ny(); i++) for (int i = 0; i < dynare.ny(); i++)
{ {
int j = dynare.model->getAtoms().y2outer_endo()[i]; int j = dynare.model->getAtoms().y2outer_endo()[i];
const char *name = dynare.model->getAtoms().get_endovars()[j]; const std::string &name = dynare.model->getAtoms().get_endovars()[j];
names.push_back(name); names.push_back(name);
} }
} }
@ -290,7 +289,7 @@ DynareExogNameList::DynareExogNameList(const Dynare &dynare)
for (int i = 0; i < dynare.nexog(); i++) for (int i = 0; i < dynare.nexog(); i++)
{ {
int j = dynare.model->getAtoms().y2outer_exo()[i]; int j = dynare.model->getAtoms().y2outer_exo()[i];
const char *name = dynare.model->getAtoms().get_exovars()[j]; const std::string &name = dynare.model->getAtoms().get_exovars()[j];
names.push_back(name); names.push_back(name);
} }
} }

View File

@ -102,7 +102,7 @@ public:
Dynare(const std::vector<std::string> &endo, Dynare(const std::vector<std::string> &endo,
const std::vector<std::string> &exo, const std::vector<std::string> &exo,
const std::vector<std::string> &par, const std::vector<std::string> &par,
const char *equations, int len, int ord, const std::string &equations, int ord,
double sstol, Journal &jr); double sstol, Journal &jr);
/** Makes a deep copy of the object. */ /** Makes a deep copy of the object. */
Dynare(const Dynare &dyn); Dynare(const Dynare &dyn);

View File

@ -9,22 +9,25 @@
#include <string> #include <string>
#include <cmath> #include <cmath>
#include <limits>
#include <sstream>
#include <iomanip>
using namespace ogdyn; using namespace ogdyn;
using std::string; using std::string;
void void
DynareStaticAtoms::register_name(const char *name) DynareStaticAtoms::register_name(string name)
{ {
if (varnames.query(name)) if (varnames.query(name))
throw ogp::ParserException(string("The name ")+name+" is not unique.", 0); throw ogp::ParserException(string("The name ")+name+" is not unique.", 0);
StaticAtoms::register_name(name); StaticAtoms::register_name(std::move(name));
} }
int int
DynareStaticAtoms::check_variable(const char *name) const DynareStaticAtoms::check_variable(const string &name) const
{ {
if (nullptr == varnames.query(name)) if (!varnames.query(name))
throw ogp::ParserException(std::string("Unknown name <")+name+">", 0); throw ogp::ParserException(std::string("Unknown name <")+name+">", 0);
auto it = vars.find(name); auto it = vars.find(name);
if (it == vars.end()) if (it == vars.end())
@ -33,56 +36,47 @@ DynareStaticAtoms::check_variable(const char *name) const
return it->second; return it->second;
} }
DynareDynamicAtoms::DynareDynamicAtoms(const DynareDynamicAtoms &dda)
: SAtoms(dda)
{
// fill atom_type
for (auto it : dda.atom_type)
atom_type.emplace(varnames.query(it.first), it.second);
}
void void
DynareDynamicAtoms::parse_variable(const char *in, std::string &out, int &ll) const DynareDynamicAtoms::parse_variable(const string &in, std::string &out, int &ll) const
{ {
ll = 0; ll = 0;
std::string str = in; auto left = in.find_first_of("({");
auto left = str.find_first_of("({");
if (left != string::npos) if (left != string::npos)
{ {
out = str.substr(0, left); out = in.substr(0, left);
left++; left++;
auto right = str.find_first_of(")}", left); auto right = in.find_first_of(")}", left);
if (string::npos == right) if (string::npos == right)
throw ogp::ParserException(string("Syntax error when parsing Dynare atom <")+in+">.", 0); throw ogp::ParserException(string("Syntax error when parsing Dynare atom <")+in+">.", 0);
ll = std::stoi(str.substr(left, right-left)); ll = std::stoi(in.substr(left, right-left));
} }
else else
out = in; out = in;
} }
void void
DynareDynamicAtoms::register_uniq_endo(const char *name) DynareDynamicAtoms::register_uniq_endo(string name)
{ {
FineAtoms::register_uniq_endo(name); FineAtoms::register_uniq_endo(name);
atom_type.emplace(varnames.query(name), atype::endovar); atom_type.emplace(std::move(name), atype::endovar);
} }
void void
DynareDynamicAtoms::register_uniq_exo(const char *name) DynareDynamicAtoms::register_uniq_exo(string name)
{ {
FineAtoms::register_uniq_exo(name); FineAtoms::register_uniq_exo(name);
atom_type.emplace(varnames.query(name), atype::exovar); atom_type.emplace(std::move(name), atype::exovar);
} }
void void
DynareDynamicAtoms::register_uniq_param(const char *name) DynareDynamicAtoms::register_uniq_param(string name)
{ {
FineAtoms::register_uniq_param(name); FineAtoms::register_uniq_param(name);
atom_type.emplace(varnames.query(name), atype::param); atom_type.emplace(std::move(name), atype::param);
} }
bool bool
DynareDynamicAtoms::is_type(const char *name, atype tp) const DynareDynamicAtoms::is_type(const string &name, atype tp) const
{ {
auto it = atom_type.find(name); auto it = atom_type.find(name);
if (it != atom_type.end() && it->second == tp) if (it != atom_type.end() && it->second == tp)
@ -95,10 +89,11 @@ void
DynareDynamicAtoms::print() const DynareDynamicAtoms::print() const
{ {
SAtoms::print(); SAtoms::print();
printf("Name types:\n"); std::cout << "Name types:\n";
for (auto it : atom_type) for (auto it : atom_type)
printf("name=%s type=%s\n", it.first, std::cout << "name=" << it.first << " type="
it.second == atype::endovar ? "endovar" : it.second == atype::exovar ? "exovar" : "param"); << (it.second == atype::endovar ? "endovar" : it.second == atype::exovar ? "exovar" : "param")
<< '\n';
} }
std::string std::string
@ -113,22 +108,18 @@ DynareDynamicAtoms::convert(int t) const
if (is_constant(t)) if (is_constant(t))
{ {
double v = get_constant_value(t); double v = get_constant_value(t);
char buf[100]; std::ostringstream buf;
sprintf(buf, "%20.16g", v); buf << std::setprecision(std::numeric_limits<double>::max_digits10)
const char *s = buf; << v;
while (*s == ' ') return buf.str();
++s;
return s;
} }
const char *s = name(t); const string &s = name(t);
if (is_type(s, atype::endovar)) if (is_type(s, atype::endovar))
{ {
int ll = lead(t); int ll = lead(t);
if (ll) if (ll)
return std::string{s} + '(' + std::to_string(ll) + ')'; return s + '(' + std::to_string(ll) + ')';
else
return s;
} }
return s; return s;
@ -248,7 +239,7 @@ DynareSteadySubstitutions::DynareSteadySubstitutions(const ogp::FineAtoms &a,
void void
DynareSteadySubstitutions::load(int i, double res) DynareSteadySubstitutions::load(int i, double res)
{ {
const char *name = left_hand_sides[i]; const string &name = left_hand_sides[i];
int iouter = atoms.name2outer_endo(name); int iouter = atoms.name2outer_endo(name);
int iy = atoms.outer2y_endo()[iouter]; int iy = atoms.outer2y_endo()[iouter];
if (!std::isfinite(y[iy])) if (!std::isfinite(y[iy]))
@ -263,7 +254,7 @@ DynareStaticSteadySubstitutions(const ogp::FineAtoms &a, const ogp::StaticFineAt
: atoms(a), atoms_static(sa), y(yy) : atoms(a), atoms_static(sa), y(yy)
{ {
// fill the vector of left and right hand sides // fill the vector of left and right hand sides
for (auto it : subst) for (const auto &it : subst)
{ {
left_hand_sides.push_back(it.first); left_hand_sides.push_back(it.first);
right_hand_sides.push_back(it.second); right_hand_sides.push_back(it.second);
@ -278,7 +269,7 @@ DynareStaticSteadySubstitutions(const ogp::FineAtoms &a, const ogp::StaticFineAt
void void
DynareStaticSteadySubstitutions::load(int i, double res) DynareStaticSteadySubstitutions::load(int i, double res)
{ {
const char *name = left_hand_sides[i]; const string &name = left_hand_sides[i];
int iouter = atoms.name2outer_endo(name); int iouter = atoms.name2outer_endo(name);
int iy = atoms.outer2y_endo()[iouter]; int iy = atoms.outer2y_endo()[iouter];
if (!std::isfinite(y[iy])) if (!std::isfinite(y[iy]))

View File

@ -19,11 +19,12 @@ namespace ogdyn
{ {
using std::map; using std::map;
using std::vector; using std::vector;
using std::string;
/** A definition of a type mapping a string to an integer. Used as /** A definition of a type mapping a string to an integer. Used as
* a substitution map, saying what names are substituted for what * a substitution map, saying what names are substituted for what
* expressions represented by tree indices. */ * expressions represented by tree indices. */
using Tsubstmap = map<const char *, int, ogp::ltstr>; using Tsubstmap = map<string, int>;
class DynareStaticAtoms : public ogp::StaticAtoms class DynareStaticAtoms : public ogp::StaticAtoms
{ {
@ -37,12 +38,12 @@ namespace ogdyn
/** This registers a unique varname identifier. It throws an /** This registers a unique varname identifier. It throws an
* exception if the variable name is duplicate. It checks the * exception if the variable name is duplicate. It checks the
* uniqueness and then it calls StaticAtoms::register_name. */ * uniqueness and then it calls StaticAtoms::register_name. */
void register_name(const char *name) override; void register_name(string name) override;
protected: protected:
/** This returns a tree index of the given variable, and if /** This returns a tree index of the given variable, and if
* the variable has not been registered, it throws an * the variable has not been registered, it throws an
* exception. */ * exception. */
int check_variable(const char *name) const override; int check_variable(const string &name) const override;
}; };
class DynareDynamicAtoms : public ogp::SAtoms, public ogp::NularyStringConvertor class DynareDynamicAtoms : public ogp::SAtoms, public ogp::NularyStringConvertor
@ -50,7 +51,7 @@ namespace ogdyn
public: public:
enum class atype {endovar, exovar, param}; enum class atype {endovar, exovar, param};
protected: protected:
using Tatypemap = map<const char *, atype, ogp::ltstr>; using Tatypemap = map<string, atype>;
/** The map assigining a type to each name. */ /** The map assigining a type to each name. */
Tatypemap atom_type; Tatypemap atom_type;
public: public:
@ -58,20 +59,18 @@ namespace ogdyn
: ogp::SAtoms() : ogp::SAtoms()
{ {
} }
DynareDynamicAtoms(const DynareDynamicAtoms &dda);
~DynareDynamicAtoms() override = default;
/** This parses a variable of the forms: varname(+3), /** This parses a variable of the forms: varname(+3),
* varname(3), varname, varname(-3), varname(0), varname(+0), * varname(3), varname, varname(-3), varname(0), varname(+0),
* varname(-0). */ * varname(-0). */
void parse_variable(const char *in, std::string &out, int &ll) const override; void parse_variable(const string &in, std::string &out, int &ll) const override;
/** Registers unique name of endogenous variable. */ /** Registers unique name of endogenous variable. */
void register_uniq_endo(const char *name) override; void register_uniq_endo(string name) override;
/** Registers unique name of exogenous variable. */ /** Registers unique name of exogenous variable. */
void register_uniq_exo(const char *name) override; void register_uniq_exo(string name) override;
/** Registers unique name of parameter. */ /** Registers unique name of parameter. */
void register_uniq_param(const char *name) override; void register_uniq_param(string name) override;
/** Return true if the name is a given type. */ /** Return true if the name is a given type. */
bool is_type(const char *name, atype tp) const; bool is_type(const string &name, atype tp) const;
/** Debug print. */ /** Debug print. */
void print() const override; void print() const override;
/** Implement NularyStringConvertor::convert. */ /** Implement NularyStringConvertor::convert. */
@ -194,7 +193,7 @@ namespace ogdyn
void load(int i, double res) override; void load(int i, double res) override;
protected: protected:
Vector &y; Vector &y;
vector<const char *> left_hand_sides; vector<string> left_hand_sides;
vector<int> right_hand_sides; vector<int> right_hand_sides;
}; };
@ -217,7 +216,7 @@ namespace ogdyn
void load(int i, double res) override; void load(int i, double res) override;
protected: protected:
Vector &y; Vector &y;
vector<const char *> left_hand_sides; vector<string> left_hand_sides;
vector<int> right_hand_sides; vector<int> right_hand_sides;
}; };

View File

@ -89,14 +89,14 @@ DynareModel::setInitOuter(const Vector &x)
void void
DynareModel::print() const DynareModel::print() const
{ {
printf("all atoms:\n"); std::cout << "all atoms:\n";
atoms.print(); atoms.print();
printf("formulas:\n"); std::cout << "formulas:\n";
DebugOperationFormatter dof(*this); DebugOperationFormatter dof(*this);
for (int i = 0; i < eqs.nformulas(); i++) for (int i = 0; i < eqs.nformulas(); i++)
{ {
int tf = eqs.formula(i); int tf = eqs.formula(i);
printf("formula %d:\n", tf); std::cout << "formula " << tf << "%d:\n";
eqs.getTree().print_operation_tree(tf, std::cout, dof); eqs.getTree().print_operation_tree(tf, std::cout, dof);
} }
} }
@ -148,17 +148,17 @@ DynareModel::dump_model(std::ostream &os) const
} }
void void
DynareModel::add_name(const std::string &name, int flag) DynareModel::add_name(std::string name, int flag)
{ {
if (flag == 1) if (flag == 1)
// endogenous // endogenous
atoms.register_uniq_endo(name.c_str()); atoms.register_uniq_endo(name);
else if (flag == 2) else if (flag == 2)
// exogenous // exogenous
atoms.register_uniq_exo(name.c_str()); atoms.register_uniq_exo(name);
else if (flag == 3) else if (flag == 3)
// parameter // parameter
atoms.register_uniq_param(name.c_str()); atoms.register_uniq_param(name);
else else
throw DynareException(__FILE__, __LINE__, "Unrecognized flag value."); throw DynareException(__FILE__, __LINE__, "Unrecognized flag value.");
} }
@ -206,7 +206,7 @@ DynareModel::check_model() const
int int
DynareModel::variable_shift(int t, int tshift) DynareModel::variable_shift(int t, int tshift)
{ {
const char *name = atoms.name(t); const string &name = atoms.name(t);
if (atoms.is_type(name, DynareDynamicAtoms::atype::param) if (atoms.is_type(name, DynareDynamicAtoms::atype::param)
|| atoms.is_constant(t)) || atoms.is_constant(t))
throw DynareException(__FILE__, __LINE__, throw DynareException(__FILE__, __LINE__,
@ -214,10 +214,7 @@ DynareModel::variable_shift(int t, int tshift)
int ll = atoms.lead(t) + tshift; int ll = atoms.lead(t) + tshift;
int res = atoms.index(name, ll); int res = atoms.index(name, ll);
if (res == -1) if (res == -1)
{ res = eqs.add_nulary(name + '(' + std::to_string(ll) + ')');
std::string str = name + '(' + std::to_string(ll) + ')';
res = eqs.add_nulary(str.c_str());
}
return res; return res;
} }
@ -230,7 +227,7 @@ DynareModel::variable_shift_map(const unordered_set<int> &a_set, int tshift,
// make shift map only for non-constants and non-parameters // make shift map only for non-constants and non-parameters
if (!atoms.is_constant(t)) if (!atoms.is_constant(t))
{ {
const char *name = atoms.name(t); const string &name = atoms.name(t);
if (atoms.is_type(name, DynareDynamicAtoms::atype::endovar) if (atoms.is_type(name, DynareDynamicAtoms::atype::endovar)
|| atoms.is_type(name, DynareDynamicAtoms::atype::exovar)) || atoms.is_type(name, DynareDynamicAtoms::atype::exovar))
{ {
@ -278,7 +275,7 @@ DynareModel::get_nonlinear_subterms(int t) const
} }
void void
DynareModel::substitute_atom_for_term(const char *name, int ll, int t) DynareModel::substitute_atom_for_term(const string &name, int ll, int t)
{ {
// if the term t is itself a named atom (parameter, exo, endo), // if the term t is itself a named atom (parameter, exo, endo),
// then we have to unassign it first // then we have to unassign it first
@ -326,7 +323,7 @@ DynareModel::final_job()
extern ogp::location_type dynglob_lloc; extern ogp::location_type dynglob_lloc;
DynareParser::DynareParser(const char *stream, int len, int ord) DynareParser::DynareParser(const string &stream, int ord)
: DynareModel(), : DynareModel(),
pa_atoms(), paramset(pa_atoms), pa_atoms(), paramset(pa_atoms),
ia_atoms(), initval(ia_atoms), vcov(), ia_atoms(), initval(ia_atoms), vcov(),
@ -341,7 +338,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
// global parse // global parse
try try
{ {
parse_glob(len, stream); parse_glob(stream);
} }
catch (const ogp::ParserException &e) catch (const ogp::ParserException &e)
{ {
@ -351,7 +348,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
try try
{ {
if (paramset_end > paramset_beg) if (paramset_end > paramset_beg)
paramset.parse(paramset_end-paramset_beg, stream+paramset_beg); paramset.parse(stream.substr(paramset_beg, paramset_end-paramset_beg));
} }
catch (const ogp::ParserException &e) catch (const ogp::ParserException &e)
{ {
@ -361,7 +358,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
try try
{ {
if (model_end > model_beg) if (model_end > model_beg)
eqs.parse(model_end-model_beg, stream+model_beg); eqs.parse(stream.substr(model_beg, model_end-model_beg));
else else
throw ogp::ParserException("Model section not found.", 0); throw ogp::ParserException("Model section not found.", 0);
} }
@ -373,7 +370,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
try try
{ {
if (initval_end > initval_beg) if (initval_end > initval_beg)
initval.parse(initval_end-initval_beg, stream+initval_beg); initval.parse(stream.substr(initval_beg, initval_end-initval_beg));
} }
catch (const ogp::ParserException &e) catch (const ogp::ParserException &e)
{ {
@ -383,7 +380,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
try try
{ {
if (vcov_end > vcov_beg) if (vcov_end > vcov_beg)
vcov.parse(vcov_end-vcov_beg, stream+vcov_beg); vcov.parse(stream.substr(vcov_beg, vcov_end-vcov_beg));
} }
catch (const ogp::ParserException &e) catch (const ogp::ParserException &e)
{ {
@ -394,7 +391,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
{ {
if (plobjective_end > plobjective_beg) if (plobjective_end > plobjective_beg)
{ {
eqs.parse(plobjective_end-plobjective_beg, stream+plobjective_beg); eqs.parse(stream.substr(plobjective_beg, plobjective_end-plobjective_beg));
t_plobjective = eqs.pop_last_formula(); t_plobjective = eqs.pop_last_formula();
} }
} }
@ -406,8 +403,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
try try
{ {
if (pldiscount_end > pldiscount_beg) if (pldiscount_end > pldiscount_beg)
t_pldiscount = parse_pldiscount(pldiscount_end - pldiscount_beg, t_pldiscount = parse_pldiscount(stream.substr(pldiscount_beg, pldiscount_end - pldiscount_beg));
stream + pldiscount_beg);
} }
catch (const ogp::ParserException &e) catch (const ogp::ParserException &e)
{ {
@ -417,7 +413,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
try try
{ {
if (order_end > order_beg) if (order_end > order_beg)
order = parse_order(order_end - order_beg, stream + order_beg); order = parse_order(stream.substr(order_beg, order_end - order_beg));
} }
catch (const ogp::ParserException &e) catch (const ogp::ParserException &e)
{ {
@ -468,45 +464,45 @@ DynareParser::DynareParser(const DynareParser &dp)
} }
void void
DynareParser::add_name(const char *name, int flag) DynareParser::add_name(string name, int flag)
{ {
DynareModel::add_name(name, flag); DynareModel::add_name(name, flag);
// register with static atoms used for atom assignements // register with static atoms used for atom assignements
if (flag == 1) if (flag == 1)
// endogenous // endogenous
ia_atoms.register_name(name); ia_atoms.register_name(std::move(name));
else if (flag == 2) else if (flag == 2)
// exogenous // exogenous
ia_atoms.register_name(name); ia_atoms.register_name(std::move(name));
else if (flag == 3) else if (flag == 3)
{ {
// parameter // parameter
pa_atoms.register_name(name); pa_atoms.register_name(name);
ia_atoms.register_name(name); ia_atoms.register_name(std::move(name));
} }
else else
throw DynareException(__FILE__, __LINE__, "Unrecognized flag value."); throw DynareException(__FILE__, __LINE__, "Unrecognized flag value.");
} }
void void
DynareParser::error(const char *mes) DynareParser::error(string mes)
{ {
// throwing zero offset since this exception will be caugth at // throwing zero offset since this exception will be caugth at
// constructor // constructor
throw ogp::ParserException(mes, 0); throw ogp::ParserException(std::move(mes), 0);
} }
void void
DynareParser::print() const DynareParser::print() const
{ {
DynareModel::print(); DynareModel::print();
printf("parameter atoms:\n"); std::cout << "parameter atoms:\n";
paramset.print(); paramset.print();
printf("initval atoms:\n"); std::cout << "initval atoms:\n";
initval.print(); initval.print();
printf("model position: %d %d\n", model_beg, model_end); std::cout << "model position: " << model_beg << ' ' << model_end << '\n'
printf("paramset position: %d %d\n", paramset_beg, paramset_end); << "paramset position: " << paramset_beg << ' ' << paramset_end << '\n'
printf("initval position: %d %d\n", initval_beg, initval_end); << "initval position: " << initval_beg << ' ' << initval_end << '\n';
} }
/** A global symbol for passing info to the DynareParser from /** A global symbol for passing info to the DynareParser from
@ -515,47 +511,35 @@ DynareParser *dynare_parser;
/** The declarations of functions defined in dynglob_ll.cc and /** The declarations of functions defined in dynglob_ll.cc and
* dynglob_tab.cc generated from dynglob.lex and dynglob.y */ * dynglob_tab.cc generated from dynglob.lex and dynglob.y */
void *dynglob__scan_buffer(char *, size_t); void *dynglob__scan_string(const char *);
void dynglob__destroy_buffer(void *); void dynglob__destroy_buffer(void *);
void dynglob_parse(); void dynglob_parse();
extern ogp::location_type dynglob_lloc; extern ogp::location_type dynglob_lloc;
void void
DynareParser::parse_glob(int length, const char *stream) DynareParser::parse_glob(const string &stream)
{ {
auto buffer = std::make_unique<char[]>(length+2); void *p = dynglob__scan_string(stream.c_str());
std::copy_n(stream, length, buffer.get());
buffer[length] = '\0';
buffer[length+1] = '\0';
void *p = dynglob__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
dynare_parser = this; dynare_parser = this;
dynglob_parse(); dynglob_parse();
dynglob__destroy_buffer(p); dynglob__destroy_buffer(p);
} }
int int
DynareParser::parse_order(int len, const char *str) DynareParser::parse_order(const string &str)
{ {
auto buf = std::make_unique<char[]>(len+1); return std::stoi(str);
std::copy_n(str, len, buf.get());
buf[len] = '\0';
int res;
sscanf(buf.get(), "%d", &res);
return res;
} }
int int
DynareParser::parse_pldiscount(int len, const char *str) DynareParser::parse_pldiscount(const string &str)
{ {
auto buf = std::make_unique<char[]>(len+1); if (!atoms.is_type(str, DynareDynamicAtoms::atype::param))
std::copy_n(str, len, buf.get()); throw ogp::ParserException(std::string{"Name "} + str + " is not a parameter", 0);
buf[len] = '\0';
if (!atoms.is_type(buf.get(), DynareDynamicAtoms::atype::param))
throw ogp::ParserException(std::string{"Name "} + buf.get() + " is not a parameter", 0);
int t = atoms.index(buf.get(), 0); int t = atoms.index(str, 0);
if (t == -1) if (t == -1)
t = eqs.add_nulary(buf.get()); t = eqs.add_nulary(str);
return t; return t;
} }
@ -571,8 +555,7 @@ DynareParser::calc_params()
for (unsigned int i = 0; i < atoms.get_params().size(); i++) for (unsigned int i = 0; i < atoms.get_params().size(); i++)
if (!std::isfinite((*param_vals)[i])) if (!std::isfinite((*param_vals)[i]))
printf("dynare++: warning: value for parameter %s is not finite\n", std::cout << "dynare++: warning: value for parameter " << atoms.get_params()[i] << " is not finite\n";
atoms.get_params()[i]);
} }
void void
@ -613,8 +596,7 @@ DynareParser::calc_init()
for (unsigned int i = 0; i < atoms.get_endovars().size(); i++) for (unsigned int i = 0; i < atoms.get_endovars().size(); i++)
if (!std::isfinite((*init_vals)[i])) if (!std::isfinite((*init_vals)[i]))
printf("dynare++: warning: initval for <%s> is not finite\n", std::cout << "dynare++: warning: initval for <" << atoms.get_endovars()[atoms.y2outer_endo()[i]] << "> is not finite\n";
atoms.get_endovars()[atoms.y2outer_endo()[i]]);
} }
// this returns false for linear functions // this returns false for linear functions
@ -682,7 +664,7 @@ NLSelector::operator()(int t) const
DynareSPModel::DynareSPModel(const std::vector<std::string> &endo, DynareSPModel::DynareSPModel(const std::vector<std::string> &endo,
const std::vector<std::string> &exo, const std::vector<std::string> &exo,
const std::vector<std::string> &par, const std::vector<std::string> &par,
const char *equations, int len, const string &equations,
int ord) int ord)
: DynareModel() : DynareModel()
{ {
@ -698,7 +680,7 @@ DynareSPModel::DynareSPModel(const std::vector<std::string> &endo,
add_name(it, 3); add_name(it, 3);
// parse the equations // parse the equations
eqs.parse(len, equations); eqs.parse(equations);
// parsing finished // parsing finished
atoms.parsing_finished(ogp::VarOrdering::bfspbfpb); atoms.parsing_finished(ogp::VarOrdering::bfspbfpb);
@ -843,7 +825,7 @@ MatlabSSWriter::write_atom_assignment(std::ostream &os) const
os << "% parameter values\n"; os << "% parameter values\n";
for (unsigned int ip = 0; ip < model.getAtoms().get_params().size(); ip++) for (unsigned int ip = 0; ip < model.getAtoms().get_params().size(); ip++)
{ {
const char *parname = model.getAtoms().get_params()[ip]; const string &parname = model.getAtoms().get_params()[ip];
int t = model.getAtoms().index(parname, 0); int t = model.getAtoms().index(parname, 0);
if (t == -1) if (t == -1)
os << "% " << parname << " not used in the model\n"; os << "% " << parname << " not used in the model\n";
@ -857,7 +839,7 @@ MatlabSSWriter::write_atom_assignment(std::ostream &os) const
os << "% exogenous variables to zeros\n"; os << "% exogenous variables to zeros\n";
for (unsigned int ie = 0; ie < model.getAtoms().get_exovars().size(); ie++) for (unsigned int ie = 0; ie < model.getAtoms().get_exovars().size(); ie++)
{ {
const char *exoname = model.getAtoms().get_exovars()[ie]; const string &exoname = model.getAtoms().get_exovars()[ie];
try try
{ {
const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(exoname); const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(exoname);
@ -876,7 +858,7 @@ MatlabSSWriter::write_atom_assignment(std::ostream &os) const
os << "% endogenous variables to y\n"; os << "% endogenous variables to y\n";
for (unsigned int ie = 0; ie < model.getAtoms().get_endovars().size(); ie++) for (unsigned int ie = 0; ie < model.getAtoms().get_endovars().size(); ie++)
{ {
const char *endoname = model.getAtoms().get_endovars()[ie]; const string &endoname = model.getAtoms().get_endovars()[ie];
const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(endoname); const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(endoname);
for (auto it : lmap) for (auto it : lmap)
{ {
@ -920,7 +902,7 @@ MatlabSSWriter::write_der1_assignment(std::ostream &os) const
for (int j : eam) for (int j : eam)
{ {
int tvar = variables[j]; int tvar = variables[j];
const char *name = model.getAtoms().name(tvar); const string &name = model.getAtoms().name(tvar);
int yi = model.getAtoms().name2outer_endo(name); int yi = model.getAtoms().name2outer_endo(name);
int t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, j)); int t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, j));
if (t != ogp::OperationTree::zero) if (t != ogp::OperationTree::zero)
@ -963,7 +945,7 @@ DebugOperationFormatter::format_nulary(int t, std::ostream &os) const
else else
{ {
int ll = a.lead(t); int ll = a.lead(t);
std::string name{a.name(t)}; const std::string &name = a.name(t);
if (ll == 0) if (ll == 0)
os << name; os << name;
else else

View File

@ -18,6 +18,7 @@
#include <unordered_set> #include <unordered_set>
#include <ostream> #include <ostream>
#include <memory> #include <memory>
#include <iostream>
namespace ogdyn namespace ogdyn
{ {
@ -40,14 +41,11 @@ namespace ogdyn
{ {
} }
PosInterval &operator=(const PosInterval &pi) = default; PosInterval &operator=(const PosInterval &pi) = default;
/** 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. */ /** Debug print. */
void void
print() const print() const
{ {
printf("fl=%d fc=%d ll=%d lc=%d\n", fl, fc, ll, lc); std::cout << "fl=" << fl << " fc=" << fc << " ll=" << ll << " lc=" << lc << '\n';
} }
}; };
@ -189,7 +187,7 @@ namespace ogdyn
* sort is governed by the flag. See dynglob.y for values of * sort is governed by the flag. See dynglob.y for values of
* the flag. This is used by a subclass when declaring the * the flag. This is used by a subclass when declaring the
* names. */ * names. */
void add_name(const std::string &name, int flag); void add_name(std::string name, int flag);
/** This checks the model consistency. Thus includes: number /** This checks the model consistency. Thus includes: number
* of endo variables and number of equations, min and max lag * of endo variables and number of equations, min and max lag
* of endogenous variables and occurrrences of exogenous * of endogenous variables and occurrrences of exogenous
@ -224,7 +222,7 @@ namespace ogdyn
* this way, all occurrences of term t are substituted with * this way, all occurrences of term t are substituted with
* the atom name(ll). The method handles also rewriting * the atom name(ll). The method handles also rewriting
* operation tree including derivatives of the term t. */ * operation tree including derivatives of the term t. */
void substitute_atom_for_term(const char *name, int ll, int t); void substitute_atom_for_term(const string &name, int ll, int t);
/** This performs a final job after the model is parsed. It /** This performs a final job after the model is parsed. It
* creates the PlannerBuilder object if the planner's FOC are * creates the PlannerBuilder object if the planner's FOC are
* needed, then it creates ForwSubstBuilder handling multiple * needed, then it creates ForwSubstBuilder handling multiple
@ -255,7 +253,7 @@ namespace ogdyn
* of the given length corresponding to the Dynare++ model * of the given length corresponding to the Dynare++ model
* file. If the given ord is not -1, then it overrides setting * file. If the given ord is not -1, then it overrides setting
* in the model file. */ * in the model file. */
DynareParser(const char *str, int len, int ord); DynareParser(const string &str, int ord);
DynareParser(const DynareParser &dp); DynareParser(const DynareParser &dp);
std::unique_ptr<DynareModel> std::unique_ptr<DynareModel>
clone() const override clone() const override
@ -265,7 +263,7 @@ namespace ogdyn
/** Adds a name of endogenous, exogenous or a parameter. This /** Adds a name of endogenous, exogenous or a parameter. This
* addss the name to the parent class DynareModel and also * addss the name to the parent class DynareModel and also
* registers the name to either paramset, or initval. */ * registers the name to either paramset, or initval. */
void add_name(const char *name, int flag); void add_name(string name, int flag);
/** Sets position of the model section. Called from /** Sets position of the model section. Called from
* dynglob.y. */ * dynglob.y. */
void void
@ -323,13 +321,13 @@ namespace ogdyn
pldiscount_end = off2; pldiscount_end = off2;
} }
/** Processes a syntax error from bison. */ /** Processes a syntax error from bison. */
void error(const char *mes); void error(string mes);
/** Debug print. */ /** Debug print. */
void print() const; void print() const;
protected: protected:
void parse_glob(int length, const char *stream); void parse_glob(const string &stream);
int parse_order(int length, const char *stream); int parse_order(const string &stream);
int parse_pldiscount(int length, const char *stream); int parse_pldiscount(const string &stream);
/** Evaluate paramset assignings and set param_vals. */ /** Evaluate paramset assignings and set param_vals. */
void calc_params(); void calc_params();
/** Evaluate initval assignings and set init_vals. */ /** Evaluate initval assignings and set init_vals. */
@ -364,7 +362,7 @@ namespace ogdyn
DynareSPModel(const std::vector<std::string> &endo, DynareSPModel(const std::vector<std::string> &endo,
const std::vector<std::string> &exo, const std::vector<std::string> &exo,
const std::vector<std::string> &par, const std::vector<std::string> &par,
const char *equations, int len, int ord); const string &equations, int ord);
DynareSPModel(const DynareSPModel &dm) = default; DynareSPModel(const DynareSPModel &dm) = default;
~DynareSPModel() override = default; ~DynareSPModel() override = default;
std::unique_ptr<DynareModel> std::unique_ptr<DynareModel>

View File

@ -160,11 +160,11 @@ DynareParams::DynareParams(int argc, char **argv)
break; break;
} }
} }
catch (std::invalid_argument) catch (std::invalid_argument &)
{ {
std::cerr << "Couldn't parse option " << optarg << ", ignored\n"; std::cerr << "Couldn't parse option " << optarg << ", ignored\n";
} }
catch (std::out_of_range) catch (std::out_of_range &)
{ {
std::cerr << "Out-of-range value " << optarg << ", ignored\n"; std::cerr << "Out-of-range value " << optarg << ", ignored\n";
} }

View File

@ -9,9 +9,11 @@
%code %code
{ {
#include <string>
#include "dynare_model.hh" #include "dynare_model.hh"
void dynglob_error(const char*); void dynglob_error(std::string);
int dynglob_lex(); int dynglob_lex();
extern ogdyn::DynareParser* dynare_parser; extern ogdyn::DynareParser* dynare_parser;
int symblist_flag; int symblist_flag;
@ -109,7 +111,7 @@ planner_discount : PLANNERDISCOUNT NAME SEMICOLON {
%% %%
void void
dynglob_error(const char* mes) dynglob_error(std::string mes)
{ {
dynare_parser->error(mes); dynare_parser->error(mes);
} }

View File

@ -59,12 +59,11 @@ ForwSubstBuilder::substitute_for_term(int t, int i, int j)
// now maxlead of lagt is +1 // now maxlead of lagt is +1
// add AUXLD_*_*_1 = f(x(+1)) to the model // add AUXLD_*_*_1 = f(x(+1)) to the model
std::string name = "AUXLD_" + std::to_string(i) + '_' + std::to_string(j) + "_1"; std::string name = "AUXLD_" + std::to_string(i) + '_' + std::to_string(j) + "_1";
model.atoms.register_uniq_endo(name.c_str()); model.atoms.register_uniq_endo(name);
info.num_aux_variables++; info.num_aux_variables++;
const char *ss = model.atoms.get_name_storage().query(name.c_str()); int auxt = model.eqs.add_nulary(name);
int auxt = model.eqs.add_nulary(name.c_str());
model.eqs.add_formula(model.eqs.add_binary(ogp::code_t::MINUS, auxt, lagt)); model.eqs.add_formula(model.eqs.add_binary(ogp::code_t::MINUS, auxt, lagt));
aux_map.emplace(ss, lagt); aux_map.emplace(name, lagt);
// now add variables and equations // now add variables and equations
// AUXLD_*_*_2 = AUXLD_*_*_1(+1) through // AUXLD_*_*_2 = AUXLD_*_*_1(+1) through
// AUXLD_*_*_{mlead-1} = AUXLD_*_*_{mlead-2}(+1) // AUXLD_*_*_{mlead-1} = AUXLD_*_*_{mlead-2}(+1)
@ -72,13 +71,12 @@ ForwSubstBuilder::substitute_for_term(int t, int i, int j)
{ {
// create AUXLD_*_*_{ll}(+1) // create AUXLD_*_*_{ll}(+1)
name = "AUXLD_" + std::to_string(i) + '_' + std::to_string(j) + '_' + std::to_string(ll) + "(+1)"; name = "AUXLD_" + std::to_string(i) + '_' + std::to_string(j) + '_' + std::to_string(ll) + "(+1)";
int lastauxt_lead = model.eqs.add_nulary(name.c_str()); int lastauxt_lead = model.eqs.add_nulary(name);
// create AUXLD_*_*{ll+1} // create AUXLD_*_*{ll+1}
name = "AUXLD_" + std::to_string(i) + '_' + std::to_string(j) + '_' + std::to_string(ll+1); name = "AUXLD_" + std::to_string(i) + '_' + std::to_string(j) + '_' + std::to_string(ll+1);
model.atoms.register_uniq_endo(name.c_str()); model.atoms.register_uniq_endo(name);
info.num_aux_variables++; info.num_aux_variables++;
ss = model.atoms.get_name_storage().query(name.c_str()); auxt = model.eqs.add_nulary(name);
auxt = model.eqs.add_nulary(name.c_str());
// add AUXLD_*_*_{ll+1} = AUXLD_*_*_{ll}(+1) // add AUXLD_*_*_{ll+1} = AUXLD_*_*_{ll}(+1)
model.eqs.add_formula(model.eqs.add_binary(ogp::code_t::MINUS, auxt, lastauxt_lead)); model.eqs.add_formula(model.eqs.add_binary(ogp::code_t::MINUS, auxt, lastauxt_lead));
// add substitution to the map; todo: this // add substitution to the map; todo: this
@ -86,38 +84,36 @@ ForwSubstBuilder::substitute_for_term(int t, int i, int j)
// aux_map is used the timing doesn't matter, // aux_map is used the timing doesn't matter,
// however, it is misleading, needs to be // however, it is misleading, needs to be
// changed // changed
aux_map.emplace(ss, lagt); aux_map.emplace(name, lagt);
} }
// now we have to substitute AUXLD_*_*{mlead-1}(+1) for t // now we have to substitute AUXLD_*_*{mlead-1}(+1) for t
name = "AUXLD_" + std::to_string(i) + '_' + std::to_string(j) + '_' + std::to_string(mlead-1); name = "AUXLD_" + std::to_string(i) + '_' + std::to_string(j) + '_' + std::to_string(mlead-1);
ss = model.atoms.get_name_storage().query(name.c_str()); model.substitute_atom_for_term(name, +1, t);
model.substitute_atom_for_term(ss, +1, t);
} }
} }
void void
ForwSubstBuilder::unassign_gt_1_leads(const char *name) ForwSubstBuilder::unassign_gt_1_leads(const string &name)
{ {
const char *ss = model.atoms.get_name_storage().query(name);
int mlead, mlag; int mlead, mlag;
model.atoms.varspan(name, mlead, mlag); model.atoms.varspan(name, mlead, mlag);
for (int ll = 2; ll <= mlead; ll++) for (int ll = 2; ll <= mlead; ll++)
{ {
int t = model.atoms.index(ss, ll); int t = model.atoms.index(name, ll);
if (t != -1) if (t != -1)
model.atoms.unassign_variable(ss, ll, t); model.atoms.unassign_variable(name, ll, t);
} }
} }
void void
ForwSubstBuilder::unassign_gt_1_leads() ForwSubstBuilder::unassign_gt_1_leads()
{ {
const vector<const char *> &endovars = model.atoms.get_endovars(); auto &endovars = model.atoms.get_endovars();
for (auto endovar : endovars) for (const auto &endovar : endovars)
unassign_gt_1_leads(endovar); unassign_gt_1_leads(endovar);
const vector<const char *> &exovars = model.atoms.get_exovars(); auto &exovars = model.atoms.get_exovars();
for (auto exovar : exovars) for (const auto &exovar : exovars)
unassign_gt_1_leads(exovar); unassign_gt_1_leads(exovar);
} }
@ -125,8 +121,5 @@ ForwSubstBuilder::ForwSubstBuilder(const ForwSubstBuilder &b, DynareModel &m)
: model(m) : model(m)
{ {
for (auto it : b.aux_map) for (auto it : b.aux_map)
{ aux_map.insert(it);
const char *ss = m.atoms.get_name_storage().query(it.first);
aux_map.emplace(ss, it.second);
}
} }

View File

@ -25,7 +25,7 @@ namespace ogdyn
class ForwSubstBuilder class ForwSubstBuilder
{ {
using Ttermauxmap = map<int, const char *>; using Ttermauxmap = map<int, string>;
protected: protected:
/** Reference to the model, to which we will add equations and /** Reference to the model, to which we will add equations and
* change some equations. */ * change some equations. */
@ -78,7 +78,7 @@ namespace ogdyn
* all nulary terms with a lead greater than 1. */ * all nulary terms with a lead greater than 1. */
void unassign_gt_1_leads(); void unassign_gt_1_leads();
/** This unassigns all leads greater than 1 of the given name. */ /** This unassigns all leads greater than 1 of the given name. */
void unassign_gt_1_leads(const char *name); void unassign_gt_1_leads(const string &name);
}; };
}; };

View File

@ -12,6 +12,8 @@
#include "../kord/approximation.hh" #include "../kord/approximation.hh"
#include <fstream> #include <fstream>
#include <iostream>
#include <cstdlib>
int int
main(int argc, char **argv) main(int argc, char **argv)
@ -20,27 +22,24 @@ main(int argc, char **argv)
if (params.help) if (params.help)
{ {
params.printHelp(); params.printHelp();
return 0; return EXIT_SUCCESS;
} }
if (params.version) if (params.version)
{ {
printf(u8"Dynare++ v. %s. Copyright © 2004-2011, Ondra Kamenik\n", std::cout << u8"Dynare++ v. " << DYNVERSION << ". Copyright © 2004-2011, Ondra Kamenik\n"
DYNVERSION); << "Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under\n"
printf("Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under\n"); << "GPL: modules integ, tl, kord, sylv, src, extern and documentation\n"
printf("GPL: modules integ, tl, kord, sylv, src, extern and documentation\n"); << "LGPL: modules parser, utils\n"
printf("LGPL: modules parser, utils\n"); << " for GPL see https://www.gnu.org/licenses/gpl.html\n"
printf(" for GPL see http://www.gnu.org/licenses/gpl.html\n"); << " for LGPL see https://www.gnu.org/licenses/lgpl.html\n";
printf(" for LGPL see http://www.gnu.org/licenses/lgpl.html\n"); return EXIT_SUCCESS;
return 0;
} }
sthread::detach_thread_group::max_parallel_threads = params.num_threads; sthread::detach_thread_group::max_parallel_threads = params.num_threads;
try try
{ {
// make journal name and journal // make journal
std::string jname(params.basename); Journal journal(params.basename + ".jnl");
jname += ".jnl";
Journal journal(jname.c_str());
// make dynare object // make dynare object
Dynare dynare(params.modname, params.order, params.ss_tol, journal); Dynare dynare(params.modname, params.order, params.ss_tol, journal);
@ -50,41 +49,38 @@ main(int argc, char **argv)
for (int i = 0; i < dynare.nexog(); i++) for (int i = 0; i < dynare.nexog(); i++)
irf_list_ind.push_back(i); irf_list_ind.push_back(i);
else else
irf_list_ind = (static_cast<const DynareNameList &>(dynare.getExogNames())).selectIndices(params.irf_list); irf_list_ind = static_cast<const DynareNameList &>(dynare.getExogNames()).selectIndices(params.irf_list);
// write matlab files // write matlab files
std::string mfile1(params.basename); std::string mfile1(params.basename + "_f.m");
mfile1 += "_f.m";
std::ofstream mfd{mfile1, std::ios::out | std::ios::trunc}; std::ofstream mfd{mfile1, std::ios::out | std::ios::trunc};
if (mfd.fail()) if (mfd.fail())
{ {
fprintf(stderr, "Couldn't open %s for writing.\n", mfile1.c_str()); std::cerr << "Couldn't open " << mfile1 << " for writing.\n";
exit(1); std::exit(EXIT_FAILURE);
} }
ogdyn::MatlabSSWriter writer0(dynare.getModel(), params.basename.c_str()); ogdyn::MatlabSSWriter writer0(dynare.getModel(), params.basename);
writer0.write_der0(mfd); writer0.write_der0(mfd);
mfd.close(); mfd.close();
std::string mfile2(params.basename); std::string mfile2(params.basename + "_ff.m");
mfile2 += "_ff.m";
mfd.open(mfile2, std::ios::out | std::ios::trunc); mfd.open(mfile2, std::ios::out | std::ios::trunc);
if (mfd.fail()) if (mfd.fail())
{ {
fprintf(stderr, "Couldn't open %s for writing.\n", mfile2.c_str()); std::cerr << "Couldn't open " << mfile2 << " for writing.\n";
exit(1); std::exit(EXIT_FAILURE);
} }
ogdyn::MatlabSSWriter writer1(dynare.getModel(), params.basename.c_str()); ogdyn::MatlabSSWriter writer1(dynare.getModel(), params.basename);
writer1.write_der1(mfd); writer1.write_der1(mfd);
mfd.close(); mfd.close();
// open mat file // open mat file
std::string matfile(params.basename); std::string matfile(params.basename + ".mat");
matfile += ".mat";
mat_t *matfd = Mat_Create(matfile.c_str(), nullptr); mat_t *matfd = Mat_Create(matfile.c_str(), nullptr);
if (matfd == nullptr) if (!matfd)
{ {
fprintf(stderr, "Couldn't open %s for writing.\n", matfile.c_str()); std::cerr << "Couldn't open " << matfile << " for writing.\n";
exit(1); std::exit(EXIT_FAILURE);
} }
// write info about the model (dimensions and variables) // write info about the model (dimensions and variables)
@ -106,16 +102,15 @@ main(int argc, char **argv)
catch (const KordException &e) catch (const KordException &e)
{ {
// tell about the exception and continue // tell about the exception and continue
printf("Caught (not yet fatal) Kord exception: "); std::cout << "Caught (not yet fatal) Kord exception: ";
e.print(); e.print();
JournalRecord rec(journal); JournalRecord rec(journal);
rec << "Solution routine not finished (" << e.get_message() rec << "Solution routine not finished (" << e.get_message()
<< "), see what happens" << endrec; << "), see what happens" << endrec;
} }
std::string ss_matrix_name(params.prefix); std::string ss_matrix_name(params.prefix + "_steady_states");
ss_matrix_name += "_steady_states"; ConstTwoDMatrix(app.getSS()).writeMat(matfd, ss_matrix_name);
ConstTwoDMatrix(app.getSS()).writeMat(matfd, ss_matrix_name.c_str());
// check the approximation // check the approximation
if (params.check_along_path || params.check_along_shocks if (params.check_along_path || params.check_along_shocks
@ -176,42 +171,41 @@ main(int argc, char **argv)
} }
Mat_Close(matfd); Mat_Close(matfd);
} }
catch (const KordException &e) catch (const KordException &e)
{ {
printf("Caught Kord exception: "); std::cout << "Caught Kord exception: ";
e.print(); e.print();
return e.code(); return e.code();
} }
catch (const TLException &e) catch (const TLException &e)
{ {
printf("Caught TL exception: "); std::cout << "Caught TL exception: ";
e.print(); e.print();
return 255; return 255;
} }
catch (SylvException &e) catch (SylvException &e)
{ {
printf("Caught Sylv exception: "); std::cout << "Caught Sylv exception: ";
e.printMessage(); e.printMessage();
return 255; return 255;
} }
catch (const DynareException &e) catch (const DynareException &e)
{ {
printf("Caught Dynare exception: %s\n", e.message().c_str()); std::cout << "Caught Dynare exception: " << e.message() << '\n';
return 255; return 255;
} }
catch (const ogu::Exception &e) catch (const ogu::Exception &e)
{ {
printf("Caught ogu::Exception: "); std::cout << "Caught ogu::Exception: ";
e.print(); e.print();
return 255; return 255;
} }
catch (const ogp::ParserException &e) catch (const ogp::ParserException &e)
{ {
std::cout << "Caught parser exception: " << e.message() << std::endl; std::cout << "Caught parser exception: " << e.message() << '\n';
return 255; return 255;
} }
return 0; return EXIT_SUCCESS;
} }

View File

@ -5,6 +5,9 @@
#include "nlsolve.hh" #include "nlsolve.hh"
#include "dynare_exception.hh" #include "dynare_exception.hh"
#include <sstream>
#include <iomanip>
using namespace ogu; using namespace ogu;
double double
@ -50,10 +53,8 @@ GoldenSectionSearch::search(OneDFunction &f, double x1, double x2)
{ {
// x is on the right from b // x is on the right from b
if (f1 > fb && fb < fx) if (f1 > fb && fb < fx)
{ // pickup bracket [f1,fb,fx]
// pickup bracket [f1,fb,fx] x2 = x;
x2 = x;
}
else else
{ {
// pickup bracket [fb,fx,f2] // pickup bracket [fb,fx,f2]
@ -201,7 +202,6 @@ NLSolver::solve(Vector &xx, int &iter)
rec << "Iter lambda residual" << endrec; rec << "Iter lambda residual" << endrec;
JournalRecord rec1(journal); JournalRecord rec1(journal);
rec1 << u8"───────────────────────────" << endrec; rec1 << u8"───────────────────────────" << endrec;
char tmpbuf[14];
x = const_cast<const Vector &>(xx); x = const_cast<const Vector &>(xx);
iter = 0; iter = 0;
@ -213,8 +213,13 @@ NLSolver::solve(Vector &xx, int &iter)
"Initial guess does not yield finite residual in NLSolver::solve"); "Initial guess does not yield finite residual in NLSolver::solve");
bool converged = fx.getMax() < tol; bool converged = fx.getMax() < tol;
JournalRecord rec2(journal); JournalRecord rec2(journal);
sprintf(tmpbuf, "%10.6g", fx.getMax()); auto format_double = [](double v)
rec2 << iter << " N/A " << tmpbuf << endrec; {
std::ostringstream buf;
buf << std::setw(11) << v;
return buf.str();
};
rec2 << iter << " N/A " << format_double(fx.getMax()) << endrec;
while (!converged && iter < max_iter) while (!converged && iter < max_iter)
{ {
// setup Jacobian // setup Jacobian
@ -246,8 +251,7 @@ NLSolver::solve(Vector &xx, int &iter)
iter++; iter++;
JournalRecord rec3(journal); JournalRecord rec3(journal);
sprintf(tmpbuf, "%10.6g", fx.getMax()); rec3 << iter << " " << lambda << " " << format_double(fx.getMax()) << endrec;
rec3 << iter << " " << lambda << " " << tmpbuf << endrec;
} }
xx = const_cast<const Vector &>(x); xx = const_cast<const Vector &>(x);

View File

@ -159,11 +159,11 @@ PlannerBuilder::shift_derivatives_of_f()
// make an auxiliary variable // make an auxiliary variable
std::string name; std::string name;
name = "AUX_" + std::to_string(yi) + '_' + std::to_string(fset[fi]) + '_' + std::to_string(-ll); name = "AUX_" + std::to_string(yi) + '_' + std::to_string(fset[fi]) + '_' + std::to_string(-ll);
model.atoms.register_uniq_endo(name.c_str()); model.atoms.register_uniq_endo(name);
info.num_aux_variables++; info.num_aux_variables++;
int taux = model.eqs.add_nulary(name.c_str()); int taux = model.eqs.add_nulary(name);
name = "AUX_" + std::to_string(yi) + '_' + std::to_string(fset[fi]) + '_' + std::to_string(-ll) + '(' + std::to_string(-ll) + ')'; name = "AUX_" + std::to_string(yi) + '_' + std::to_string(fset[fi]) + '_' + std::to_string(-ll) + '(' + std::to_string(-ll) + ')';
int taux_leaded = model.eqs.add_nulary(name.c_str()); int taux_leaded = model.eqs.add_nulary(name);
// put aux_leaded to the equation // put aux_leaded to the equation
diff_f(yi, fi, ll-minlag) = taux_leaded; diff_f(yi, fi, ll-minlag) = taux_leaded;
// save auxiliary variable and the term // save auxiliary variable and the term
@ -244,8 +244,7 @@ PlannerBuilder::make_static_version()
for (const auto &it : aux_map) for (const auto &it : aux_map)
{ {
int tstatic = static_tree.add_substitution(it.second, tmap, model.eqs.getTree()); int tstatic = static_tree.add_substitution(it.second, tmap, model.eqs.getTree());
const char *name = static_atoms.get_name_storage().query(it.first); static_aux_map.emplace(it.first, tstatic);
static_aux_map.emplace(name, tstatic);
} }
} }
@ -257,7 +256,7 @@ PlannerBuilder::lagrange_mult_f()
for (int fi = 0; fi < diff_f.dim2(); fi++) for (int fi = 0; fi < diff_f.dim2(); fi++)
{ {
mult_name = "MULT" + std::to_string(fset[fi]); mult_name = "MULT" + std::to_string(fset[fi]);
model.atoms.register_uniq_endo(mult_name.c_str()); model.atoms.register_uniq_endo(mult_name);
info.num_lagrange_mults++; info.num_lagrange_mults++;
} }
// multiply with the multipliers // multiply with the multipliers
@ -267,7 +266,7 @@ PlannerBuilder::lagrange_mult_f()
if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero) if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero)
{ {
mult_name = "MULT" + std::to_string(fset[fi]) + '(' + std::to_string(-ll) + ')'; mult_name = "MULT" + std::to_string(fset[fi]) + '(' + std::to_string(-ll) + ')';
int tm = model.eqs.add_nulary(mult_name.c_str()); int tm = model.eqs.add_nulary(mult_name);
diff_f(yi, fi, ll-minlag) diff_f(yi, fi, ll-minlag)
= model.eqs.add_binary(ogp::code_t::TIMES, tm, diff_f(yi, fi, ll-minlag)); = model.eqs.add_binary(ogp::code_t::TIMES, tm, diff_f(yi, fi, ll-minlag));
} }
@ -301,7 +300,7 @@ PlannerBuilder::fill_yset(const ogp::NameStorage &ns,
const PlannerBuilder::Tvarset &yyset) const PlannerBuilder::Tvarset &yyset)
{ {
for (auto it : yyset) for (auto it : yyset)
yset.insert(ns.query(it)); yset.insert(it);
} }
void void
@ -310,11 +309,11 @@ PlannerBuilder::fill_aux_map(const ogp::NameStorage &ns, const Tsubstmap &aaux_m
{ {
// fill aux_map // fill aux_map
for (auto it : aaux_map) for (auto it : aaux_map)
aux_map.emplace(ns.query(it.first), it.second); aux_map.insert(it);
// fill static_aux_map // fill static_aux_map
for (auto it : astatic_aux_map) for (auto it : astatic_aux_map)
static_aux_map.emplace(static_atoms.get_name_storage().query(it.first), it.second); static_aux_map.insert(it);
} }
MultInitSS::MultInitSS(const PlannerBuilder &pb, const Vector &pvals, Vector &yy) MultInitSS::MultInitSS(const PlannerBuilder &pb, const Vector &pvals, Vector &yy)
@ -358,7 +357,7 @@ MultInitSS::MultInitSS(const PlannerBuilder &pb, const Vector &pvals, Vector &yy
for (int fi = 0; fi < builder.diff_f_static.dim2(); fi++) for (int fi = 0; fi < builder.diff_f_static.dim2(); fi++)
{ {
std::string mult_name = "MULT" + std::to_string(builder.fset[fi]); std::string mult_name = "MULT" + std::to_string(builder.fset[fi]);
int iouter = builder.model.atoms.name2outer_endo(mult_name.c_str()); int iouter = builder.model.atoms.name2outer_endo(mult_name);
int iy = builder.model.atoms.outer2y_endo()[iouter]; int iy = builder.model.atoms.outer2y_endo()[iouter];
if (!std::isfinite(yy[iy])) if (!std::isfinite(yy[iy]))
yy[iy] = lambda[fi]; yy[iy] = lambda[fi];
@ -369,13 +368,13 @@ MultInitSS::MultInitSS(const PlannerBuilder &pb, const Vector &pvals, Vector &yy
{ {
const ogp::AtomSubstitutions::Toldnamemap &old2new const ogp::AtomSubstitutions::Toldnamemap &old2new
= builder.model.atom_substs->get_old2new(); = builder.model.atom_substs->get_old2new();
auto it = old2new.find(mult_name.c_str()); auto it = old2new.find(mult_name);
if (it != old2new.end()) if (it != old2new.end())
{ {
const ogp::AtomSubstitutions::Tshiftnameset &sset = it->second; const ogp::AtomSubstitutions::Tshiftnameset &sset = it->second;
for (const auto & itt : sset) for (const auto & itt : sset)
{ {
const char *newname = itt.first; const std::string &newname = itt.first;
int iouter = builder.model.atoms.name2outer_endo(newname); int iouter = builder.model.atoms.name2outer_endo(newname);
int iy = builder.model.atoms.outer2y_endo()[iouter]; int iy = builder.model.atoms.outer2y_endo()[iouter];
if (!std::isfinite(yy[iy])) if (!std::isfinite(yy[iy]))

View File

@ -146,7 +146,7 @@ namespace ogdyn
friend class MultInitSS; friend class MultInitSS;
public: public:
/** Type for a set of variable names. */ /** Type for a set of variable names. */
using Tvarset = unordered_set<const char *>; using Tvarset = unordered_set<string>;
/** Type for a set of equations. An equation is identified by /** Type for a set of equations. An equation is identified by
* an index to an equation in the equation vector given by * an index to an equation in the equation vector given by
* DynareModel::eqs. The tree index of the i-th formula is * DynareModel::eqs. The tree index of the i-th formula is

View File

@ -222,7 +222,7 @@ public:
for (int i = 0; i < sym.num(); i++) for (int i = 0; i < sym.num(); i++)
lname += '_' + std::to_string(sym[i]); lname += '_' + std::to_string(sym[i]);
ConstTwoDMatrix m(*(it.second)); ConstTwoDMatrix m(*(it.second));
m.writeMat(fd, lname.c_str()); m.writeMat(fd, lname);
} }
} }

View File

@ -104,7 +104,7 @@ TwoDMatrix::save(const std::string &fname) const
if (fd.fail()) if (fd.fail())
TL_RAISE("Cannot open file for writing in TwoDMatrix::save"); TL_RAISE("Cannot open file for writing in TwoDMatrix::save");
fd << std::setprecision(std::numeric_limits<double>::digits10 + 1); fd << std::setprecision(std::numeric_limits<double>::max_digits10);
for (int row = 0; row < nrows(); row++) for (int row = 0; row < nrows(); row++)
{ {