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

View File

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

View File

@ -1,16 +1,13 @@
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 = \
location.hh \
namelist.hh \
atom_assignings.cc \
atom_assignings.hh \
atom_substitutions.cc \
atom_substitutions.hh \
csv_parser.cc \
csv_parser.hh \
dynamic_atoms.cc \
dynamic_atoms.hh \
fine_atoms.cc \
@ -33,7 +30,7 @@ libparser_a_CPPFLAGS = -I../.. $(BOOST_CPPFLAGS)
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
$(YACC) -W -o$*_tab.cc $<

View File

@ -10,8 +10,9 @@
%code
{
#include "atom_assignings.hh"
#include <string>
void asgn_error(const char*);
void asgn_error(std::string);
int asgn_lex();
extern ogp::AtomAssignings* aparser;
}
@ -51,7 +52,7 @@ space : space BLANK | BLANK;
%%
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 <iostream>
#include <algorithm>
#include <sstream>
#include <iomanip>
using namespace ogp;
AtomAssignings::AtomAssignings(const AtomAssignings &aa, ogp::StaticAtoms &a)
: 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
@ -29,34 +27,30 @@ AtomAssignings *aparser;
/** The declaration of functions defined in asgn_ll.cc and asgn_tab.cc
* 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_parse();
extern location_type asgn_lloc;
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.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;
asgn_parse();
asgn__destroy_buffer(p);
}
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
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
int t;
@ -75,25 +69,26 @@ AtomAssignings::add_assignment_to_double(const char *name, double val)
order.push_back(t);
// add the double to the tree
char tmp[100];
sprintf(tmp, "%30.25g", val);
std::ostringstream buf;
buf << std::setprecision(std::numeric_limits<double>::max_digits10)
<< val;
try
{
expr.parse(strlen(tmp), tmp);
expr.parse(buf.str());
}
catch (const ParserException &e)
{
// 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
const char *ss = left_names.insert(name);
lname2expr.emplace(ss, order.size()-1);
left_names.insert(name);
lname2expr.emplace(std::move(name), order.size()-1);
}
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)
{
// 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
// expression tree before the expression is parsed.
// find the name in the atoms, make copy of name to be able to put
// '\0' at the end
auto *buf = new char[name_len+1];
strncpy(buf, str, name_len);
buf[name_len] = '\0';
// find the name in the atoms
string name = str.substr(0, name_len);
// if left hand side is a registered atom, insert it to tree
int t;
try
{
t = atoms.check(buf);
t = atoms.check(name);
if (t == -1)
t = expr.add_nulary(buf);
t = expr.add_nulary(name);
}
catch (const ParserException &e)
{
atoms.register_name(buf);
t = expr.add_nulary(buf);
atoms.register_name(name);
t = expr.add_nulary(name);
}
// register left hand side in order
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
try
{
expr.parse(right_len, str+right_off);
expr.parse(str.substr(right_off, right_len));
}
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
const char *ss = left_names.insert(buf);
if (lname2expr.find(ss) != lname2expr.end())
left_names.insert(name);
if (lname2expr.find(name) != lname2expr.end())
{
// 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);
}
lname2expr[ss] = order.size()-1;
// delete name
delete [] buf;
lname2expr[name] = order.size()-1;
}
void
@ -154,7 +144,7 @@ AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm)
// variables
for (const auto & it : mm)
{
const char *oldname = it.first;
const string &oldname = it.first;
const AtomSubstitutions::Tshiftnameset &sset = it.second;
if (!sset.empty())
{
@ -171,9 +161,9 @@ AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm)
// reference to the newly added formula
for (const auto & itt : sset)
{
const char *newname = itt.first;
const char *nn = left_names.insert(newname);
lname2expr.emplace(nn, expr.nformulas()-1);
const string &newname = itt.first;
left_names.insert(newname);
lname2expr.emplace(newname, expr.nformulas()-1);
}
}
}
@ -199,7 +189,7 @@ AtomAsgnEvaluator::setValues(EvalTree &et) const
double nan = std::numeric_limits<double>::quiet_NaN();
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);
if (t >= 0)
{
@ -213,7 +203,7 @@ AtomAsgnEvaluator::setValues(EvalTree &et) const
}
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);
if (t >= 0)
@ -238,7 +228,7 @@ AtomAsgnEvaluator::load(int i, double res)
}
double
AtomAsgnEvaluator::get_value(const char *name) const
AtomAsgnEvaluator::get_value(const string &name) const
{
auto it = aa.lname2expr.find(name);
if (it == aa.lname2expr.end())

View File

@ -14,7 +14,6 @@
namespace ogp
{
class AtomAsgnEvaluator;
/** This class represents atom assignments used in parameters
@ -26,7 +25,7 @@ namespace ogp
{
friend class AtomAsgnEvaluator;
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
* right hand sides. The atoms should be filled with names
* (preregistered). This is a responsibility of the caller. */
@ -53,14 +52,14 @@ namespace ogp
AtomAssignings(const AtomAssignings &aa, StaticAtoms &a);
virtual ~AtomAssignings() = default;
/** 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. */
void error(const char *mes);
void error(string mes);
/** Add an assignment of the given name to the given
* double. Can be called by a user, anytime. */
void add_assignment_to_double(const char *name, double val);
void add_assignment_to_double(string name, double val);
/** 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);
/** This applies old2new map (possibly from atom
* 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
* constrast endogenous variables are set initially to NaNs by
* 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
* also checks whether the i-th expression is an atom. If so,
* 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
* found among atoms, or there is no assignment for the atom,
* NaN is returned. */
double get_value(const char *name) const;
double get_value(const string &name) const;
};
};
#endif

View File

@ -9,46 +9,24 @@ using namespace ogp;
AtomSubstitutions::AtomSubstitutions(const AtomSubstitutions &as, const FineAtoms &oa,
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
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
new2old.emplace(newname, Tshiftname(oldname, tshift));
// insert to old2new map
auto it = old2new.find(oldname);
if (it != old2new.end())
it->second.emplace(newname, -tshift);
it->second.emplace(std::move(newname), -tshift);
else
{
Tshiftnameset snset;
snset.emplace(newname, -tshift);
old2new.emplace(oldname, snset);
snset.emplace(std::move(newname), -tshift);
old2new.emplace(std::move(oldname), snset);
}
// put to info
@ -59,14 +37,14 @@ void
AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot)
{
// create an external ordering of new_atoms from old_atoms
const vector<const char *> &oa_ext = old_atoms.get_allvar();
vector<const char *> na_ext;
for (auto oname : oa_ext)
const vector<string> &oa_ext = old_atoms.get_allvar();
vector<string> na_ext;
for (const auto &oname : oa_ext)
{
// add the old name itself
na_ext.push_back(oname);
// 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())
for (const auto & itt : it->second)
na_ext.push_back(itt.first);
@ -76,8 +54,8 @@ AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot)
new_atoms.parsing_finished(ot, na_ext);
}
const char *
AtomSubstitutions::get_new4old(const char *oldname, int tshift) const
string
AtomSubstitutions::get_new4old(const string &oldname, int tshift) const
{
auto it = old2new.find(oldname);
if (it != old2new.end())
@ -87,7 +65,7 @@ AtomSubstitutions::get_new4old(const char *oldname, int tshift) const
if (itt.second == -tshift)
return itt.first;
}
return nullptr;
return "";
}
void
@ -106,25 +84,25 @@ AtomSubstitutions::print() const
void
SAtoms::substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as)
{
const char *name;
string name;
int mlead, mlag;
endovarspan(mlead, mlag);
// 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);
// 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);
exovarspan(mlead, mlag);
// substitute all lagged exo
while (name = findExoWithLeadInInterval(mlag, -1))
while (!(name = findExoWithLeadInInterval(mlag, -1)).empty())
makeAuxVariables(name, -1, -1, mlag, fp, as);
// substitute all leaded exo
while (name = findExoWithLeadInInterval(1, mlead))
while (!(name = findExoWithLeadInInterval(1, mlead)).empty())
makeAuxVariables(name, 1, 1, mlead, fp, as);
// notify that substitution have been finished
@ -134,30 +112,30 @@ SAtoms::substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as)
void
SAtoms::substituteAllLagsAndExo1Leads(FormulaParser &fp, AtomSubstitutions &as)
{
const char *name;
string name;
int mlead, mlag;
endovarspan(mlead, mlag);
// 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);
exovarspan(mlead, mlag);
// substitute all lagged exo
while (name = findExoWithLeadInInterval(mlag, -1))
while (!(name = findExoWithLeadInInterval(mlag, -1)).empty())
makeAuxVariables(name, -1, -1, mlag, fp, as);
// substitute all leaded exo by 1
while (name = findExoWithLeadInInterval(1, 1))
while (!(name = findExoWithLeadInInterval(1, 1)).empty())
makeAuxVariables(name, 1, 1, 1, fp, as);
// notify that substitution have been finished
as.substitutions_finished(order_type);
}
const char *
SAtoms::findNameWithLeadInInterval(const vector<const char *> &names,
string
SAtoms::findNameWithLeadInInterval(const vector<string> &names,
int ll1, int ll2) const
{
for (auto name : names)
@ -165,7 +143,7 @@ SAtoms::findNameWithLeadInInterval(const vector<const char *> &names,
auto it = vars.find(name);
if (it != vars.end())
{
const DynamicAtoms::Tlagmap &lmap = (*it).second;
const DynamicAtoms::Tlagmap &lmap = it->second;
for (auto itt : lmap)
if (itt.first >= ll1 && itt.first <= ll2)
return name;
@ -173,29 +151,29 @@ SAtoms::findNameWithLeadInInterval(const vector<const char *> &names,
}
// nothing found
return nullptr;
return "";
}
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';
string absll = std::to_string(std::abs(ll));
int iter = 1;
do
{
out = string(str) + '_';
out = str + '_';
for (int i = 0; i < iter; i++)
out += c;
if (ll != 0)
out += absll;
iter++;
}
while (varnames.query(out.c_str()));
while (varnames.query(out));
}
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)
{
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)"
int tprev = index(name, start-step);
if (tprev == -1)
{
string tmp = string{name} + '(' + std::to_string(start-step) + ')';
tprev = fp.add_nulary(tmp.c_str());
}
tprev = fp.add_nulary(name + '(' + std::to_string(start-step) + ')');
int ll = start;
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
// different step), in this case do not add equation "a_m2(0)
// = a(-2)"
const char *newname;
string newname_str;
string newname, newname_str;
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);
newname = newname_str.c_str();
newname = newname_str;
register_uniq_endo(newname);
newname = varnames.query(newname);
string tmp = string{newname} + "(0)";
taux = fp.add_nulary(tmp.c_str());
taux = fp.add_nulary(newname + "(0)");
// add to substitutions
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)
{
// no "a(-3)", make t <-> a_m2(-1)
string tmp = string{newname} + '(' + std::to_string(step) + ')';
t = fp.add_nulary(tmp.c_str());
t = fp.add_nulary(newname + '(' + std::to_string(step) + ')');
}
else
{

View File

@ -30,10 +30,10 @@ namespace ogp
class AtomSubstitutions
{
public:
using Tshiftname = pair<const char *, int>;
using Tshiftmap = map<const char *, Tshiftname, ltstr>;
using Tshiftname = pair<string, int>;
using Tshiftmap = map<string, Tshiftname>;
using Tshiftnameset = set<Tshiftname>;
using Toldnamemap = map<const char *, Tshiftnameset, ltstr>;
using Toldnamemap = map<string, Tshiftnameset>;
protected:
/** This maps a new name to a shifted old name. This is, one
* entry looks as "a_m3 ==> a(-3)", saying that a variable
@ -76,15 +76,15 @@ namespace ogp
* substitution method of the new atoms. This says that the
* new name, say "a_m3" is a substitution of old name "a"
* shifted by -3. */
void add_substitution(const char *newname, const char *oldname, int tshift);
void add_substitution(string newname, string oldname, int tshift);
/** This is called when all substitutions are finished. This
* forms the new external ordering of the new atoms and calls
* parsing_finished() for the new atoms with the given ordering type. */
void substitutions_finished(VarOrdering::ord_type ot);
/** Returns a new name for old name and given tshift. For "a"
* and tshift=-3, it returns "a_m3". If there is no such
* substitution, it returns NULL. */
const char *get_new4old(const char *oldname, int tshift) const;
* substitution, it returns an empty string. */
string get_new4old(const string &oldname, int tshift) const;
/** Return new2old. */
const Tshiftmap &
get_new2old() const
@ -127,7 +127,6 @@ namespace ogp
{
}
SAtoms(const SAtoms &sa) = default;
~SAtoms() override = default;
/** This substitutes all lags and leads for all exogenous and
* all lags and leads greater than 1 for all endogenous
* variables. This is useful for perfect foresight problems
@ -140,14 +139,14 @@ namespace ogp
protected:
/** This finds an endogenous variable name which occurs between
* ll1 and ll2 included. */
const char *
string
findEndoWithLeadInInterval(int ll1, int ll2) const
{
return findNameWithLeadInInterval(get_endovars(), ll1, ll2);
}
/** This finds an exogenous variable name which occurs between
* ll1 and ll2 included. */
const char *
string
findExoWithLeadInInterval(int ll1, int ll2) const
{
return findNameWithLeadInInterval(get_exovars(), ll1, ll2);
@ -159,7 +158,7 @@ namespace ogp
* such form is already registered, one more character (either
* 'p' or 'm') is added and the test is performed again. The
* resulting name is returned in a string out. */
void attemptAuxName(const char *str, int ll, string &out) const;
void attemptAuxName(const string &str, int ll, string &out) const;
/** This makes auxiliary variables to eliminate all leads/lags
* greater/less than or equal to start up to the limit_lead
@ -170,13 +169,13 @@ namespace ogp
* atoms are created in this object. The auxiliary equations
* are created in the given FormulaParser. The value of step
* is allowed to be either -1 (lags) or +1 (leads). */
void makeAuxVariables(const char *name, int step, int start, int limit_lead,
void makeAuxVariables(const string &name, int step, int start, int limit_lead,
FormulaParser &fp, AtomSubstitutions &as);
private:
/** This is a worker routine for findEndoWithLeadInInterval
* and findExoWithLeadInInterval. */
const char *findNameWithLeadInInterval(const vector<const char *> &names,
int ll1, int ll2) const;
string findNameWithLeadInInterval(const vector<string> &names,
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;
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];
strcpy(str, i);
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);
name_store.push_back(name);
name_set.insert(std::move(name));
}
}
@ -104,15 +66,12 @@ Constants::get_constant_value(int t) const
if (it != cmap.end())
return it->second;
else
{
throw ogu::Exception(__FILE__, __LINE__,
"Tree index is not constant in Constants::get_constant_value");
return 0;
}
throw ogu::Exception(__FILE__, __LINE__,
"Tree index is not constant in Constants::get_constant_value");
}
int
Constants::check(const char *str) const
Constants::check(const string &str) const
{
double d = std::stod(str);
auto it = cinvmap.find(d);
@ -126,26 +85,11 @@ void
Constants::print() const
{
for (const auto &it : cmap)
printf("$%d: %8.4g\n", it.first, it.second);
}
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));
std::cout << "$" << it.first << ": " << it.second << "\n";
}
int
DynamicAtoms::check(const char *name) const
DynamicAtoms::check(const string &name) const
{
if (is_string_constant(name))
return Constants::check(name);
@ -154,12 +98,12 @@ DynamicAtoms::check(const char *name) const
}
int
DynamicAtoms::check_variable(const char *name) const
DynamicAtoms::check_variable(const string &name) const
{
string str;
int ll;
parse_variable(name, str, ll);
auto it = vars.find(str.c_str());
auto it = vars.find(str);
if (it != vars.end())
{
@ -172,7 +116,7 @@ DynamicAtoms::check_variable(const char *name) const
}
void
DynamicAtoms::assign(const char *name, int t)
DynamicAtoms::assign(const string &name, int t)
{
if (is_string_constant(name))
assign_constant(name, t);
@ -181,7 +125,7 @@ DynamicAtoms::assign(const char *name, int t)
}
void
DynamicAtoms::assign_constant(const char *name, int t)
DynamicAtoms::assign_constant(const string &name, int t)
{
double val = std::stod(name);
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)
void
DynamicAtoms::assign_variable(const char *name, int t)
DynamicAtoms::assign_variable(const string &name, int t)
{
int ll;
string str;
parse_variable(name, str, ll);
// 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
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))
throw ogu::Exception(__FILE__, __LINE__,
@ -226,14 +170,12 @@ DynamicAtoms::assign_variable(const char *varname, int ll, int t)
indices.emplace(t, varname);
nv++;
if (ll < minlag)
minlag = ll;
if (ll > maxlead)
maxlead = ll;
minlag = std::min(ll, minlag);
maxlead = std::max(ll, maxlead);
}
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);
if (it != vars.end())
@ -315,7 +257,7 @@ DynamicAtoms::varspan(int t, int &mlead, int &mlag) const
}
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);
if (vars.end() == it)
@ -332,11 +274,11 @@ DynamicAtoms::varspan(const char *name, int &mlead, int &mlag) const
}
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();
mlag = std::numeric_limits<int>::max();
for (auto name : names)
for (const auto &name : names)
{
int lag, lead;
varspan(name, lead, lag);
@ -348,11 +290,11 @@ DynamicAtoms::varspan(const vector<const char *> &names, int &mlead, int &mlag)
bool
DynamicAtoms::is_named_atom(int t) const
{
return (indices.end() != indices.find(t));
return indices.end() != indices.find(t);
}
int
DynamicAtoms::index(const char *name, int ll) const
DynamicAtoms::index(const string &name, int ll) const
{
auto it = vars.find(name);
if (vars.end() != it)
@ -366,14 +308,13 @@ DynamicAtoms::index(const char *name, int ll) const
}
bool
DynamicAtoms::is_referenced(const char *name) const
DynamicAtoms::is_referenced(const string &name) const
{
auto it = vars.find(name);
return it != vars.end();
return vars.find(name) != vars.end();
}
const DynamicAtoms::Tlagmap &
DynamicAtoms::lagmap(const char *name) const
DynamicAtoms::lagmap(const string &name) const
{
auto it = vars.find(name);
if (vars.end() == it)
@ -383,7 +324,7 @@ DynamicAtoms::lagmap(const char *name) const
return it->second;
}
const char *
const string &
DynamicAtoms::name(int t) const
{
auto it = indices.find(t);
@ -396,7 +337,7 @@ DynamicAtoms::name(int t) const
int
DynamicAtoms::lead(int t) const
{
const char *nam = name(t);
const string &nam = name(t);
const Tlagmap &lmap = lagmap(nam);
auto it = lmap.begin();
while (it != lmap.end() && it->second != t)
@ -410,32 +351,32 @@ DynamicAtoms::lead(int t) const
void
DynamicAtoms::print() const
{
printf("names:\n");
std::cout << "names:\n";
varnames.print();
printf("constants:\n");
std::cout << "constants:\n";
Constants::print();
printf("variables:\n");
std::cout << "variables:\n";
for (const auto & var : vars)
{
const Tlagmap &lmap = var.second;
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)
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
* analyzer. It can be either a variable or a double. So it is easy to
* recognize it by the first character. */
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');
}
VarOrdering::VarOrdering(const VarOrdering &vo, const vector<const char *> &vnames,
VarOrdering::VarOrdering(const VarOrdering &vo, const vector<string> &vnames,
const DynamicAtoms &a)
: 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),
@ -446,8 +387,7 @@ VarOrdering::VarOrdering(const VarOrdering &vo, const vector<const char *> &vnam
bool
VarOrdering::check(int t) const
{
auto it = positions.find(t);
return it != positions.end();
return positions.find(t) != positions.end();
}
int
@ -455,15 +395,10 @@ VarOrdering::get_pos_of(int t) const
{
auto it = positions.find(t);
if (it != positions.end())
{
return it->second;
}
return it->second;
else
{
throw ogu::Exception(__FILE__, __LINE__,
"Couldn't find the tree index in VarOrdering::get_pos_of");
return -1;
}
throw ogu::Exception(__FILE__, __LINE__,
"Couldn't find the tree index in VarOrdering::get_pos_of");
}
void
@ -487,7 +422,7 @@ VarOrdering::do_general(ord_type ordering)
for (unsigned int i = 0; i < varnames.size(); i++)
{
const char *ss = varnames[i];
const string &ss = varnames[i];
int lead;
int lag;
atoms.varspan(ss, lead, lag);
@ -516,10 +451,8 @@ VarOrdering::do_general(ord_type ordering)
y2o_both.push_back(i);
}
else
{
throw ogu::Exception(__FILE__, __LINE__,
"A wrong lag/lead of a variable in VarOrdering::do_pbspbfbf");
}
throw ogu::Exception(__FILE__, __LINE__,
"A wrong lag/lead of a variable in VarOrdering::do_pbspbfbf");
}
// here we fill ords according to ordering
@ -546,11 +479,9 @@ VarOrdering::do_general(ord_type ordering)
ords[6] = &pred_minus;
ords[7] = &both_minus;
}
else // BEWARE: when implementing a new ordering, check also a
{// code below setting y2outer
throw ogu::Exception(__FILE__, __LINE__,
"Ordering not implemented in VarOrdering::do_general");
}
else // BEWARE: when implementing a new ordering, check also the code below setting y2outer
throw ogu::Exception(__FILE__, __LINE__,
"Ordering not implemented in VarOrdering::do_general");
// make der_atoms and positions
int off = 0;
@ -652,18 +583,19 @@ VarOrdering::do_increasing_time()
void
VarOrdering::print() const
{
printf("nstat=%d, npred=%d, nboth=%d, nforw=%d\n", n_stat, n_pred, n_both, n_forw);
printf("der_atoms:\n");
std::cout << "nstat=" << n_stat << ", npred=" << n_pred << ", nboth=" << n_both
<< ", nforw=" << n_forw << "\n"
<< "der_atoms:\n";
for (int der_atom : der_atoms)
printf(" %d", der_atom);
printf("\nmap:\n");
std::cout << " " << der_atom;
std::cout << "\nmap:\n";
for (auto position : positions)
printf(u8" [%d→%d]", position.first, position.second);
printf("\ny2outer:\n");
std::cout << " [" << position.first << u8"" << position.second << "]";
std::cout << "\ny2outer:\n";
for (int i : y2outer)
printf(" %d", i);
printf("\nouter2y:\n");
std::cout << " " << i;
std::cout << "\nouter2y:\n";
for (int i : outer2y)
printf(" %d", i);
printf("\n");
std::cout << " " << i;
std::cout << "\n";
}

View File

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

View File

@ -9,21 +9,20 @@
using namespace ogp;
AllvarOuterOrdering::AllvarOuterOrdering(const vector<const char *> &allvar_outer,
AllvarOuterOrdering::AllvarOuterOrdering(const vector<string> &allvar_outer,
const FineAtoms &a)
: atoms(a), allvar(),
endo2all(a.get_endovars().size(), -1),
exo2all(a.get_exovars().size(), -1)
{
// 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 (s)
if (atoms.varnames.query(s))
allvar.push_back(s);
else
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
@ -62,54 +61,44 @@ AllvarOuterOrdering::AllvarOuterOrdering(const vector<const char *> &allvar_oute
AllvarOuterOrdering::AllvarOuterOrdering(const AllvarOuterOrdering &avo,
const FineAtoms &a)
: atoms(a), allvar(),
: atoms(a), allvar(avo.allvar),
endo2all(avo.endo2all),
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)
: DynamicAtoms(fa), params(), endovars(), exovars(),
endo_order(nullptr), exo_order(nullptr), allvar_order(nullptr),
der_atoms(fa.der_atoms),
endo_atoms_map(fa.endo_atoms_map),
exo_atoms_map(fa.exo_atoms_map)
{
// fill in params
for (auto param : fa.params)
for (const auto &param : fa.params)
{
const char *s = varnames.query(param);
if (!s)
if (!varnames.query(param))
throw ogu::Exception(__FILE__, __LINE__,
string("Parameter ") + param + " does not exist in FineAtoms copy cosntructor");
params.push_back(s);
param_outer_map.emplace(s, params.size()-1);
params.push_back(param);
param_outer_map.emplace(param, params.size()-1);
}
// fill in endovars
for (auto endovar : fa.endovars)
for (const auto &endovar : fa.endovars)
{
const char *s = varnames.query(endovar);
if (!s)
if (!varnames.query(endovar))
throw ogu::Exception(__FILE__, __LINE__,
string("Endo variable ") + endovar + " does not exist in FineAtoms copy constructor");
endovars.push_back(s);
endo_outer_map.emplace(s, endovars.size()-1);
endovars.push_back(endovar);
endo_outer_map.emplace(endovar, endovars.size()-1);
}
// fill in exovars
for (auto exovar : fa.exovars)
for (const auto &exovar : fa.exovars)
{
const char *s = varnames.query(exovar);
if (!s)
if (!varnames.query(exovar))
throw ogu::Exception(__FILE__, __LINE__,
string("Exo variable ") + exovar + " does not exist in FineAtoms copy cosntructor");
exovars.push_back(s);
exo_outer_map.emplace(s, exovars.size()-1);
exovars.push_back(exovar);
exo_outer_map.emplace(exovar, exovars.size()-1);
}
if (fa.endo_order)
@ -123,12 +112,12 @@ FineAtoms::FineAtoms(const FineAtoms &fa)
}
int
FineAtoms::check_variable(const char *name) const
FineAtoms::check_variable(const string &name) const
{
string str;
int ll;
parse_variable(name, str, ll);
if (varnames.query(str.c_str()))
if (varnames.query(str))
return DynamicAtoms::check_variable(name);
else
{
@ -152,7 +141,7 @@ FineAtoms::parsing_finished(VarOrdering::ord_type ot)
// by default, concatenate outer endo and outer exo and make it as
// 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(), exovars.begin(), exovars.end());
@ -161,13 +150,13 @@ FineAtoms::parsing_finished(VarOrdering::ord_type ot)
void
FineAtoms::parsing_finished(VarOrdering::ord_type ot,
const vector<const char *> allvar)
const vector<string> &allvar)
{
make_internal_orderings(ot);
allvar_order = std::make_unique<AllvarOuterOrdering>(allvar, *this);
}
const vector<const char *> &
const vector<string> &
FineAtoms::get_allvar() const
{
if (!allvar_order)
@ -367,7 +356,7 @@ FineAtoms::get_exo_atoms_map() const
}
int
FineAtoms::name2outer_param(const char *name) const
FineAtoms::name2outer_param(const string &name) const
{
auto it = param_outer_map.find(name);
if (it == param_outer_map.end())
@ -377,7 +366,7 @@ FineAtoms::name2outer_param(const char *name) const
}
int
FineAtoms::name2outer_endo(const char *name) const
FineAtoms::name2outer_endo(const string &name) const
{
auto it = endo_outer_map.find(name);
if (it == endo_outer_map.end())
@ -387,7 +376,7 @@ FineAtoms::name2outer_endo(const char *name) const
}
int
FineAtoms::name2outer_exo(const char *name) const
FineAtoms::name2outer_exo(const string &name) const
{
auto it = exo_outer_map.find(name);
if (it == exo_outer_map.end())
@ -397,7 +386,7 @@ FineAtoms::name2outer_exo(const char *name) const
}
int
FineAtoms::name2outer_allvar(const char *name) const
FineAtoms::name2outer_allvar(const string &name) const
{
if (!allvar_order)
throw ogu::Exception(__FILE__, __LINE__,
@ -419,33 +408,33 @@ FineAtoms::name2outer_allvar(const char *name) const
}
void
FineAtoms::register_uniq_endo(const char *name)
FineAtoms::register_uniq_endo(string name)
{
if (varnames.query(name))
throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.", 0);
const char *ss = varnames.insert(name);
endovars.push_back(ss);
endo_outer_map.emplace(ss, endovars.size()-1);
varnames.insert(name);
endovars.push_back(name);
endo_outer_map.emplace(std::move(name), endovars.size()-1);
}
void
FineAtoms::register_uniq_exo(const char *name)
FineAtoms::register_uniq_exo(string name)
{
if (varnames.query(name))
throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.", 0);
const char *ss = varnames.insert(name);
exovars.push_back(ss);
exo_outer_map.emplace(ss, exovars.size()-1);
varnames.insert(name);
exovars.push_back(name);
exo_outer_map.emplace(std::move(name), exovars.size()-1);
}
void
FineAtoms::register_uniq_param(const char *name)
FineAtoms::register_uniq_param(string name)
{
if (varnames.query(name))
throw ogp::ParserException(string("Parameter <")+name+"> is not unique.", 0);
const char *ss = varnames.insert(name);
params.push_back(ss);
param_outer_map.emplace(ss, params.size()-1);
varnames.insert(name);
params.push_back(name);
param_outer_map.emplace(std::move(name), params.size()-1);
}
void
@ -508,24 +497,24 @@ FineAtoms::print() const
DynamicAtoms::print();
if (endo_order)
{
printf("Endo ordering:\n");
std::cout << "Endo ordering:\n";
endo_order->print();
}
else
printf("Endo ordering not created.\n");
std::cout << "Endo ordering not created.\n";
if (exo_order)
{
printf("Exo ordering:\n");
std::cout << "Exo ordering:\n";
exo_order->print();
}
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++)
printf(u8"%d → %d\n", i, endo_atoms_map[i]);
printf("exo atoms map:\n");
std::cout << i << u8"" << endo_atoms_map[i] << "\n";
std::cout << "exo atoms map:\n";
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
{
public:
EndoVarOrdering1(const vector<const char *> &vnames, const DynamicAtoms &a)
EndoVarOrdering1(const vector<string> &vnames, const DynamicAtoms &a)
: VarOrdering(vnames, a)
{
}
EndoVarOrdering1(const EndoVarOrdering1 &vo, const vector<const char *> &vnames,
EndoVarOrdering1(const EndoVarOrdering1 &vo, const vector<string> &vnames,
const DynamicAtoms &a)
: VarOrdering(vo, vnames, a)
{
}
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);
}
@ -51,17 +51,17 @@ namespace ogp
class EndoVarOrdering2 : public VarOrdering
{
public:
EndoVarOrdering2(const vector<const char *> &vnames, const DynamicAtoms &a)
EndoVarOrdering2(const vector<string> &vnames, const DynamicAtoms &a)
: VarOrdering(vnames, a)
{
}
EndoVarOrdering2(const EndoVarOrdering2 &vo, const vector<const char *> &vnames,
EndoVarOrdering2(const EndoVarOrdering2 &vo, const vector<string> &vnames,
const DynamicAtoms &a)
: VarOrdering(vo, vnames, a)
{
}
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);
}
@ -78,17 +78,17 @@ namespace ogp
class ExoVarOrdering : public VarOrdering
{
public:
ExoVarOrdering(const vector<const char *> &vnames, const DynamicAtoms &a)
ExoVarOrdering(const vector<string> &vnames, const DynamicAtoms &a)
: VarOrdering(vnames, a)
{
}
ExoVarOrdering(const ExoVarOrdering &vo, const vector<const char *> &vnames,
ExoVarOrdering(const ExoVarOrdering &vo, const vector<string> &vnames,
const DynamicAtoms &a)
: VarOrdering(vo, vnames, a)
{
}
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);
}
@ -109,12 +109,12 @@ namespace ogp
{
protected:
/** 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. */
const FineAtoms &atoms;
/** The vector of all endo and exo variables in outer
* ordering. The pointers point to storage in atoms. */
vector<const char *> allvar;
vector<string> allvar;
/** The mapping from outer endogenous to outer all. For
* example endo2all[0] is the order of the first outer
* endogenous variable in the allvar ordering. */
@ -129,7 +129,7 @@ namespace ogp
* arbitrary storage, the storage is transformed to the atoms
* storage. An exception is thrown if either the list is not
* exhaustive, or some string is not a variable. */
AllvarOuterOrdering(const vector<const char *> &allvar_outer, const FineAtoms &a);
AllvarOuterOrdering(const vector<string> &allvar_outer, const FineAtoms &a);
/** Copy constructor using the storage of provided atoms. */
AllvarOuterOrdering(const AllvarOuterOrdering &allvar_outer, const FineAtoms &a);
/** Return endo2all mapping. */
@ -145,7 +145,7 @@ namespace ogp
return exo2all;
}
/** Return the allvar ordering. */
const vector<const char *> &
const vector<string> &
get_allvar() const
{
return allvar;
@ -175,23 +175,23 @@ namespace ogp
{
friend class AllvarOuterOrdering;
protected:
using Tvarintmap = map<const char *, int, ltstr>;
using Tvarintmap = map<string, int>;
private:
/** The vector of parameters names. The order gives the order
* 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
* ordering. */
Tvarintmap param_outer_map;
/** The vector of endogenous variables. This defines the order
* like parameters. */
vector<const char *> endovars;
vector<string> endovars;
/** A map mapping a name of an endogenous variable to an index
* in the outer ordering. */
Tvarintmap endo_outer_map;
/** The vector of exogenous variables. Also defines the order
* like parameters and endovars. */
vector<const char *> exovars;
vector<string> exovars;
/** A map mapping a name of an exogenous variable to an index
* in the outer ordering. */
Tvarintmap exo_outer_map;
@ -237,7 +237,7 @@ namespace ogp
* variable is declared by inserting it to
* DynamicAtoms::varnames. This is a responsibility of a
* 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. */
void
endovarspan(int &mlead, int &mlag) const
@ -254,19 +254,19 @@ namespace ogp
* one exogenous variable occurs. */
int num_exo_periods() const;
/** Return an (external) ordering of parameters. */
const vector<const char *> &
const vector<string> &
get_params() const
{
return params;
}
/** Return an external ordering of endogenous variables. */
const vector<const char *> &
const vector<string> &
get_endovars() const
{
return endovars;
}
/** Return an external ordering of exogenous variables. */
const vector<const char *> &
const vector<string> &
get_exovars() const
{
return exovars;
@ -282,20 +282,20 @@ namespace ogp
* inputing a different outer ordering of all variables. The
* ordering is input as a list of strings, their storage can
* be arbitrary. */
void parsing_finished(VarOrdering::ord_type ot, const vector<const char *> avo);
void parsing_finished(VarOrdering::ord_type ot, const vector<string> &avo);
/** Return the external ordering of all variables (endo and
* exo). This is either the second argument to
* parsing_finished or the default external ordering. This
* must be called only after parsing_finished. */
const vector<const char *>&get_allvar() const;
const vector<string> &get_allvar() const;
/** Return the map from outer ordering of endo variables to
* the allvar ordering. This must be called only after
* parsing_finished. */
const vector<int>&outer_endo2all() const;
const vector<int> &outer_endo2all() const;
/** Return the map from outer ordering of exo variables to
* the allvar ordering. This must be called only after
* parsing_finished. */
const vector<int>&outer_exo2all() const;
const vector<int> &outer_exo2all() const;
/** Return the atoms with respect to which we are going to
* differentiate. This must be called after
* parsing_finished. */
@ -340,20 +340,20 @@ namespace ogp
/** Return an index in the outer ordering of a given
* parameter. An exception is thrown if the name is not a
* parameter. */
int name2outer_param(const char *name) const;
int name2outer_param(const string &name) const;
/** Return an index in the outer ordering of a given
* endogenous variable. An exception is thrown if the name is not a
* and endogenous variable. */
int name2outer_endo(const char *name) const;
int name2outer_endo(const string &name) const;
/** Return an index in the outer ordering of a given
* exogenous variable. An exception is thrown if the name is not a
* and exogenous variable. */
int name2outer_exo(const char *name) const;
int name2outer_exo(const string &name) const;
/** Return an index in the outer ordering of all variables
* (endo and exo) for a given name. An exception is thrown if
* the name is not a variable. This must be called only after
* parsing_finished(). */
int name2outer_allvar(const char *name) const;
int name2outer_allvar(const string &name) const;
/** Return the number of endogenous variables at time t-1, these are state
* variables. */
int
@ -389,17 +389,17 @@ namespace ogp
* calls defines the endo outer ordering. The method is
* virtual, since a superclass may want to do some additional
* action. */
virtual void register_uniq_endo(const char *name);
virtual void register_uniq_endo(string name);
/** Register unique exogenous variable name. The order of
* calls defines the exo outer ordering. The method is
* virtual, since a superclass may want to do somem additional
* action. */
virtual void register_uniq_exo(const char *name);
virtual void register_uniq_exo(string name);
/** Register unique parameter name. The order of calls defines
* the param outer ordering. The method is
* virtual, since a superclass may want to do somem additional
* action. */
virtual void register_uniq_param(const char *name);
virtual void register_uniq_param(string name);
/** Debug print. */
void print() const override;
private:

View File

@ -10,8 +10,9 @@
%code
{
#include "formula_parser.hh"
#include <string>
void fmla_error(const char*);
void fmla_error(std::string);
int fmla_lex();
extern ogp::FormulaParser* fparser;
}
@ -76,7 +77,7 @@ extern ogp::FormulaParser* fparser;
%%
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
FormulaParser::add_nulary(const char *str)
FormulaParser::add_nulary(const string &str)
{
int t = -1;
try
@ -116,7 +116,7 @@ FormulaParser *fparser;
/** The declarations of functions defined in formula_ll.cc and
* 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 *);
int fmla_parse();
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
* end. */
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.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;
fmla_parse();
fmla__destroy_buffer(p);
}
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
@ -173,12 +169,12 @@ FormulaParser::print() const
atoms.print();
for (int formula : formulas)
{
printf("formula %d:\n", formula);
std::cout << "formula " << formula << ":\n";
otree.print_operation(formula);
}
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);
}
}
@ -261,9 +257,9 @@ FormulaDerivatives::print(const OperationTree &otree) const
{
for (const auto & it : ind2der)
{
printf("derivative ");
std::cout << "derivative ";
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]);
}
}
@ -409,10 +405,10 @@ FoldMultiIndex::offset() const
void
FoldMultiIndex::print() const
{
printf("[");
std::cout << "[";
for (int i = 0; i < ord; i++)
printf("%d ", data[i]);
printf("]");
std::cout << data[i] << ' ';
std::cout << "]";
}
int

View File

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

View File

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

View File

@ -11,7 +11,7 @@
{
#include "matrix_parser.hh"
void matrix_error(const char*);
void matrix_error(std::string);
int matrix_lex();
extern ogp::MatrixParser* mparser;
}
@ -63,9 +63,9 @@ one_row : NEW_ROW {mparser->start_row();} lod;
%%
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 "matrix_tab.hh"
#include <memory>
#include <algorithm>
using namespace ogp;
@ -18,26 +17,22 @@ MatrixParser *mparser;
/** The declaration of functions defined in matrix_ll.cc and
* 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 *);
int matrix_parse();
extern ogp::location_type matrix_lloc;
void
MatrixParser::parse(int length, const char *stream)
MatrixParser::parse(const string &stream)
{
// reinitialize the object
data.clear();
row_lengths.clear();
nc = 0;
// 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.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;
matrix_parse();
matrix__destroy_buffer(p);
@ -60,9 +55,9 @@ MatrixParser::start_row()
}
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

View File

@ -6,6 +6,7 @@
#define OGP_MATRIX_PARSER
#include <vector>
#include <string>
namespace ogp
{
@ -48,7 +49,7 @@ namespace ogp
return nc;
}
/** 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
* parser. */
void add_item(double v);
@ -56,7 +57,7 @@ namespace ogp
* parser. */
void start_row();
/** Process a parse error from the parser. */
void error(const char *mes) const;
void error(std::string mes) const;
/** Return begin iterator. */
MPIterator begin() const;
/** 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;
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
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++)
{
const char *name = da.get_name_storage().get_name(i);
const string &name = da.get_name_storage().get_name(i);
register_name(name);
int tnew = otree.add_nulary();
assign(name, tnew);
if (da.is_referenced(name))
{
const DynamicAtoms::Tlagmap &lmap = da.lagmap(name);
for (auto it : lmap)
for (const auto &it : lmap)
{
int told = it.second;
tmap.emplace(told, tnew);
@ -57,7 +31,7 @@ StaticAtoms::import_atoms(const DynamicAtoms &da, OperationTree &otree, Tintintm
}
int
StaticAtoms::check(const char *name) const
StaticAtoms::check(const string &name) const
{
if (DynamicAtoms::is_string_constant(name))
return Constants::check(name);
@ -66,7 +40,7 @@ StaticAtoms::check(const char *name) const
}
int
StaticAtoms::index(const char *name) const
StaticAtoms::index(const string &name) const
{
auto it = vars.find(name);
if (it == vars.end())
@ -75,18 +49,8 @@ StaticAtoms::index(const char *name) const
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
StaticAtoms::assign(const char *name, int t)
StaticAtoms::assign(const string &name, int t)
{
if (DynamicAtoms::is_string_constant(name))
{
@ -95,9 +59,9 @@ StaticAtoms::assign(const char *name, int t)
}
else
{
const char *ss = varnames.insert(name);
vars.emplace(ss, t);
indices.emplace(t, ss);
varnames.insert(name);
vars.emplace(name, t);
indices.emplace(t, name);
}
}
@ -105,26 +69,26 @@ vector<int>
StaticAtoms::variables() const
{
vector<int> res;
for (auto var : vars)
for (const auto &var : vars)
res.push_back(var.second);
return res;
}
void
StaticAtoms::register_name(const char *name)
StaticAtoms::register_name(string name)
{
const char *ss = varnames.insert(name);
varorder.push_back(ss);
varnames.insert(name);
varorder.push_back(std::move(name));
}
void
StaticAtoms::print() const
{
printf("constants:\n");
std::cout << "constants:\n";
Constants::print();
printf("variable names:\n");
std::cout << "variable names:\n";
varnames.print();
printf("map to tree indices:\n");
std::cout << "map to tree indices:\n";
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
{
protected:
using Tvarmap = map<const char *, int, ltstr>;
using Tinvmap = map<int, const char *>;
using Tvarmap = map<string, int>;
using Tinvmap = map<int, string>;
/** Storage for names. */
NameStorage varnames;
/** Outer order of variables. */
vector<const char *> varorder;
vector<string> varorder;
/** This is the map mapping a variable name to the tree
* index. */
Tvarmap vars;
@ -25,11 +25,7 @@ namespace ogp
* variable name. */
Tinvmap indices;
public:
StaticAtoms() : Atoms(), Constants(), varnames(), varorder(), vars()
{
}
/* Copy constructor. */
StaticAtoms(const StaticAtoms &a);
StaticAtoms() = default;
/** Conversion from DynamicAtoms. This takes all atoms from
* the DynamicAtoms and adds its static version. The new tree
* indices are allocated in the passed OperationTree. Whole
@ -51,10 +47,10 @@ namespace ogp
* constant is registered in Constants, it returns -1
* otherwise. If the name is not constant, it returns result
* from check_variable, which is implemented by a subclass. */
int check(const char *name) const override;
int check(const string &name) const override;
/** This assigns a given tree index to the variable name. The
* name should have been checked before the call. */
void assign(const char *name, int t) override;
void assign(const string &name, int t) override;
int
nvar() const override
{
@ -63,12 +59,9 @@ namespace ogp
/** This returns a vector of all variables. */
vector<int> variables() const override;
/** This returns a tree index of the given variable. */
int index(const char *name) const;
/** This returns a name from the given tree index. NULL is
* returned if the tree index doesn't exist. */
const char *inv_index(int t) const;
int index(const string &name) const;
/** This returns a name in a outer ordering. (There is no other ordering.) */
const char *
const string &
name(int i) const
{
return varorder[i];
@ -79,7 +72,7 @@ namespace ogp
* this, for example, to ensure uniqueness of the
* name. However, this method should be always called in
* overriding methods to do the registering job. */
virtual void register_name(const char *name);
virtual void register_name(string name);
/** Return the name storage to allow querying to other
* classes. */
const NameStorage &
@ -91,7 +84,7 @@ namespace ogp
/** This checks the variable. The implementing subclass might
* want to throw an exception if the variable has not been
* registered. */
virtual int check_variable(const char *name) const = 0;
virtual int check_variable(const string &name) const = 0;
};
};

View File

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

View File

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

View File

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

View File

@ -54,7 +54,7 @@ Dynare::Dynare(const std::string &modname, int ord, double sstol, Journal &jr)
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)
{
@ -86,13 +86,13 @@ Dynare::Dynare(const std::string &modname, int ord, double sstol, Journal &jr)
Dynare::Dynare(const std::vector<std::string> &endo,
const std::vector<std::string> &exo,
const std::vector<std::string> &par,
const char *equations, int len, int ord,
const std::string &equations, int ord,
double sstol, Journal &jr)
: journal(jr), md(1), ss_tol(sstol)
{
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)
{
@ -142,9 +142,8 @@ Dynare::writeMat(mat_t *fd, const std::string &prefix) const
void
Dynare::writeDump(const std::string &basename) const
{
std::string fname(basename);
fname += ".dump";
std::ofstream out(fname.c_str());
std::string fname(basename + ".dump");
std::ofstream out(fname);
model->dump_model(out);
out.close();
}
@ -271,7 +270,7 @@ DynareNameList::DynareNameList(const Dynare &dynare)
for (int i = 0; i < dynare.ny(); 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);
}
}
@ -290,7 +289,7 @@ DynareExogNameList::DynareExogNameList(const Dynare &dynare)
for (int i = 0; i < dynare.nexog(); 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);
}
}

View File

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

View File

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

View File

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

View File

@ -89,14 +89,14 @@ DynareModel::setInitOuter(const Vector &x)
void
DynareModel::print() const
{
printf("all atoms:\n");
std::cout << "all atoms:\n";
atoms.print();
printf("formulas:\n");
std::cout << "formulas:\n";
DebugOperationFormatter dof(*this);
for (int i = 0; i < eqs.nformulas(); 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);
}
}
@ -148,17 +148,17 @@ DynareModel::dump_model(std::ostream &os) const
}
void
DynareModel::add_name(const std::string &name, int flag)
DynareModel::add_name(std::string name, int flag)
{
if (flag == 1)
// endogenous
atoms.register_uniq_endo(name.c_str());
atoms.register_uniq_endo(name);
else if (flag == 2)
// exogenous
atoms.register_uniq_exo(name.c_str());
atoms.register_uniq_exo(name);
else if (flag == 3)
// parameter
atoms.register_uniq_param(name.c_str());
atoms.register_uniq_param(name);
else
throw DynareException(__FILE__, __LINE__, "Unrecognized flag value.");
}
@ -206,7 +206,7 @@ DynareModel::check_model() const
int
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)
|| atoms.is_constant(t))
throw DynareException(__FILE__, __LINE__,
@ -214,10 +214,7 @@ DynareModel::variable_shift(int t, int tshift)
int ll = atoms.lead(t) + tshift;
int res = atoms.index(name, ll);
if (res == -1)
{
std::string str = name + '(' + std::to_string(ll) + ')';
res = eqs.add_nulary(str.c_str());
}
res = eqs.add_nulary(name + '(' + std::to_string(ll) + ')');
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
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)
|| atoms.is_type(name, DynareDynamicAtoms::atype::exovar))
{
@ -278,7 +275,7 @@ DynareModel::get_nonlinear_subterms(int t) const
}
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),
// then we have to unassign it first
@ -326,7 +323,7 @@ DynareModel::final_job()
extern ogp::location_type dynglob_lloc;
DynareParser::DynareParser(const char *stream, int len, int ord)
DynareParser::DynareParser(const string &stream, int ord)
: DynareModel(),
pa_atoms(), paramset(pa_atoms),
ia_atoms(), initval(ia_atoms), vcov(),
@ -341,7 +338,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
// global parse
try
{
parse_glob(len, stream);
parse_glob(stream);
}
catch (const ogp::ParserException &e)
{
@ -351,7 +348,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
try
{
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)
{
@ -361,7 +358,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
try
{
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
throw ogp::ParserException("Model section not found.", 0);
}
@ -373,7 +370,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
try
{
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)
{
@ -383,7 +380,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
try
{
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)
{
@ -394,7 +391,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
{
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();
}
}
@ -406,8 +403,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
try
{
if (pldiscount_end > pldiscount_beg)
t_pldiscount = parse_pldiscount(pldiscount_end - pldiscount_beg,
stream + pldiscount_beg);
t_pldiscount = parse_pldiscount(stream.substr(pldiscount_beg, pldiscount_end - pldiscount_beg));
}
catch (const ogp::ParserException &e)
{
@ -417,7 +413,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord)
try
{
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)
{
@ -468,45 +464,45 @@ DynareParser::DynareParser(const DynareParser &dp)
}
void
DynareParser::add_name(const char *name, int flag)
DynareParser::add_name(string name, int flag)
{
DynareModel::add_name(name, flag);
// register with static atoms used for atom assignements
if (flag == 1)
// endogenous
ia_atoms.register_name(name);
ia_atoms.register_name(std::move(name));
else if (flag == 2)
// exogenous
ia_atoms.register_name(name);
ia_atoms.register_name(std::move(name));
else if (flag == 3)
{
// parameter
pa_atoms.register_name(name);
ia_atoms.register_name(name);
ia_atoms.register_name(std::move(name));
}
else
throw DynareException(__FILE__, __LINE__, "Unrecognized flag value.");
}
void
DynareParser::error(const char *mes)
DynareParser::error(string mes)
{
// throwing zero offset since this exception will be caugth at
// constructor
throw ogp::ParserException(mes, 0);
throw ogp::ParserException(std::move(mes), 0);
}
void
DynareParser::print() const
{
DynareModel::print();
printf("parameter atoms:\n");
std::cout << "parameter atoms:\n";
paramset.print();
printf("initval atoms:\n");
std::cout << "initval atoms:\n";
initval.print();
printf("model position: %d %d\n", model_beg, model_end);
printf("paramset position: %d %d\n", paramset_beg, paramset_end);
printf("initval position: %d %d\n", initval_beg, initval_end);
std::cout << "model position: " << model_beg << ' ' << model_end << '\n'
<< "paramset position: " << paramset_beg << ' ' << paramset_end << '\n'
<< "initval position: " << initval_beg << ' ' << initval_end << '\n';
}
/** 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
* 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_parse();
extern ogp::location_type dynglob_lloc;
void
DynareParser::parse_glob(int length, const char *stream)
DynareParser::parse_glob(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';
void *p = dynglob__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
void *p = dynglob__scan_string(stream.c_str());
dynare_parser = this;
dynglob_parse();
dynglob__destroy_buffer(p);
}
int
DynareParser::parse_order(int len, const char *str)
DynareParser::parse_order(const string &str)
{
auto buf = std::make_unique<char[]>(len+1);
std::copy_n(str, len, buf.get());
buf[len] = '\0';
int res;
sscanf(buf.get(), "%d", &res);
return res;
return std::stoi(str);
}
int
DynareParser::parse_pldiscount(int len, const char *str)
DynareParser::parse_pldiscount(const string &str)
{
auto buf = std::make_unique<char[]>(len+1);
std::copy_n(str, len, buf.get());
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);
if (!atoms.is_type(str, DynareDynamicAtoms::atype::param))
throw ogp::ParserException(std::string{"Name "} + str + " is not a parameter", 0);
int t = atoms.index(buf.get(), 0);
int t = atoms.index(str, 0);
if (t == -1)
t = eqs.add_nulary(buf.get());
t = eqs.add_nulary(str);
return t;
}
@ -571,8 +555,7 @@ DynareParser::calc_params()
for (unsigned int i = 0; i < atoms.get_params().size(); i++)
if (!std::isfinite((*param_vals)[i]))
printf("dynare++: warning: value for parameter %s is not finite\n",
atoms.get_params()[i]);
std::cout << "dynare++: warning: value for parameter " << atoms.get_params()[i] << " is not finite\n";
}
void
@ -613,8 +596,7 @@ DynareParser::calc_init()
for (unsigned int i = 0; i < atoms.get_endovars().size(); i++)
if (!std::isfinite((*init_vals)[i]))
printf("dynare++: warning: initval for <%s> is not finite\n",
atoms.get_endovars()[atoms.y2outer_endo()[i]]);
std::cout << "dynare++: warning: initval for <" << atoms.get_endovars()[atoms.y2outer_endo()[i]] << "> is not finite\n";
}
// this returns false for linear functions
@ -682,7 +664,7 @@ NLSelector::operator()(int t) const
DynareSPModel::DynareSPModel(const std::vector<std::string> &endo,
const std::vector<std::string> &exo,
const std::vector<std::string> &par,
const char *equations, int len,
const string &equations,
int ord)
: DynareModel()
{
@ -698,7 +680,7 @@ DynareSPModel::DynareSPModel(const std::vector<std::string> &endo,
add_name(it, 3);
// parse the equations
eqs.parse(len, equations);
eqs.parse(equations);
// parsing finished
atoms.parsing_finished(ogp::VarOrdering::bfspbfpb);
@ -843,7 +825,7 @@ MatlabSSWriter::write_atom_assignment(std::ostream &os) const
os << "% parameter values\n";
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);
if (t == -1)
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";
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
{
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";
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);
for (auto it : lmap)
{
@ -920,7 +902,7 @@ MatlabSSWriter::write_der1_assignment(std::ostream &os) const
for (int j : eam)
{
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 t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, j));
if (t != ogp::OperationTree::zero)
@ -963,7 +945,7 @@ DebugOperationFormatter::format_nulary(int t, std::ostream &os) const
else
{
int ll = a.lead(t);
std::string name{a.name(t)};
const std::string &name = a.name(t);
if (ll == 0)
os << name;
else

View File

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

View File

@ -160,11 +160,11 @@ DynareParams::DynareParams(int argc, char **argv)
break;
}
}
catch (std::invalid_argument)
catch (std::invalid_argument &)
{
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";
}

View File

@ -9,9 +9,11 @@
%code
{
#include <string>
#include "dynare_model.hh"
void dynglob_error(const char*);
void dynglob_error(std::string);
int dynglob_lex();
extern ogdyn::DynareParser* dynare_parser;
int symblist_flag;
@ -109,7 +111,7 @@ planner_discount : PLANNERDISCOUNT NAME SEMICOLON {
%%
void
dynglob_error(const char* mes)
dynglob_error(std::string 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
// add AUXLD_*_*_1 = f(x(+1)) to the model
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++;
const char *ss = model.atoms.get_name_storage().query(name.c_str());
int auxt = model.eqs.add_nulary(name.c_str());
int auxt = model.eqs.add_nulary(name);
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
// AUXLD_*_*_2 = AUXLD_*_*_1(+1) through
// 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)
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}
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++;
ss = model.atoms.get_name_storage().query(name.c_str());
auxt = model.eqs.add_nulary(name.c_str());
auxt = model.eqs.add_nulary(name);
// add AUXLD_*_*_{ll+1} = AUXLD_*_*_{ll}(+1)
model.eqs.add_formula(model.eqs.add_binary(ogp::code_t::MINUS, auxt, lastauxt_lead));
// 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,
// however, it is misleading, needs to be
// changed
aux_map.emplace(ss, lagt);
aux_map.emplace(name, lagt);
}
// 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);
ss = model.atoms.get_name_storage().query(name.c_str());
model.substitute_atom_for_term(ss, +1, t);
model.substitute_atom_for_term(name, +1, t);
}
}
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;
model.atoms.varspan(name, mlead, mlag);
for (int ll = 2; ll <= mlead; ll++)
{
int t = model.atoms.index(ss, ll);
int t = model.atoms.index(name, ll);
if (t != -1)
model.atoms.unassign_variable(ss, ll, t);
model.atoms.unassign_variable(name, ll, t);
}
}
void
ForwSubstBuilder::unassign_gt_1_leads()
{
const vector<const char *> &endovars = model.atoms.get_endovars();
for (auto endovar : endovars)
auto &endovars = model.atoms.get_endovars();
for (const auto &endovar : endovars)
unassign_gt_1_leads(endovar);
const vector<const char *> &exovars = model.atoms.get_exovars();
for (auto exovar : exovars)
auto &exovars = model.atoms.get_exovars();
for (const auto &exovar : exovars)
unassign_gt_1_leads(exovar);
}
@ -125,8 +121,5 @@ ForwSubstBuilder::ForwSubstBuilder(const ForwSubstBuilder &b, DynareModel &m)
: model(m)
{
for (auto it : b.aux_map)
{
const char *ss = m.atoms.get_name_storage().query(it.first);
aux_map.emplace(ss, it.second);
}
aux_map.insert(it);
}

View File

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

View File

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

View File

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

View File

@ -159,11 +159,11 @@ PlannerBuilder::shift_derivatives_of_f()
// make an auxiliary variable
std::string name;
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++;
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) + ')';
int taux_leaded = model.eqs.add_nulary(name.c_str());
int taux_leaded = model.eqs.add_nulary(name);
// put aux_leaded to the equation
diff_f(yi, fi, ll-minlag) = taux_leaded;
// save auxiliary variable and the term
@ -244,8 +244,7 @@ PlannerBuilder::make_static_version()
for (const auto &it : aux_map)
{
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(name, tstatic);
static_aux_map.emplace(it.first, tstatic);
}
}
@ -257,7 +256,7 @@ PlannerBuilder::lagrange_mult_f()
for (int fi = 0; fi < diff_f.dim2(); 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++;
}
// multiply with the multipliers
@ -267,7 +266,7 @@ PlannerBuilder::lagrange_mult_f()
if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero)
{
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)
= 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)
{
for (auto it : yyset)
yset.insert(ns.query(it));
yset.insert(it);
}
void
@ -310,11 +309,11 @@ PlannerBuilder::fill_aux_map(const ogp::NameStorage &ns, const Tsubstmap &aaux_m
{
// fill aux_map
for (auto it : aaux_map)
aux_map.emplace(ns.query(it.first), it.second);
aux_map.insert(it);
// fill static_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)
@ -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++)
{
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];
if (!std::isfinite(yy[iy]))
yy[iy] = lambda[fi];
@ -369,13 +368,13 @@ MultInitSS::MultInitSS(const PlannerBuilder &pb, const Vector &pvals, Vector &yy
{
const ogp::AtomSubstitutions::Toldnamemap &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())
{
const ogp::AtomSubstitutions::Tshiftnameset &sset = it->second;
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 iy = builder.model.atoms.outer2y_endo()[iouter];
if (!std::isfinite(yy[iy]))

View File

@ -146,7 +146,7 @@ namespace ogdyn
friend class MultInitSS;
public:
/** 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
* an index to an equation in the equation vector given by
* 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++)
lname += '_' + std::to_string(sym[i]);
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())
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++)
{