Dynare++ parser: various modernizations

time-shift
Sébastien Villemot 2019-04-19 17:09:04 +02:00
parent ee891948e0
commit 3915299334
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
29 changed files with 668 additions and 897 deletions

View File

@ -10,6 +10,7 @@
#include <limits> #include <limits>
#include <iostream> #include <iostream>
#include <algorithm>
using namespace ogp; using namespace ogp;
@ -19,7 +20,7 @@ AtomAssignings::AtomAssignings(const AtomAssignings &aa, ogp::StaticAtoms &a)
{ {
// fill the lname2expr // fill the lname2expr
for (auto it : aa.lname2expr) for (auto it : aa.lname2expr)
lname2expr.insert(Tvarintmap::value_type(left_names.query(it.first), it.second)); lname2expr.emplace(left_names.query(it.first), it.second);
} }
/** A global symbol for passing info to the AtomAssignings from /** A global symbol for passing info to the AtomAssignings from
@ -36,16 +37,15 @@ extern location_type asgn_lloc;
void void
AtomAssignings::parse(int length, const char *stream) AtomAssignings::parse(int length, const char *stream)
{ {
auto *buffer = new char[length+2]; auto buffer = std::make_unique<char[]>(length+2);
strncpy(buffer, stream, length); std::copy_n(stream, length, buffer.get());
buffer[length] = '\0'; buffer[length] = '\0';
buffer[length+1] = '\0'; buffer[length+1] = '\0';
asgn_lloc.off = 0; asgn_lloc.off = 0;
asgn_lloc.ll = 0; asgn_lloc.ll = 0;
void *p = asgn__scan_buffer(buffer, (unsigned int) length+2); void *p = asgn__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
aparser = this; aparser = this;
asgn_parse(); asgn_parse();
delete [] buffer;
asgn__destroy_buffer(p); asgn__destroy_buffer(p);
} }
@ -89,7 +89,7 @@ AtomAssignings::add_assignment_to_double(const char *name, double val)
// register name of the left hand side and put to lname2expr // register name of the left hand side and put to lname2expr
const char *ss = left_names.insert(name); const char *ss = left_names.insert(name);
lname2expr.insert(Tvarintmap::value_type(ss, order.size()-1)); lname2expr.emplace(ss, order.size()-1);
} }
void void
@ -173,7 +173,7 @@ AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm)
{ {
const char *newname = itt.first; const char *newname = itt.first;
const char *nn = left_names.insert(newname); const char *nn = left_names.insert(newname);
lname2expr.insert(Tvarintmap::value_type(nn, expr.nformulas()-1)); lname2expr.emplace(nn, expr.nformulas()-1);
} }
} }
} }
@ -182,11 +182,11 @@ AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm)
void void
AtomAssignings::print() const AtomAssignings::print() const
{ {
printf("Atom Assignings\nExpressions:\n"); std::cout << "Atom Assignings\nExpressions:\n";
expr.print(); expr.print();
printf("Left names:\n"); std::cout << "Left names:\n";
for (auto it : lname2expr) for (auto it : lname2expr)
printf("%s ==> %d (t=%d)\n", it.first, expr.formula(it.second), order[it.second]); std::cout << it.first << u8"" << expr.formula(it.second) << " (t=" << order[it.second] << ")\n";
} }
void void
@ -207,7 +207,7 @@ AtomAsgnEvaluator::setValues(EvalTree &et) const
if (it == user_values.end()) if (it == user_values.end())
et.set_nulary(t, nan); et.set_nulary(t, nan);
else else
et.set_nulary(t, (*it).second); et.set_nulary(t, it->second);
} }
} }
} }
@ -220,9 +220,9 @@ AtomAsgnEvaluator::set_user_value(const char *name, double val)
{ {
auto it = user_values.find(t); auto it = user_values.find(t);
if (it == user_values.end()) if (it == user_values.end())
user_values.insert(Tusrvalmap::value_type(t, val)); user_values.emplace(t, val);
else else
(*it).second = val; it->second = val;
} }
} }
@ -244,5 +244,5 @@ AtomAsgnEvaluator::get_value(const char *name) const
if (it == aa.lname2expr.end()) if (it == aa.lname2expr.end())
return std::numeric_limits<double>::quiet_NaN(); return std::numeric_limits<double>::quiet_NaN();
else else
return operator[]((*it).second); return operator[](it->second);
} }

View File

@ -51,8 +51,7 @@ namespace ogp
/** Make a copy with provided reference to (posibly different) /** Make a copy with provided reference to (posibly different)
* static atoms. */ * static atoms. */
AtomAssignings(const AtomAssignings &aa, StaticAtoms &a); AtomAssignings(const AtomAssignings &aa, StaticAtoms &a);
virtual ~AtomAssignings() virtual ~AtomAssignings() = default;
= default;
/** Parse the assignments from the given string. */ /** Parse the assignments from the given string. */
void parse(int length, const char *stream); void parse(int length, const char *stream);
/** Process a syntax error from bison. */ /** Process a syntax error from bison. */
@ -97,8 +96,7 @@ namespace ogp
std::vector<double>(a.expr.nformulas()), aa(a) std::vector<double>(a.expr.nformulas()), aa(a)
{ {
} }
~AtomAsgnEvaluator() ~AtomAsgnEvaluator() override = default;
override = default;
/** This sets all initial values to NaNs, all constants and /** This sets all initial values to NaNs, all constants and
* all values set by user by call set_value. This is called by * all values set by user by call set_value. This is called by
* FormulaEvaluator::eval() method, which is called by eval() * FormulaEvaluator::eval() method, which is called by eval()

View File

@ -15,16 +15,16 @@ AtomSubstitutions::AtomSubstitutions(const AtomSubstitutions &as, const FineAtom
// fill new2old // fill new2old
for (const auto & it : as.new2old) for (const auto & it : as.new2old)
new2old.insert(Tshiftmap::value_type(ns.query(it.first), new2old.emplace(ns.query(it.first),
Tshiftname(ns.query(it.second.first), Tshiftname(ns.query(it.second.first),
it.second.second))); it.second.second));
// fill old2new // fill old2new
for (const auto & it : as.old2new) for (const auto & it : as.old2new)
{ {
Tshiftnameset sset; Tshiftnameset sset;
for (const auto & itt : it.second) for (const auto & itt : it.second)
sset.insert(Tshiftname(ns.query(itt.first), itt.second)); sset.emplace(ns.query(itt.first), itt.second);
old2new.insert(Toldnamemap::value_type(ns.query(it.first), sset)); old2new.emplace(ns.query(it.first), sset);
} }
} }
@ -34,21 +34,21 @@ AtomSubstitutions::add_substitution(const char *newname, const char *oldname, in
// make sure the storage is from the new_atoms // make sure the storage is from the new_atoms
newname = new_atoms.get_name_storage().query(newname); newname = new_atoms.get_name_storage().query(newname);
oldname = new_atoms.get_name_storage().query(oldname); oldname = new_atoms.get_name_storage().query(oldname);
if (newname == nullptr || oldname == nullptr) if (!newname || !oldname)
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
"Bad newname or oldname in AtomSubstitutions::add_substitution"); "Bad newname or oldname in AtomSubstitutions::add_substitution");
// insert to new2old map // insert to new2old map
new2old.insert(Tshiftmap::value_type(newname, Tshiftname(oldname, tshift))); new2old.emplace(newname, Tshiftname(oldname, tshift));
// insert to old2new map // insert to old2new map
auto it = old2new.find(oldname); auto it = old2new.find(oldname);
if (it != old2new.end()) if (it != old2new.end())
(*it).second.insert(Tshiftname(newname, -tshift)); it->second.emplace(newname, -tshift);
else else
{ {
Tshiftnameset snset; Tshiftnameset snset;
snset.insert(Tshiftname(newname, -tshift)); snset.emplace(newname, -tshift);
old2new.insert(Toldnamemap::value_type(oldname, snset)); old2new.emplace(oldname, snset);
} }
// put to info // put to info
@ -68,7 +68,7 @@ AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot)
// add all new names derived from the old name // add all new names derived from the old name
Toldnamemap::const_iterator it = old2new.find(oname); Toldnamemap::const_iterator it = old2new.find(oname);
if (it != old2new.end()) if (it != old2new.end())
for (const auto & itt : (*it).second) for (const auto & itt : it->second)
na_ext.push_back(itt.first); na_ext.push_back(itt.first);
} }
@ -82,7 +82,7 @@ AtomSubstitutions::get_new4old(const char *oldname, int tshift) const
auto it = old2new.find(oldname); auto it = old2new.find(oldname);
if (it != old2new.end()) if (it != old2new.end())
{ {
const Tshiftnameset &sset = (*it).second; const Tshiftnameset &sset = it->second;
for (const auto & itt : sset) for (const auto & itt : sset)
if (itt.second == -tshift) if (itt.second == -tshift)
return itt.first; return itt.first;
@ -93,15 +93,14 @@ AtomSubstitutions::get_new4old(const char *oldname, int tshift) const
void void
AtomSubstitutions::print() const AtomSubstitutions::print() const
{ {
printf("Atom Substitutions:\nOld ==> New:\n"); std::cout << u8"Atom Substitutions:\nOld ⇒ New:\n";
for (const auto & it : old2new) for (const auto & it : old2new)
for (auto itt = it.second.begin(); for (const auto &itt : it.second)
itt != it.second.end(); ++itt) std::cout << " " << it.first << u8" ⇒ [" << itt.first << ", " << itt.second << "]\n";
printf(" %s ==> [%s, %d]\n", it.first, (*itt).first, (*itt).second);
printf("Old <== New:\n"); std::cout << u8"Old ⇐ New:\n";
for (const auto & it : new2old) for (const auto & it : new2old)
printf(" [%s, %d] <== %s\n", it.second.first, it.second.second, it.first); std::cout << " [" << it.second.first << ", " << it.second.second << "] ⇐ " << it.first << '\n';
} }
void void
@ -113,19 +112,19 @@ SAtoms::substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as)
endovarspan(mlead, mlag); endovarspan(mlead, mlag);
// substitute all endo lagged more than 1 // substitute all endo lagged more than 1
while (nullptr != (name = findEndoWithLeadInInterval(mlag, -2))) while (name = findEndoWithLeadInInterval(mlag, -2))
makeAuxVariables(name, -1, -2, mlag, fp, as); makeAuxVariables(name, -1, -2, mlag, fp, as);
// substitute all endo leaded more than 1 // substitute all endo leaded more than 1
while (nullptr != (name = findEndoWithLeadInInterval(2, mlead))) while (name = findEndoWithLeadInInterval(2, mlead))
makeAuxVariables(name, 1, 2, mlead, fp, as); makeAuxVariables(name, 1, 2, mlead, fp, as);
exovarspan(mlead, mlag); exovarspan(mlead, mlag);
// substitute all lagged exo // substitute all lagged exo
while (nullptr != (name = findExoWithLeadInInterval(mlag, -1))) while (name = findExoWithLeadInInterval(mlag, -1))
makeAuxVariables(name, -1, -1, mlag, fp, as); makeAuxVariables(name, -1, -1, mlag, fp, as);
// substitute all leaded exo // substitute all leaded exo
while (nullptr != (name = findExoWithLeadInInterval(1, mlead))) while (name = findExoWithLeadInInterval(1, mlead))
makeAuxVariables(name, 1, 1, mlead, fp, as); makeAuxVariables(name, 1, 1, mlead, fp, as);
// notify that substitution have been finished // notify that substitution have been finished
@ -141,16 +140,16 @@ SAtoms::substituteAllLagsAndExo1Leads(FormulaParser &fp, AtomSubstitutions &as)
endovarspan(mlead, mlag); endovarspan(mlead, mlag);
// substitute all endo lagged more than 1 // substitute all endo lagged more than 1
while (nullptr != (name = findEndoWithLeadInInterval(mlag, -2))) while (name = findEndoWithLeadInInterval(mlag, -2))
makeAuxVariables(name, -1, -2, mlag, fp, as); makeAuxVariables(name, -1, -2, mlag, fp, as);
exovarspan(mlead, mlag); exovarspan(mlead, mlag);
// substitute all lagged exo // substitute all lagged exo
while (nullptr != (name = findExoWithLeadInInterval(mlag, -1))) while (name = findExoWithLeadInInterval(mlag, -1))
makeAuxVariables(name, -1, -1, mlag, fp, as); makeAuxVariables(name, -1, -1, mlag, fp, as);
// substitute all leaded exo by 1 // substitute all leaded exo by 1
while (nullptr != (name = findExoWithLeadInInterval(1, 1))) while (name = findExoWithLeadInInterval(1, 1))
makeAuxVariables(name, 1, 1, 1, fp, as); makeAuxVariables(name, 1, 1, 1, fp, as);
// notify that substitution have been finished // notify that substitution have been finished
@ -181,8 +180,7 @@ void
SAtoms::attemptAuxName(const char *str, int ll, string &out) const SAtoms::attemptAuxName(const char *str, int ll, string &out) const
{ {
char c = (ll >= 0) ? ((ll == 0) ? 'e' : 'p') : 'm'; char c = (ll >= 0) ? ((ll == 0) ? 'e' : 'p') : 'm';
char absll[100]; string absll = std::to_string(std::abs(ll));
sprintf(absll, "%d", std::abs(ll));
int iter = 1; int iter = 1;
do do
{ {
@ -218,15 +216,13 @@ SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead,
// Comment to comments: name="a"; start=-3; step=-1; // Comment to comments: name="a"; start=-3; step=-1;
char tmp[500];
// recover tree index of a previous atom, i.e. set tprev to a tree // recover tree index of a previous atom, i.e. set tprev to a tree
// index of atom "a(-2)" // index of atom "a(-2)"
int tprev = index(name, start-step); int tprev = index(name, start-step);
if (tprev == -1) if (tprev == -1)
{ {
sprintf(tmp, "%s(%d)", name, start-step); string tmp = string{name} + '(' + std::to_string(start-step) + ')';
tprev = fp.add_nulary(tmp); tprev = fp.add_nulary(tmp.c_str());
} }
int ll = start; int ll = start;
@ -241,19 +237,19 @@ SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead,
const char *newname; const char *newname;
string newname_str; string newname_str;
int taux; int taux;
if (nullptr == (newname = as.get_new4old(name, ll-step))) if (!(newname = as.get_new4old(name, ll-step)))
{ {
attemptAuxName(name, ll-step, newname_str); attemptAuxName(name, ll-step, newname_str);
newname = newname_str.c_str(); newname = newname_str.c_str();
register_uniq_endo(newname); register_uniq_endo(newname);
newname = varnames.query(newname); newname = varnames.query(newname);
sprintf(tmp, "%s(0)", newname); string tmp = string{newname} + "(0)";
taux = fp.add_nulary(tmp); taux = fp.add_nulary(tmp.c_str());
// add to substitutions // add to substitutions
as.add_substitution(newname, name, ll-step); as.add_substitution(newname, name, ll-step);
// add equation "a_m2(0) = a(-2)", this is taux = tprev // add equation "a_m2(0) = a(-2)", this is taux = tprev
fp.add_formula(fp.add_binary(MINUS, taux, tprev)); fp.add_formula(fp.add_binary(code_t::MINUS, taux, tprev));
} }
else else
{ {
@ -273,8 +269,8 @@ SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead,
if (t == -1) if (t == -1)
{ {
// no "a(-3)", make t <-> a_m2(-1) // no "a(-3)", make t <-> a_m2(-1)
sprintf(tmp, "%s(%d)", newname, step); string tmp = string{newname} + '(' + std::to_string(step) + ')';
t = fp.add_nulary(tmp); t = fp.add_nulary(tmp.c_str());
} }
else else
{ {

View File

@ -22,8 +22,7 @@ namespace ogp
struct SubstInfo struct SubstInfo
{ {
int num_substs{0}; int num_substs{0};
SubstInfo() SubstInfo() = default;
= default;
}; };
/** This class tracks all atom substitutions during the job and /** This class tracks all atom substitutions during the job and
@ -72,8 +71,7 @@ namespace ogp
* of old atoms and new atoms, which are supposed to be * of old atoms and new atoms, which are supposed to be
* semantically same as the atoms from as. */ * semantically same as the atoms from as. */
AtomSubstitutions(const AtomSubstitutions &as, const FineAtoms &oa, FineAtoms &na); AtomSubstitutions(const AtomSubstitutions &as, const FineAtoms &oa, FineAtoms &na);
virtual ~AtomSubstitutions() virtual ~AtomSubstitutions() = default;
= default;
/** This is called during the substitution job from the /** This is called during the substitution job from the
* substitution method of the new atoms. This says that the * substitution method of the new atoms. This says that the
* new name, say "a_m3" is a substitution of old name "a" * new name, say "a_m3" is a substitution of old name "a"
@ -128,11 +126,8 @@ namespace ogp
: FineAtoms() : FineAtoms()
{ {
} }
SAtoms(const SAtoms &sa) SAtoms(const SAtoms &sa) = default;
~SAtoms() override = default;
= default;
~SAtoms()
override = default;
/** This substitutes all lags and leads for all exogenous and /** This substitutes all lags and leads for all exogenous and
* all lags and leads greater than 1 for all endogenous * all lags and leads greater than 1 for all endogenous
* variables. This is useful for perfect foresight problems * variables. This is useful for perfect foresight problems

View File

@ -2,7 +2,9 @@
#include "parser_exception.hh" #include "parser_exception.hh"
#include "location.hh" #include "location.hh"
#include "csv_tab.hh" #include "csv_tab.hh"
#include <cstring>
#include <memory>
#include <algorithm>
using namespace ogp; using namespace ogp;
@ -28,17 +30,16 @@ void
CSVParser::csv_parse(int length, const char *str) CSVParser::csv_parse(int length, const char *str)
{ {
// allocate temporary buffer and parse // allocate temporary buffer and parse
auto *buffer = new char[length+2]; auto buffer = std::make_unique<char[]>(length+2);
strncpy(buffer, str, length); std::copy_n(str, length, buffer.get());
buffer[length] = '\0'; buffer[length] = '\0';
buffer[length+1] = '\0'; buffer[length+1] = '\0';
csv_lloc.off = 0; csv_lloc.off = 0;
csv_lloc.ll = 0; csv_lloc.ll = 0;
parsed_string = buffer; parsed_string = buffer.get();
void *p = csv__scan_buffer(buffer, (unsigned int) length+2); void *p = csv__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
csv_parser = this; csv_parser = this;
::csv_parse(); ::csv_parse();
delete [] buffer;
csv__destroy_buffer(p); csv__destroy_buffer(p);
parsed_string = nullptr; parsed_string = nullptr;
} }

View File

@ -59,7 +59,7 @@ void
NameStorage::print() const NameStorage::print() const
{ {
for (auto i : name_store) for (auto i : name_store)
printf("%s\n", i); std::cout << i << '\n';
} }
void void
@ -69,7 +69,7 @@ Constants::import_constants(const Constants &c, OperationTree &otree, Tintintmap
{ {
int told = it.first; int told = it.first;
int tnew = otree.add_nulary(); int tnew = otree.add_nulary();
tmap.insert(Tintintmap::value_type(told, tnew)); tmap.emplace(told, tnew);
add_constant(tnew, it.second); add_constant(tnew, it.second);
} }
} }
@ -77,16 +77,15 @@ Constants::import_constants(const Constants &c, OperationTree &otree, Tintintmap
void void
Constants::setValues(EvalTree &et) const Constants::setValues(EvalTree &et) const
{ {
Tconstantmap::const_iterator it; for (const auto & it : cmap)
for (it = cmap.begin(); it != cmap.end(); ++it) et.set_nulary(it.first, it.second);
et.set_nulary((*it).first, (*it).second);
} }
void void
Constants::add_constant(int t, double val) Constants::add_constant(int t, double val)
{ {
cmap.insert(Tconstantmap::value_type(t, val)); cmap.emplace(t, val);
cinvmap.insert(Tconstantinvmap::value_type(val, t)); cinvmap.emplace(val, t);
} }
bool bool
@ -103,7 +102,7 @@ Constants::get_constant_value(int t) const
{ {
auto it = cmap.find(t); auto it = cmap.find(t);
if (it != cmap.end()) if (it != cmap.end())
return (*it).second; return it->second;
else else
{ {
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
@ -119,7 +118,7 @@ Constants::check(const char *str) const
sscanf(str, "%lf", &d); sscanf(str, "%lf", &d);
auto it = cinvmap.find(d); auto it = cinvmap.find(d);
if (it != cinvmap.end()) if (it != cinvmap.end())
return (*it).second; return it->second;
else else
return -1; return -1;
} }
@ -127,13 +126,11 @@ Constants::check(const char *str) const
void void
Constants::print() const Constants::print() const
{ {
Tconstantmap::const_iterator it; for (const auto &it : cmap)
for (it = cmap.begin(); it != cmap.end(); ++it) printf("$%d: %8.4g\n", it.first, it.second);
printf("$%d: %8.4g\n", (*it).first, (*it).second);
} }
DynamicAtoms::DynamicAtoms() DynamicAtoms::DynamicAtoms() = default;
= default;
DynamicAtoms::DynamicAtoms(const DynamicAtoms &da) DynamicAtoms::DynamicAtoms(const DynamicAtoms &da)
: Constants(da), : Constants(da),
@ -142,12 +139,10 @@ DynamicAtoms::DynamicAtoms(const DynamicAtoms &da)
{ {
// copy vars // copy vars
for (const auto & var : da.vars) for (const auto & var : da.vars)
vars.insert(Tvarmap::value_type(varnames.query(var.first), vars.emplace(varnames.query(var.first), var.second);
var.second));
// copy indices // copy indices
for (auto indice : da.indices) for (auto indice : da.indices)
indices.insert(Tindexmap::value_type(indice.first, indices.emplace(indice.first, varnames.query(indice.second));
varnames.query(indice.second)));
} }
int int
@ -169,10 +164,10 @@ DynamicAtoms::check_variable(const char *name) const
if (it != vars.end()) if (it != vars.end())
{ {
const Tlagmap &lmap = (*it).second; const Tlagmap &lmap = it->second;
auto itt = lmap.find(ll); auto itt = lmap.find(ll);
if (itt != lmap.end()) if (itt != lmap.end())
return (*itt).second; return itt->second;
} }
return -1; return -1;
} }
@ -218,19 +213,19 @@ DynamicAtoms::assign_variable(const char *varname, int ll, int t)
auto it = vars.find(varname); auto it = vars.find(varname);
if (it != vars.end()) if (it != vars.end())
{ {
Tlagmap &lmap = (*it).second; Tlagmap &lmap = it->second;
if (lmap.end() != lmap.find(ll)) if (lmap.end() != lmap.find(ll))
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
"Attempt to assign already allocated variable"); "Attempt to assign already allocated variable");
lmap.insert(Tlagmap::value_type(ll, t)); lmap.emplace(ll, t);
} }
else else
{ {
Tlagmap lmap; Tlagmap lmap;
lmap.insert(Tlagmap::value_type(ll, t)); lmap.emplace(ll, t);
vars.insert(Tvarmap::value_type(varname, lmap)); vars.emplace(varname, lmap);
} }
indices.insert(Tindexmap::value_type(t, varname)); indices.emplace(t, varname);
nv++; nv++;
if (ll < minlag) if (ll < minlag)
@ -245,11 +240,11 @@ DynamicAtoms::unassign_variable(const char *varname, int ll, int t)
auto it = vars.find(varname); auto it = vars.find(varname);
if (it != vars.end()) if (it != vars.end())
{ {
Tlagmap &lmap = (*it).second; Tlagmap &lmap = it->second;
auto itt = lmap.find(ll); auto itt = lmap.find(ll);
if (itt != lmap.end()) if (itt != lmap.end())
{ {
if ((*itt).second == t) if (itt->second == t)
{ {
// erase it from the lagmap; if it becomes empty, // erase it from the lagmap; if it becomes empty,
// erase the lagmap from varmap // erase the lagmap from varmap
@ -281,18 +276,16 @@ DynamicAtoms::unassign_variable(const char *varname, int ll, int t)
void void
DynamicAtoms::update_minmaxll() DynamicAtoms::update_minmaxll()
{ {
minlag = INT_MAX; minlag = std::numeric_limits<int>::max();
maxlead = INT_MIN; maxlead = std::numeric_limits<int>::min();
for (Tvarmap::const_iterator it = vars.begin(); it != vars.end(); ++it) for (const auto &it : vars)
{ {
const Tlagmap &lmap = (*it).second; const Tlagmap &lmap = it.second;
for (auto itt : lmap) for (auto itt : lmap)
{ {
int ll = itt.first; int ll = itt.first;
if (ll < minlag) minlag = std::min(ll, minlag);
minlag = ll; maxlead = std::max(ll, maxlead);
if (ll > maxlead)
maxlead = ll;
} }
} }
} }
@ -316,11 +309,11 @@ DynamicAtoms::varspan(int t, int &mlead, int &mlag) const
auto it = indices.find(t); auto it = indices.find(t);
if (indices.end() == it) if (indices.end() == it)
{ {
mlead = INT_MIN; mlead = std::numeric_limits<int>::min();
mlag = INT_MAX; mlag = std::numeric_limits<int>::max();
return; return;
} }
varspan((*it).second, mlead, mlag); varspan(it->second, mlead, mlag);
} }
void void
@ -329,30 +322,28 @@ DynamicAtoms::varspan(const char *name, int &mlead, int &mlag) const
auto it = vars.find(name); auto it = vars.find(name);
if (vars.end() == it) if (vars.end() == it)
{ {
mlead = INT_MIN; mlead = std::numeric_limits<int>::min();
mlag = INT_MAX; mlag = std::numeric_limits<int>::max();
return; return;
} }
const Tlagmap &lmap = (*it).second; const Tlagmap &lmap = it->second;
auto beg = lmap.begin(); auto beg = lmap.begin();
auto end = lmap.rbegin(); auto end = lmap.rbegin();
mlag = (*beg).first; mlag = beg->first;
mlead = (*end).first; mlead = end->first;
} }
void void
DynamicAtoms::varspan(const vector<const char *> &names, int &mlead, int &mlag) const DynamicAtoms::varspan(const vector<const char *> &names, int &mlead, int &mlag) const
{ {
mlead = INT_MIN; mlead = std::numeric_limits<int>::min();
mlag = INT_MAX; mlag = std::numeric_limits<int>::max();
for (auto name : names) for (auto name : names)
{ {
int lag, lead; int lag, lead;
varspan(name, lead, lag); varspan(name, lead, lag);
if (lead > mlead) mlead = std::max(lead, mlead);
mlead = lead; mlag = std::min(lag, mlag);
if (lag < mlag)
mlag = lag;
} }
} }
@ -368,10 +359,10 @@ DynamicAtoms::index(const char *name, int ll) const
auto it = vars.find(name); auto it = vars.find(name);
if (vars.end() != it) if (vars.end() != it)
{ {
const Tlagmap &lmap = (*it).second; const Tlagmap &lmap = it->second;
auto itt = lmap.find(ll); auto itt = lmap.find(ll);
if (lmap.end() != itt) if (lmap.end() != itt)
return (*itt).second; return itt->second;
} }
return -1; return -1;
} }
@ -391,7 +382,7 @@ DynamicAtoms::lagmap(const char *name) const
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
std::string("Couldn't find the name ") std::string("Couldn't find the name ")
+ name + " in DynamicAtoms::lagmap"); + name + " in DynamicAtoms::lagmap");
return (*it).second; return it->second;
} }
const char * const char *
@ -401,7 +392,7 @@ DynamicAtoms::name(int t) const
if (indices.end() == it) if (indices.end() == it)
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
"Couldn't find tree index in DynamicAtoms::name"); "Couldn't find tree index in DynamicAtoms::name");
return (*it).second; return it->second;
} }
int int
@ -410,12 +401,12 @@ DynamicAtoms::lead(int t) const
const char *nam = name(t); const char *nam = name(t);
const Tlagmap &lmap = lagmap(nam); const Tlagmap &lmap = lagmap(nam);
auto it = lmap.begin(); auto it = lmap.begin();
while (it != lmap.end() && (*it).second != t) while (it != lmap.end() && it->second != t)
++it; ++it;
if (lmap.end() == it) if (lmap.end() == it)
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
"Couldn't find the three index in DynamicAtoms::lead"); "Couldn't find the three index in DynamicAtoms::lead");
return (*it).first; return it->first;
} }
void void
@ -434,7 +425,7 @@ DynamicAtoms::print() const
} }
printf("indices:\n"); printf("indices:\n");
for (auto indice : indices) for (auto indice : indices)
printf("t=%d ==> %s\n", indice.first, indice.second); printf(u8"t=%d ⇒ %s\n", indice.first, indice.second);
} }
/** Note that the str has been parsed by the lexicographic /** Note that the str has been parsed by the lexicographic
@ -467,7 +458,7 @@ VarOrdering::get_pos_of(int t) const
auto it = positions.find(t); auto it = positions.find(t);
if (it != positions.end()) if (it != positions.end())
{ {
return (*it).second; return it->second;
} }
else else
{ {
@ -570,7 +561,7 @@ VarOrdering::do_general(ord_type ordering)
if ((*ord)[j] != -1) if ((*ord)[j] != -1)
{ {
der_atoms.push_back((*ord)[j]); der_atoms.push_back((*ord)[j]);
positions.insert(std::pair<int, int>((*ord)[j], off)); positions.emplace((*ord)[j], off);
} }
// set integer constants // set integer constants
@ -599,7 +590,7 @@ VarOrdering::do_increasing_time()
// setup the matrix of tree indices, if there is no occurrence, // setup the matrix of tree indices, if there is no occurrence,
// the index is set to -1 // the index is set to -1
vector<int> ll_init(varnames.size(), -1); vector<int> ll_init(varnames.size(), -1);
vector<vector<int> > tree_ind(mlead-mlag+1, ll_init); vector<vector<int>> tree_ind(mlead-mlag+1, ll_init);
for (unsigned int iv = 0; iv < varnames.size(); iv++) for (unsigned int iv = 0; iv < varnames.size(); iv++)
{ {
try try
@ -627,7 +618,7 @@ VarOrdering::do_increasing_time()
{ {
der_atoms.push_back(t); der_atoms.push_back(t);
int pos = (ll-mlag)*varnames.size() + iv; int pos = (ll-mlag)*varnames.size() + iv;
positions.insert(map<int, int>::value_type(t, pos)); positions.emplace(t, pos);
} }
} }
@ -644,31 +635,19 @@ VarOrdering::do_increasing_time()
int mmlag, mmlead; int mmlag, mmlead;
atoms.varspan(varname, mmlead, mmlag); atoms.varspan(varname, mmlead, mmlag);
if (mmlead == 0 && mmlag == 0) if (mmlead == 0 && mmlag == 0)
{ n_stat++;
n_stat++;
}
else if (mmlead <= 0 && mmlag < 0) else if (mmlead <= 0 && mmlag < 0)
{ n_pred++;
n_pred++;
}
else if (mmlead > 0 && mmlag >= 0) else if (mmlead > 0 && mmlag >= 0)
{ n_forw++;
n_forw++;
}
else if (mmlead > 0 && mmlag < 0) else if (mmlead > 0 && mmlag < 0)
{ n_both++;
n_both++;
}
else if (mmlead < mmlag) else if (mmlead < mmlag)
{ // variable does not occur in the tree, cound as static
// variable does not occur in the tree, cound as static n_stat++;
n_stat++;
}
else else
{ throw ogu::Exception(__FILE__, __LINE__,
throw ogu::Exception(__FILE__, __LINE__, "A wrong lag/lead of a variable in VarOrdering::do_increasing_time");
"A wrong lag/lead of a variable in VarOrdering::do_increasing_time");
}
} }
} }
@ -681,7 +660,7 @@ VarOrdering::print() const
printf(" %d", der_atom); printf(" %d", der_atom);
printf("\nmap:\n"); printf("\nmap:\n");
for (auto position : positions) for (auto position : positions)
printf(" [%d->%d]", position.first, position.second); printf(u8" [%d→%d]", position.first, position.second);
printf("\ny2outer:\n"); printf("\ny2outer:\n");
for (int i : y2outer) for (int i : y2outer)
printf(" %d", i); printf(" %d", i);

View File

@ -12,7 +12,8 @@
#include <set> #include <set>
#include <string> #include <string>
#include <cstring> #include <cstring>
#include <climits> #include <limits>
#include <memory>
namespace ogp namespace ogp
{ {
@ -45,11 +46,9 @@ namespace ogp
* allocated or not. */ * allocated or not. */
set<const char *, ltstr> name_set; set<const char *, ltstr> name_set;
public: public:
NameStorage() NameStorage() = default;
= default;
NameStorage(const NameStorage &stor); NameStorage(const NameStorage &stor);
virtual virtual ~NameStorage();
~NameStorage();
/** Query for the name. If the name has been stored, it /** Query for the name. If the name has been stored, it
* returns its address, otherwise 0. */ * returns its address, otherwise 0. */
const char *query(const char *name) const; const char *query(const char *name) const;
@ -59,7 +58,7 @@ namespace ogp
int int
num() const num() const
{ {
return (int) name_store.size(); return static_cast<int>(name_store.size());
} }
const char * const char *
get_name(int i) const get_name(int i) const
@ -80,8 +79,7 @@ namespace ogp
/** Map mapping a tree index of a constant to its double value. */ /** Map mapping a tree index of a constant to its double value. */
Tconstantmap cmap; Tconstantmap cmap;
public: public:
Constants() Constants() = default;
= default;
/** Copy constructor. */ /** Copy constructor. */
Constants(const Constants &c) Constants(const Constants &c)
: cmap(c.cmap), cinvmap(c.cinvmap) : cmap(c.cmap), cinvmap(c.cinvmap)
@ -162,15 +160,14 @@ namespace ogp
/** Number of variables. */ /** Number of variables. */
int nv{0}; int nv{0};
/** Minimum lag, if there is at least one lag, than this is a negative number. */ /** Minimum lag, if there is at least one lag, than this is a negative number. */
int minlag{INT_MAX}; int minlag{std::numeric_limits<int>::max()};
/** Maximum lead, if there is at least one lead, than this is a positive number. */ /** Maximum lead, if there is at least one lead, than this is a positive number. */
int maxlead{INT_MIN}; int maxlead{std::numeric_limits<int>::min()};
public: public:
/** Construct empty DynamicAtoms. */ /** Construct empty DynamicAtoms. */
DynamicAtoms(); DynamicAtoms();
DynamicAtoms(const DynamicAtoms &da); DynamicAtoms(const DynamicAtoms &da);
~DynamicAtoms() ~DynamicAtoms() override = default;
override = default;
/** Check the nulary term identified by its string /** Check the nulary term identified by its string
* representation. The nulary term can be either a constant or * representation. The nulary term can be either a constant or
* a variable. If constant, -1 is returned so that it could be * a variable. If constant, -1 is returned so that it could be
@ -326,7 +323,7 @@ namespace ogp
* follows: y(t-1), x(t-1), z(t-1), [y(t)], [x(t)], z(t), * follows: y(t-1), x(t-1), z(t-1), [y(t)], [x(t)], z(t),
* x(t+1), where a bracketed expresion means non-existent by * x(t+1), where a bracketed expresion means non-existent by
* occupying a space. The map thus will look as follows: * occupying a space. The map thus will look as follows:
* {5->0, 6->1, 3->2, 2->5, 3->6}. Note that nothing is mapped * {50, 61, 32, 25, 36}. Note that nothing is mapped
* to positions 3 and 4. */ * to positions 3 and 4. */
map<int, int> positions; map<int, int> positions;
/** This maps an ordering of the list of variables in /** This maps an ordering of the list of variables in
@ -358,11 +355,10 @@ namespace ogp
VarOrdering(const VarOrdering &vo, const vector<const char *> &vnames, VarOrdering(const VarOrdering &vo, const vector<const char *> &vnames,
const DynamicAtoms &a); const DynamicAtoms &a);
VarOrdering(const VarOrdering &vo) = delete; VarOrdering(const VarOrdering &vo) = delete;
virtual VarOrdering *clone(const vector<const char *> &vnames, virtual std::unique_ptr<VarOrdering> clone(const vector<const char *> &vnames,
const DynamicAtoms &a) const = 0; const DynamicAtoms &a) const = 0;
/** Destructor does nothing here. */ /** Destructor does nothing here. */
virtual ~VarOrdering() virtual ~VarOrdering() = default;
= default;
/** This is the method setting the ordering and the map. A /** This is the method setting the ordering and the map. A
* subclass must reimplement it, possibly using a * subclass must reimplement it, possibly using a
* preimplemented ordering. This method must be called by the * preimplemented ordering. This method must be called by the

View File

@ -31,12 +31,12 @@ AllvarOuterOrdering::AllvarOuterOrdering(const vector<const char *> &allvar_oute
{ {
auto it = atoms.endo_outer_map.find(allvar[i]); auto it = atoms.endo_outer_map.find(allvar[i]);
if (it != atoms.endo_outer_map.end()) if (it != atoms.endo_outer_map.end())
endo2all[(*it).second] = i; endo2all[it->second] = i;
else else
{ {
it = atoms.exo_outer_map.find(allvar[i]); it = atoms.exo_outer_map.find(allvar[i]);
if (it != atoms.exo_outer_map.end()) if (it != atoms.exo_outer_map.end())
exo2all[(*it).second] = i; exo2all[it->second] = i;
else else
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
string("Name ") + allvar[i] + " is neither endogenous nor exogenous variable in AllvarOuterOrdering constructor"); string("Name ") + allvar[i] + " is neither endogenous nor exogenous variable in AllvarOuterOrdering constructor");
@ -89,7 +89,7 @@ FineAtoms::FineAtoms(const FineAtoms &fa)
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
string("Parameter ") + param + " does not exist in FineAtoms copy cosntructor"); string("Parameter ") + param + " does not exist in FineAtoms copy cosntructor");
params.push_back(s); params.push_back(s);
param_outer_map.insert(Tvarintmap::value_type(s, params.size()-1)); param_outer_map.emplace(s, params.size()-1);
} }
// fill in endovars // fill in endovars
for (auto endovar : fa.endovars) for (auto endovar : fa.endovars)
@ -99,7 +99,7 @@ FineAtoms::FineAtoms(const FineAtoms &fa)
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
string("Endo variable ") + endovar + " does not exist in FineAtoms copy constructor"); string("Endo variable ") + endovar + " does not exist in FineAtoms copy constructor");
endovars.push_back(s); endovars.push_back(s);
endo_outer_map.insert(Tvarintmap::value_type(s, endovars.size()-1)); endo_outer_map.emplace(s, endovars.size()-1);
} }
// fill in exovars // fill in exovars
for (auto exovar : fa.exovars) for (auto exovar : fa.exovars)
@ -109,7 +109,7 @@ FineAtoms::FineAtoms(const FineAtoms &fa)
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
string("Exo variable ") + exovar + " does not exist in FineAtoms copy cosntructor"); string("Exo variable ") + exovar + " does not exist in FineAtoms copy cosntructor");
exovars.push_back(s); exovars.push_back(s);
exo_outer_map.insert(Tvarintmap::value_type(s, exovars.size()-1)); exo_outer_map.emplace(s, exovars.size()-1);
} }
if (fa.endo_order) if (fa.endo_order)
@ -119,7 +119,7 @@ FineAtoms::FineAtoms(const FineAtoms &fa)
exo_order = fa.exo_order->clone(exovars, *this); exo_order = fa.exo_order->clone(exovars, *this);
if (fa.allvar_order) if (fa.allvar_order)
allvar_order = new AllvarOuterOrdering(*(fa.allvar_order), *this); allvar_order = std::make_unique<AllvarOuterOrdering>(*(fa.allvar_order), *this);
} }
int int
@ -156,9 +156,7 @@ FineAtoms::parsing_finished(VarOrdering::ord_type ot)
allvar_tmp.insert(allvar_tmp.end(), endovars.begin(), endovars.end()); allvar_tmp.insert(allvar_tmp.end(), endovars.begin(), endovars.end());
allvar_tmp.insert(allvar_tmp.end(), exovars.begin(), exovars.end()); allvar_tmp.insert(allvar_tmp.end(), exovars.begin(), exovars.end());
if (allvar_order) allvar_order = std::make_unique<AllvarOuterOrdering>(allvar_tmp, *this);
delete allvar_order;
allvar_order = new AllvarOuterOrdering(allvar_tmp, *this);
} }
void void
@ -166,9 +164,7 @@ FineAtoms::parsing_finished(VarOrdering::ord_type ot,
const vector<const char *> allvar) const vector<const char *> allvar)
{ {
make_internal_orderings(ot); make_internal_orderings(ot);
if (allvar_order) allvar_order = std::make_unique<AllvarOuterOrdering>(allvar, *this);
delete allvar_order;
allvar_order = new AllvarOuterOrdering(allvar, *this);
} }
const vector<const char *> & const vector<const char *> &
@ -205,14 +201,12 @@ vector<int>
FineAtoms::variables() const FineAtoms::variables() const
{ {
if (endo_order) if (endo_order)
{ return der_atoms;
return der_atoms;
}
else else
{ {
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
"FineAtoms::variables called before parsing_finished"); "FineAtoms::variables called before parsing_finished");
return vector<int>(); return {};
} }
} }
@ -220,9 +214,7 @@ int
FineAtoms::nstat() const FineAtoms::nstat() const
{ {
if (endo_order) if (endo_order)
{ return endo_order->nstat();
return endo_order->nstat();
}
else else
{ {
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
@ -235,9 +227,7 @@ int
FineAtoms::npred() const FineAtoms::npred() const
{ {
if (endo_order) if (endo_order)
{ return endo_order->npred();
return endo_order->npred();
}
else else
{ {
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
@ -250,9 +240,7 @@ int
FineAtoms::nboth() const FineAtoms::nboth() const
{ {
if (endo_order) if (endo_order)
{ return endo_order->nboth();
return endo_order->nboth();
}
else else
{ {
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
@ -265,9 +253,7 @@ int
FineAtoms::nforw() const FineAtoms::nforw() const
{ {
if (endo_order) if (endo_order)
{ return endo_order->nforw();
return endo_order->nforw();
}
else else
{ {
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
@ -280,9 +266,7 @@ int
FineAtoms::get_pos_of_endo(int t) const FineAtoms::get_pos_of_endo(int t) const
{ {
if (endo_order) if (endo_order)
{ return endo_order->get_pos_of(t);
return endo_order->get_pos_of(t);
}
else else
{ {
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
@ -295,9 +279,7 @@ int
FineAtoms::get_pos_of_exo(int t) const FineAtoms::get_pos_of_exo(int t) const
{ {
if (exo_order) if (exo_order)
{ return exo_order->get_pos_of(t);
return exo_order->get_pos_of(t);
}
else else
{ {
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
@ -391,7 +373,7 @@ FineAtoms::name2outer_param(const char *name) const
if (it == param_outer_map.end()) if (it == param_outer_map.end())
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
"Name is not a parameter in FineAtoms::name2outer_param"); "Name is not a parameter in FineAtoms::name2outer_param");
return (*it).second; return it->second;
} }
int int
@ -401,7 +383,7 @@ FineAtoms::name2outer_endo(const char *name) const
if (it == endo_outer_map.end()) if (it == endo_outer_map.end())
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
"Name is not an endogenous variable in FineAtoms::name2outer_endo"); "Name is not an endogenous variable in FineAtoms::name2outer_endo");
return (*it).second; return it->second;
} }
int int
@ -411,7 +393,7 @@ FineAtoms::name2outer_exo(const char *name) const
if (it == exo_outer_map.end()) if (it == exo_outer_map.end())
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
"Name is not an exogenous variable in FineAtoms::name2outer_exo"); "Name is not an exogenous variable in FineAtoms::name2outer_exo");
return (*it).second; return it->second;
} }
int int
@ -423,12 +405,12 @@ FineAtoms::name2outer_allvar(const char *name) const
auto it = endo_outer_map.find(name); auto it = endo_outer_map.find(name);
if (it != endo_outer_map.end()) if (it != endo_outer_map.end())
return allvar_order->get_endo2all()[(*it).second]; return allvar_order->get_endo2all()[it->second];
else else
{ {
it = exo_outer_map.find(name); it = exo_outer_map.find(name);
if (it != exo_outer_map.end()) if (it != exo_outer_map.end())
return allvar_order->get_exo2all()[(*it).second]; return allvar_order->get_exo2all()[it->second];
} }
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
@ -443,7 +425,7 @@ FineAtoms::register_uniq_endo(const char *name)
throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.", 0); throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.", 0);
const char *ss = varnames.insert(name); const char *ss = varnames.insert(name);
endovars.push_back(ss); endovars.push_back(ss);
endo_outer_map.insert(Tvarintmap::value_type(ss, endovars.size()-1)); endo_outer_map.emplace(ss, endovars.size()-1);
} }
void void
@ -453,7 +435,7 @@ FineAtoms::register_uniq_exo(const char *name)
throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.", 0); throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.", 0);
const char *ss = varnames.insert(name); const char *ss = varnames.insert(name);
exovars.push_back(ss); exovars.push_back(ss);
exo_outer_map.insert(Tvarintmap::value_type(ss, exovars.size()-1)); exo_outer_map.emplace(ss, exovars.size()-1);
} }
void void
@ -463,7 +445,7 @@ FineAtoms::register_uniq_param(const char *name)
throw ogp::ParserException(string("Parameter <")+name+"> is not unique.", 0); throw ogp::ParserException(string("Parameter <")+name+"> is not unique.", 0);
const char *ss = varnames.insert(name); const char *ss = varnames.insert(name);
params.push_back(ss); params.push_back(ss);
param_outer_map.insert(Tvarintmap::value_type(ss, params.size()-1)); param_outer_map.emplace(ss, params.size()-1);
} }
void void
@ -479,12 +461,10 @@ FineAtoms::make_internal_orderings(VarOrdering::ord_type ot)
if (mlag >= -1 && mlead <= 1) if (mlag >= -1 && mlead <= 1)
{ {
// make endo ordering // make endo ordering
if (endo_order)
delete endo_order;
if (ot == VarOrdering::pbspbfbf) if (ot == VarOrdering::pbspbfbf)
endo_order = new EndoVarOrdering1(endovars, *this); endo_order = std::make_unique<EndoVarOrdering1>(endovars, *this);
else else
endo_order = new EndoVarOrdering2(endovars, *this); endo_order = std::make_unique<EndoVarOrdering2>(endovars, *this);
endo_order->do_ordering(); endo_order->do_ordering();
endo_ordering_done = true; endo_ordering_done = true;
} }
@ -493,9 +473,7 @@ FineAtoms::make_internal_orderings(VarOrdering::ord_type ot)
if (mlag == 0 && mlead == 0) if (mlag == 0 && mlead == 0)
{ {
// make exo ordering // make exo ordering
if (exo_order) exo_order = std::make_unique<ExoVarOrdering>(exovars, *this);
delete exo_order;
exo_order = new ExoVarOrdering(exovars, *this);
exo_order->do_ordering(); exo_order->do_ordering();
exo_ordering_done = true; exo_ordering_done = true;
} }
@ -534,22 +512,20 @@ FineAtoms::print() const
endo_order->print(); endo_order->print();
} }
else else
{ printf("Endo ordering not created.\n");
printf("Endo ordering not created.\n");
}
if (exo_order) if (exo_order)
{ {
printf("Exo ordering:\n"); printf("Exo ordering:\n");
exo_order->print(); exo_order->print();
} }
else else
{ printf("Exo ordering not created.\n");
printf("Exo ordering not created.\n");
}
printf("endo atoms map:\n"); printf("endo atoms map:\n");
for (unsigned int i = 0; i < endo_atoms_map.size(); i++) for (unsigned int i = 0; i < endo_atoms_map.size(); i++)
printf("%d --> %d\n", i, endo_atoms_map[i]); printf(u8"%d → %d\n", i, endo_atoms_map[i]);
printf("exo atoms map:\n"); printf("exo atoms map:\n");
for (unsigned int i = 0; i < exo_atoms_map.size(); i++) for (unsigned int i = 0; i < exo_atoms_map.size(); i++)
printf("%d --> %d\n", i, exo_atoms_map[i]); printf(u8"%d → %d\n", i, exo_atoms_map[i]);
} }

View File

@ -9,6 +9,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <memory>
namespace ogp namespace ogp
{ {
@ -32,10 +33,10 @@ namespace ogp
: VarOrdering(vo, vnames, a) : VarOrdering(vo, vnames, a)
{ {
} }
VarOrdering * std::unique_ptr<VarOrdering>
clone(const vector<const char *> &vnames, const DynamicAtoms &a) const override clone(const vector<const char *> &vnames, const DynamicAtoms &a) const override
{ {
return new EndoVarOrdering1(*this, vnames, a); return std::make_unique<EndoVarOrdering1>(*this, vnames, a);
} }
void void
do_ordering() override do_ordering() override
@ -60,10 +61,10 @@ namespace ogp
: VarOrdering(vo, vnames, a) : VarOrdering(vo, vnames, a)
{ {
} }
VarOrdering * std::unique_ptr<VarOrdering>
clone(const vector<const char *> &vnames, const DynamicAtoms &a) const override clone(const vector<const char *> &vnames, const DynamicAtoms &a) const override
{ {
return new EndoVarOrdering2(*this, vnames, a); return std::make_unique<EndoVarOrdering2>(*this, vnames, a);
} }
void void
do_ordering() override do_ordering() override
@ -87,10 +88,10 @@ namespace ogp
: VarOrdering(vo, vnames, a) : VarOrdering(vo, vnames, a)
{ {
} }
VarOrdering * std::unique_ptr<VarOrdering>
clone(const vector<const char *> &vnames, const DynamicAtoms &a) const override clone(const vector<const char *> &vnames, const DynamicAtoms &a) const override
{ {
return new ExoVarOrdering(*this, vnames, a); return std::make_unique<ExoVarOrdering>(*this, vnames, a);
} }
void void
do_ordering() override do_ordering() override
@ -201,14 +202,14 @@ namespace ogp
* to endogenous variables. It is constructed by * to endogenous variables. It is constructed by
* parsing_finished() method, which should be called after all * parsing_finished() method, which should be called after all
* parsing jobs have been finished. */ * parsing jobs have been finished. */
VarOrdering *endo_order{nullptr}; std::unique_ptr<VarOrdering> endo_order;
/** This is the internal ordering of all atoms corresponding /** This is the internal ordering of all atoms corresponding
* to exogenous variables. It has the same handling as * to exogenous variables. It has the same handling as
* endo_order. */ * endo_order. */
VarOrdering *exo_order{nullptr}; std::unique_ptr<VarOrdering> exo_order;
/** This is the all variables outer ordering. It is /** This is the all variables outer ordering. It is
* constructed by parsing finished. */ * constructed by parsing finished. */
AllvarOuterOrdering *allvar_order{nullptr}; std::unique_ptr<AllvarOuterOrdering> allvar_order;
/** This vector defines a set of atoms as tree indices used /** This vector defines a set of atoms as tree indices used
* for differentiation. The order of the atoms in this vector * for differentiation. The order of the atoms in this vector
* defines ordering of the derivative tensors. The ordering is * defines ordering of the derivative tensors. The ordering is
@ -228,20 +229,10 @@ namespace ogp
* atoms of exogenous variables. */ * atoms of exogenous variables. */
vector<int> exo_atoms_map; vector<int> exo_atoms_map;
public: public:
FineAtoms() FineAtoms() = default;
= default;
FineAtoms(const FineAtoms &fa); FineAtoms(const FineAtoms &fa);
/** Deletes endo_order and exo_order. */ /** Deletes endo_order and exo_order. */
~FineAtoms() override ~FineAtoms() override = default;
{
if (endo_order)
delete endo_order;
if (exo_order)
delete exo_order;
if (allvar_order)
delete allvar_order;
}
/** Overrides DynamicAtoms::check_variable so that the error /** Overrides DynamicAtoms::check_variable so that the error
* would be raised if the variable name is not declared. A * would be raised if the variable name is not declared. A
* variable is declared by inserting it to * variable is declared by inserting it to
@ -387,13 +378,13 @@ namespace ogp
int int
nexo() const nexo() const
{ {
return (int) exovars.size(); return static_cast<int>(exovars.size());
} }
/** Return the number of parameters. */ /** Return the number of parameters. */
int int
np() const np() const
{ {
return (int) (params.size()); return static_cast<int>(params.size());
} }
/** Register unique endogenous variable name. The order of /** Register unique endogenous variable name. The order of
* calls defines the endo outer ordering. The method is * calls defines the endo outer ordering. The method is

View File

@ -47,27 +47,27 @@ extern ogp::FormulaParser* fparser;
equation_list : equation_list equation | equation ; equation_list : equation_list equation | equation ;
equation : expression EQUAL_SIGN expression ';' equation : expression EQUAL_SIGN expression ';'
{fparser->add_formula(fparser->add_binary(ogp::MINUS,$1,$3));} {fparser->add_formula(fparser->add_binary(ogp::code_t::MINUS,$1,$3));}
| expression ';' | expression ';'
{fparser->add_formula($1);} {fparser->add_formula($1);}
; ;
expression : '(' expression ')' { $$ = $2;} expression : '(' expression ')' { $$ = $2;}
| expression YPLUS expression {$$=fparser->add_binary(ogp::PLUS,$1,$3);} | expression YPLUS expression {$$=fparser->add_binary(ogp::code_t::PLUS,$1,$3);}
| expression YMINUS expression {$$=fparser->add_binary(ogp::MINUS,$1,$3);} | expression YMINUS expression {$$=fparser->add_binary(ogp::code_t::MINUS,$1,$3);}
| expression YTIMES expression {$$=fparser->add_binary(ogp::TIMES,$1,$3);} | expression YTIMES expression {$$=fparser->add_binary(ogp::code_t::TIMES,$1,$3);}
| expression YDIVIDE expression {$$=fparser->add_binary(ogp::DIVIDE,$1,$3);} | expression YDIVIDE expression {$$=fparser->add_binary(ogp::code_t::DIVIDE,$1,$3);}
| expression YPOWER expression {$$=fparser->add_binary(ogp::POWER,$1,$3);} | expression YPOWER expression {$$=fparser->add_binary(ogp::code_t::POWER,$1,$3);}
| YMINUS expression %prec YUMINUS {$$=fparser->add_unary(ogp::UMINUS,$2);} | YMINUS expression %prec YUMINUS {$$=fparser->add_unary(ogp::code_t::UMINUS,$2);}
| YPLUS expression %prec YUPLUS {$$ = $2;} | YPLUS expression %prec YUPLUS {$$ = $2;}
| YSIN '(' expression ')' {$$=fparser->add_unary(ogp::SIN,$3);} | YSIN '(' expression ')' {$$=fparser->add_unary(ogp::code_t::SIN,$3);}
| YCOS '(' expression ')' {$$=fparser->add_unary(ogp::COS,$3);} | YCOS '(' expression ')' {$$=fparser->add_unary(ogp::code_t::COS,$3);}
| YTAN '(' expression ')' {$$=fparser->add_unary(ogp::TAN,$3);} | YTAN '(' expression ')' {$$=fparser->add_unary(ogp::code_t::TAN,$3);}
| YEXP '(' expression ')' {$$=fparser->add_unary(ogp::EXP,$3);} | YEXP '(' expression ')' {$$=fparser->add_unary(ogp::code_t::EXP,$3);}
| YLOG '(' expression ')' {$$=fparser->add_unary(ogp::LOG,$3);} | YLOG '(' expression ')' {$$=fparser->add_unary(ogp::code_t::LOG,$3);}
| YSQRT '(' expression ')' {$$=fparser->add_unary(ogp::SQRT,$3);} | YSQRT '(' expression ')' {$$=fparser->add_unary(ogp::code_t::SQRT,$3);}
| YERF '(' expression ')' {$$=fparser->add_unary(ogp::ERF,$3);} | YERF '(' expression ')' {$$=fparser->add_unary(ogp::code_t::ERF,$3);}
| YERFC '(' expression ')' {$$=fparser->add_unary(ogp::ERFC,$3);} | YERFC '(' expression ')' {$$=fparser->add_unary(ogp::code_t::ERFC,$3);}
| YDIFF '(' expression ',' NAME ')' {$$=fparser->add_derivative($3, fparser->add_nulary($5));} | YDIFF '(' expression ',' NAME ')' {$$=fparser->add_derivative($3, fparser->add_nulary($5));}
| NAME {$$=fparser->add_nulary($1);} | NAME {$$=fparser->add_nulary($1);}
| DNUMBER {$$=fparser->add_nulary($1);} | DNUMBER {$$=fparser->add_nulary($1);}

View File

@ -11,7 +11,7 @@
#include "formula_tab.hh" #include "formula_tab.hh"
#include <cmath> #include <cmath>
#include <cstring> #include <algorithm>
using namespace ogp; using namespace ogp;
@ -21,29 +21,24 @@ FormulaParser::FormulaParser(const FormulaParser &fp, Atoms &a)
: otree(fp.otree), atoms(a), formulas(fp.formulas), ders() : otree(fp.otree), atoms(a), formulas(fp.formulas), ders()
{ {
// create derivatives // create derivatives
for (auto der : fp.ders) for (const auto &der : fp.ders)
ders.push_back(new FormulaDerivatives(*der)); ders.push_back(std::make_unique<FormulaDerivatives>(*der));
}
FormulaParser::~FormulaParser()
{
destroy_derivatives();
} }
void void
FormulaParser::differentiate(int max_order) FormulaParser::differentiate(int max_order)
{ {
destroy_derivatives(); ders.clear();
vector<int> vars; vector<int> vars;
vars = atoms.variables(); vars = atoms.variables();
for (int formula : formulas) for (int formula : formulas)
ders.push_back(new FormulaDerivatives(otree, vars, formula, max_order)); ders.push_back(std::make_unique<FormulaDerivatives>(otree, vars, formula, max_order));
} }
const FormulaDerivatives & const FormulaDerivatives &
FormulaParser::derivatives(int i) const FormulaParser::derivatives(int i) const
{ {
if (i < (int) ders.size()) if (i < static_cast<int>(ders.size()))
return *(ders[i]); return *(ders[i]);
else else
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
@ -108,11 +103,10 @@ FormulaParser::substitute_formulas(const map<int, int> &smap)
int f = add_substitution(formulas[i], smap); int f = add_substitution(formulas[i], smap);
formulas[i] = f; formulas[i] = f;
// update the derivatives if any // update the derivatives if any
if (i < (int) ders.size() && ders[i]) if (i < static_cast<int>(ders.size()) && ders[i])
{ {
int order = ders[i]->get_order(); int order = ders[i]->get_order();
delete ders[i]; ders[i] = std::make_unique<FormulaDerivatives>(otree, atoms.variables(), formulas[i], order);
ders[i] = new FormulaDerivatives(otree, atoms.variables(), formulas[i], order);
} }
} }
} }
@ -134,16 +128,15 @@ extern location_type fmla_lloc;
void void
FormulaParser::parse(int length, const char *stream) FormulaParser::parse(int length, const char *stream)
{ {
auto *buffer = new char[length+2]; auto buffer = std::make_unique<char[]>(length+2);
strncpy(buffer, stream, length); std::copy_n(stream, length, buffer.get());
buffer[length] = '\0'; buffer[length] = '\0';
buffer[length+1] = '\0'; buffer[length+1] = '\0';
fmla_lloc.off = 0; fmla_lloc.off = 0;
fmla_lloc.ll = 0; fmla_lloc.ll = 0;
void *p = fmla__scan_buffer(buffer, (unsigned int) length+2); void *p = fmla__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
fparser = this; fparser = this;
fmla_parse(); fmla_parse();
delete [] buffer;
fmla__destroy_buffer(p); fmla__destroy_buffer(p);
} }
@ -158,8 +151,7 @@ FormulaParser::last_formula() const
{ {
int res = -1; int res = -1;
for (int formula : formulas) for (int formula : formulas)
if (res < formula) res = std::max(res, formula);
res = formula;
return std::max(res, otree.get_last_nulary()); return std::max(res, otree.get_last_nulary());
} }
@ -170,10 +162,7 @@ FormulaParser::pop_last_formula()
return -1; return -1;
int t = formulas.back(); int t = formulas.back();
if (formulas.size() == ders.size()) if (formulas.size() == ders.size())
{ ders.pop_back();
delete ders.back();
ders.pop_back();
}
formulas.pop_back(); formulas.pop_back();
return t; return t;
} }
@ -194,16 +183,6 @@ FormulaParser::print() const
} }
} }
void
FormulaParser::destroy_derivatives()
{
while (ders.size() > 0)
{
delete ders.back();
ders.pop_back();
}
}
/** This constructor makes a vector of indices for formulas /** This constructor makes a vector of indices for formulas
* corresponding to derivatives of the given formula. The formula is * corresponding to derivatives of the given formula. The formula is
* supposed to belong to the provided tree, the created derivatives * supposed to belong to the provided tree, the created derivatives
@ -254,13 +233,11 @@ FormulaDerivatives::FormulaDerivatives(OperationTree &otree,
// build ind2der map // build ind2der map
for (unsigned int i = 0; i < indices.size(); i++) for (unsigned int i = 0; i < indices.size(); i++)
ind2der.insert(Tfmiintmap::value_type(indices[i], i)); ind2der.emplace(indices[i], i);
} }
FormulaDerivatives::FormulaDerivatives(const FormulaDerivatives &fd) FormulaDerivatives::FormulaDerivatives(const FormulaDerivatives &fd) = default;
= default;
int int
FormulaDerivatives::derivative(const FoldMultiIndex &mi) const FormulaDerivatives::derivative(const FoldMultiIndex &mi) const
@ -276,7 +253,7 @@ FormulaDerivatives::derivative(const FoldMultiIndex &mi) const
if (it == ind2der.end()) if (it == ind2der.end())
return OperationTree::zero; return OperationTree::zero;
else else
return tder[(*it).second]; return tder[it->second];
} }
void void
@ -299,17 +276,17 @@ FormulaCustomEvaluator::eval(const AtomValues &av, FormulaEvalLoader &loader)
for (unsigned int i = 0; i < terms.size(); i++) for (unsigned int i = 0; i < terms.size(); i++)
{ {
double res = etree.eval(terms[i]); double res = etree.eval(terms[i]);
loader.load((int) i, res); loader.load(static_cast<int>(i), res);
} }
} }
FoldMultiIndex::FoldMultiIndex(int nv) FoldMultiIndex::FoldMultiIndex(int nv)
: nvar(nv), ord(0), data(new int[ord]) : nvar(nv), ord(0), data(std::make_unique<int[]>(ord))
{ {
} }
FoldMultiIndex::FoldMultiIndex(int nv, int ordd, int ii) FoldMultiIndex::FoldMultiIndex(int nv, int ordd, int ii)
: nvar(nv), ord(ordd), data(new int[ord]) : nvar(nv), ord(ordd), data(std::make_unique<int[]>(ord))
{ {
for (int i = 0; i < ord; i++) for (int i = 0; i < ord; i++)
data[i] = ii; data[i] = ii;
@ -318,7 +295,7 @@ FoldMultiIndex::FoldMultiIndex(int nv, int ordd, int ii)
/** Note that a monotone sequence mapped by monotone mapping yields a /** Note that a monotone sequence mapped by monotone mapping yields a
* monotone sequence. */ * monotone sequence. */
FoldMultiIndex::FoldMultiIndex(int nv, const FoldMultiIndex &mi, const vector<int> &mp) FoldMultiIndex::FoldMultiIndex(int nv, const FoldMultiIndex &mi, const vector<int> &mp)
: nvar(nv), ord(mi.ord), data(new int[ord]) : nvar(nv), ord(mi.ord), data(std::make_unique<int[]>(ord))
{ {
for (int i = 0; i < ord; i++) for (int i = 0; i < ord; i++)
{ {
@ -335,36 +312,31 @@ FoldMultiIndex::FoldMultiIndex(int nv, const FoldMultiIndex &mi, const vector<in
FoldMultiIndex::FoldMultiIndex(const FoldMultiIndex &fmi, int new_orders) FoldMultiIndex::FoldMultiIndex(const FoldMultiIndex &fmi, int new_orders)
: nvar(fmi.nvar), : nvar(fmi.nvar),
ord(fmi.ord+new_orders), ord(fmi.ord+new_orders),
data(new int[ord]) data(std::make_unique<int[]>(ord))
{ {
memcpy(data, fmi.data, fmi.ord*sizeof(int)); std::copy_n(fmi.data.get(), fmi.ord, data.get());
int new_item = (fmi.ord > 0) ? fmi.data[fmi.ord-1] : 0; int new_item = (fmi.ord > 0) ? fmi.data[fmi.ord-1] : 0;
for (int i = fmi.ord; i < ord; i++) for (int i = fmi.ord; i < ord; i++)
{ data[i] = new_item;
data[i] = new_item;
}
} }
FoldMultiIndex::FoldMultiIndex(const FoldMultiIndex &fmi) FoldMultiIndex::FoldMultiIndex(const FoldMultiIndex &fmi)
: nvar(fmi.nvar), : nvar(fmi.nvar),
ord(fmi.ord), ord(fmi.ord),
data(new int[fmi.ord]) data(std::make_unique<int[]>(ord))
{ {
memcpy(data, fmi.data, ord*sizeof(int)); std::copy_n(fmi.data.get(), ord, data.get());
} }
const FoldMultiIndex & const FoldMultiIndex &
FoldMultiIndex::operator=(const FoldMultiIndex &fmi) FoldMultiIndex::operator=(const FoldMultiIndex &fmi)
{ {
if (ord != fmi.ord) if (ord != fmi.ord)
{ data = std::make_unique<int[]>(fmi.ord);
delete [] data;
data = new int[fmi.ord];
}
ord = fmi.ord; ord = fmi.ord;
nvar = fmi.nvar; nvar = fmi.nvar;
memcpy(data, fmi.data, ord*sizeof(int)); std::copy_n(fmi.data.get(), ord, data.get());
return *this; return *this;
} }
@ -427,13 +399,10 @@ int
FoldMultiIndex::offset() const FoldMultiIndex::offset() const
{ {
// make copy for the recursions // make copy for the recursions
auto *tmp = new int[ord]; auto tmp = std::make_unique<int[]>(ord);
for (int i = 0; i < ord; i++) std::copy_n(data.get(), ord, tmp.get());
tmp[i] = data[i];
// call the recursive algorithm // call the recursive algorithm
int res = offset_recurse(tmp, ord, nvar); int res = offset_recurse(tmp.get(), ord, nvar);
delete [] tmp;
return res; return res;
} }
@ -478,8 +447,8 @@ ltfmi::operator()(const FoldMultiIndex &i1, const FoldMultiIndex &i2) const
FormulaDerEvaluator::FormulaDerEvaluator(const FormulaParser &fp) FormulaDerEvaluator::FormulaDerEvaluator(const FormulaParser &fp)
: etree(fp.otree, -1) : etree(fp.otree, -1)
{ {
for (auto der : fp.ders) for (const auto &der : fp.ders)
ders.push_back((const FormulaDerivatives *) der); ders.push_back(der.get());
der_atoms = fp.atoms.variables(); der_atoms = fp.atoms.variables();
} }
@ -498,28 +467,25 @@ FormulaDerEvaluator::eval(const AtomValues &av, FormulaDerEvalLoader &loader, in
etree.reset_all(); etree.reset_all();
av.setValues(etree); av.setValues(etree);
auto *vars = new int[order]; auto vars = std::make_unique<int[]>(order);
for (unsigned int i = 0; i < ders.size(); i++) for (unsigned int i = 0; i < ders.size(); i++)
{ {
for (auto it = ders[i]->ind2der.begin(); for (const auto &it : ders[i]->ind2der)
it != ders[i]->ind2der.end(); ++it)
{ {
const FoldMultiIndex &mi = (*it).first; const FoldMultiIndex &mi = it.first;
if (mi.order() == order) if (mi.order() == order)
{ {
// set vars from multiindex mi and variables // set vars from multiindex mi and variables
for (int k = 0; k < order; k++) for (int k = 0; k < order; k++)
vars[k] = der_atoms[mi[k]]; vars[k] = der_atoms[mi[k]];
// evaluate // evaluate
double res = etree.eval(ders[i]->tder[(*it).second]); double res = etree.eval(ders[i]->tder[it.second]);
// load // load
loader.load(i, order, vars, res); loader.load(i, order, vars.get(), res);
} }
} }
} }
delete [] vars;
} }
void void
@ -531,7 +497,7 @@ FormulaDerEvaluator::eval(const vector<int> &mp, const AtomValues &av,
int nvar_glob = der_atoms.size(); int nvar_glob = der_atoms.size();
int nvar = mp.size(); int nvar = mp.size();
auto *vars = new int[order]; auto vars = std::make_unique<int[]>(order);
for (unsigned int i = 0; i < ders.size(); i++) for (unsigned int i = 0; i < ders.size(); i++)
{ {
@ -549,12 +515,10 @@ FormulaDerEvaluator::eval(const vector<int> &mp, const AtomValues &av,
// evaluate derivative // evaluate derivative
double res = etree.eval(der); double res = etree.eval(der);
// load // load
loader.load(i, order, vars, res); loader.load(i, order, vars.get(), res);
} }
mi.increment(); mi.increment();
} }
while (!mi.past_the_end()); while (!mi.past_the_end());
} }
delete [] vars;
} }

View File

@ -4,6 +4,8 @@
#define OGP_FORMULA_PARSER_H #define OGP_FORMULA_PARSER_H
#include <utility> #include <utility>
#include <memory>
#include <vector>
#include "tree.hh" #include "tree.hh"
@ -16,10 +18,8 @@ namespace ogp
class Atoms class Atoms
{ {
public: public:
Atoms() Atoms() = default;
= default; virtual ~Atoms() = default;
virtual ~Atoms()
= default;
/** This returns previously assigned internal index to the /** This returns previously assigned internal index to the
* given atom, or returns -1 if the atom has not been assigned * given atom, or returns -1 if the atom has not been assigned
* yet. The method can raise an exception, if the Atoms * yet. The method can raise an exception, if the Atoms
@ -48,8 +48,7 @@ namespace ogp
class AtomValues class AtomValues
{ {
public: public:
virtual ~AtomValues() virtual ~AtomValues() = default;
= default;
virtual void setValues(EvalTree &et) const = 0; virtual void setValues(EvalTree &et) const = 0;
}; };
@ -110,8 +109,7 @@ namespace ogp
FormulaDerivatives(OperationTree &otree, const vector<int> &vars, int f, int max_order); FormulaDerivatives(OperationTree &otree, const vector<int> &vars, int f, int max_order);
/** Copy constructor. */ /** Copy constructor. */
FormulaDerivatives(const FormulaDerivatives &fd); FormulaDerivatives(const FormulaDerivatives &fd);
virtual ~FormulaDerivatives() virtual ~FormulaDerivatives() = default;
= default;
/** Random access to the derivatives via multiindex. */ /** Random access to the derivatives via multiindex. */
int derivative(const FoldMultiIndex &mi) const; int derivative(const FoldMultiIndex &mi) const;
/** Return the order. */ /** Return the order. */
@ -151,7 +149,7 @@ namespace ogp
vector<int> formulas; vector<int> formulas;
/** The vector to derivatives, each vector corresponds to a /** The vector to derivatives, each vector corresponds to a
* formula in the vector formulas. */ * formula in the vector formulas. */
vector<FormulaDerivatives *> ders; vector<std::unique_ptr<FormulaDerivatives>> ders;
public: public:
/** Construct an empty formula parser. */ /** Construct an empty formula parser. */
FormulaParser(Atoms &a) FormulaParser(Atoms &a)
@ -161,8 +159,7 @@ namespace ogp
FormulaParser(const FormulaParser &fp) = delete; FormulaParser(const FormulaParser &fp) = delete;
/** Copy constructor using a different instance of Atoms. */ /** Copy constructor using a different instance of Atoms. */
FormulaParser(const FormulaParser &fp, Atoms &a); FormulaParser(const FormulaParser &fp, Atoms &a);
virtual virtual ~FormulaParser() = default;
~FormulaParser();
/** Requires an addition of the formula; called from the /** Requires an addition of the formula; called from the
* parser. */ * parser. */
@ -267,7 +264,7 @@ namespace ogp
int int
nformulas() const nformulas() const
{ {
return (int) (formulas.size()); return static_cast<int>(formulas.size());
} }
/** This returns a reference to atoms. */ /** This returns a reference to atoms. */
@ -295,9 +292,6 @@ namespace ogp
/** Debug print. */ /** Debug print. */
void print() const; void print() const;
private:
/** Destroy all derivatives. */
void destroy_derivatives();
}; };
/** This is a pure virtual class defining an interface for all /** This is a pure virtual class defining an interface for all
@ -307,8 +301,7 @@ namespace ogp
class FormulaEvalLoader class FormulaEvalLoader
{ {
public: public:
virtual ~FormulaEvalLoader() virtual ~FormulaEvalLoader() = default;
= default;
/** Set the value res for the given formula. The formula is /** Set the value res for the given formula. The formula is
* identified by an index corresponding to the ordering in * identified by an index corresponding to the ordering in
* which the formulas have been parsed (starting from * which the formulas have been parsed (starting from
@ -368,8 +361,7 @@ namespace ogp
class FormulaDerEvalLoader class FormulaDerEvalLoader
{ {
public: public:
virtual ~FormulaDerEvalLoader() virtual ~FormulaDerEvalLoader() = default;
= default;
/** This loads the result of the derivative of the given /** This loads the result of the derivative of the given
* order. The semantics of i is the same as in * order. The semantics of i is the same as in
* FormulaEvalLoader::load. The indices of variables with * FormulaEvalLoader::load. The indices of variables with
@ -389,7 +381,7 @@ namespace ogp
/** Dimension. */ /** Dimension. */
int ord; int ord;
/** The multiindex. */ /** The multiindex. */
int *data; std::unique_ptr<int[]> data;
public: public:
/** Initializes to the zero derivative. Order is 0, data is /** Initializes to the zero derivative. Order is 0, data is
* empty. */ * empty. */
@ -407,10 +399,7 @@ namespace ogp
/** Copy constructor. */ /** Copy constructor. */
FoldMultiIndex(const FoldMultiIndex &fmi); FoldMultiIndex(const FoldMultiIndex &fmi);
/** Desctructor. */ /** Desctructor. */
virtual ~FoldMultiIndex() virtual ~FoldMultiIndex() = default;
{
delete [] data;
}
/** Assignment operator. */ /** Assignment operator. */
const FoldMultiIndex &operator=(const FoldMultiIndex &fmi); const FoldMultiIndex &operator=(const FoldMultiIndex &fmi);
/** Operator < implementing lexicographic ordering within one /** Operator < implementing lexicographic ordering within one
@ -443,7 +432,7 @@ namespace ogp
const int * const int *
ind() const ind() const
{ {
return data; return data.get();
} }
/** Return true if the end of the tensor is reached. The /** Return true if the end of the tensor is reached. The
* result of a subsequent increment should be considered * result of a subsequent increment should be considered

View File

@ -6,7 +6,9 @@
#include "matrix_parser.hh" #include "matrix_parser.hh"
#include "location.hh" #include "location.hh"
#include "matrix_tab.hh" #include "matrix_tab.hh"
#include <cstring>
#include <memory>
#include <algorithm>
using namespace ogp; using namespace ogp;
@ -29,16 +31,15 @@ MatrixParser::parse(int length, const char *stream)
row_lengths.clear(); row_lengths.clear();
nc = 0; nc = 0;
// allocate temporary buffer and parse // allocate temporary buffer and parse
auto *buffer = new char[length+2]; auto buffer = std::make_unique<char[]>(length+2);
strncpy(buffer, stream, length); std::copy_n(stream, length, buffer.get());
buffer[length] = '\0'; buffer[length] = '\0';
buffer[length+1] = '\0'; buffer[length+1] = '\0';
matrix_lloc.off = 0; matrix_lloc.off = 0;
matrix_lloc.ll = 0; matrix_lloc.ll = 0;
void *p = matrix__scan_buffer(buffer, (unsigned int) length+2); void *p = matrix__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
mparser = this; mparser = this;
matrix_parse(); matrix_parse();
delete [] buffer;
matrix__destroy_buffer(p); matrix__destroy_buffer(p);
} }
@ -49,8 +50,7 @@ MatrixParser::add_item(double v)
if (row_lengths.size() == 0) if (row_lengths.size() == 0)
row_lengths.push_back(0); row_lengths.push_back(0);
(row_lengths.back())++; (row_lengths.back())++;
if (row_lengths.back() > nc) nc = std::max(nc, row_lengths.back());
nc = row_lengths.back();
} }
void void
@ -69,7 +69,7 @@ int
MatrixParser::find_first_non_empty_row(int start) const MatrixParser::find_first_non_empty_row(int start) const
{ {
int r = start; int r = start;
while (r < (int) row_lengths.size() && row_lengths[r] == 0) while (r < static_cast<int>(row_lengths.size()) && row_lengths[r] == 0)
r++; r++;
return r; return r;
} }

View File

@ -5,7 +5,6 @@
#ifndef OGP_MATRIX_PARSER #ifndef OGP_MATRIX_PARSER
#define OGP_MATRIX_PARSER #define OGP_MATRIX_PARSER
#include <cstdlib> // For NULL
#include <vector> #include <vector>
namespace ogp namespace ogp
@ -33,19 +32,14 @@ namespace ogp
/** Maximum number of row lengths. */ /** Maximum number of row lengths. */
int nc{0}; int nc{0};
public: public:
MatrixParser() MatrixParser() = default;
MatrixParser(const MatrixParser &mp) = default;
= default; virtual ~MatrixParser() = default;
MatrixParser(const MatrixParser &mp)
= default;
virtual ~MatrixParser()
= default;
/** Return a number of read rows. */ /** Return a number of read rows. */
int int
nrows() const nrows() const
{ {
return (int) row_lengths.size(); return static_cast<int>(row_lengths.size());
} }
/** Return a maximum number of items in the rows. */ /** Return a maximum number of items in the rows. */
int int
@ -91,8 +85,7 @@ namespace ogp
int r{0}; int r{0};
public: public:
MPIterator() MPIterator() = default;
= default;
/** Constructs an iterator pointing to the beginning of the /** Constructs an iterator pointing to the beginning of the
* parsed matrix. */ * parsed matrix. */
MPIterator(const MatrixParser &mp); MPIterator(const MatrixParser &mp);
@ -118,9 +111,7 @@ namespace ogp
return c; return c;
} }
/** Assignment operator. */ /** Assignment operator. */
MPIterator & MPIterator &operator=(const MPIterator &it) = default;
operator=(const MPIterator &it)
= default;
/** Return true if the iterators are the same, this is if they /** Return true if the iterators are the same, this is if they
* have the same underlying object and the same item index. */ * have the same underlying object and the same item index. */
bool bool

View File

@ -4,7 +4,8 @@
#include "namelist.hh" #include "namelist.hh"
#include <cstring> #include <memory>
#include <algorithm>
using namespace ogp; using namespace ogp;
@ -19,13 +20,12 @@ void namelist_parse();
void void
NameListParser::namelist_parse(int length, const char *stream) NameListParser::namelist_parse(int length, const char *stream)
{ {
auto *buffer = new char[length+2]; auto buffer = std::make_unique<char[]>(length+2);
strncpy(buffer, stream, length); std::copy_n(str, length, buffer.get());
buffer[length] = '\0'; buffer[length] = '\0';
buffer[length+1] = '\0'; buffer[length+1] = '\0';
void *p = namelist__scan_buffer(buffer, (unsigned int) length+2); void *p = namelist__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
name_list_parser = this; name_list_parser = this;
::namelist_parse(); ::namelist_parse();
delete [] buffer;
namelist__destroy_buffer(p); namelist__destroy_buffer(p);
} }

View File

@ -7,7 +7,6 @@
namespace ogp namespace ogp
{ {
/** Parent class of all parsers parsing a namelist. They must /** Parent class of all parsers parsing a namelist. They must
* implement add_name() method and error() method, which is called * implement add_name() method and error() method, which is called
* when an parse error occurs. * when an parse error occurs.
@ -20,8 +19,7 @@ namespace ogp
class NameListParser class NameListParser
{ {
public: public:
virtual ~NameListParser() virtual ~NameListParser() = default;
= default;
virtual void add_name(const char *name) = 0; virtual void add_name(const char *name) = 0;
virtual void namelist_error(const char *mes) = 0; virtual void namelist_error(const char *mes) = 0;
void namelist_parse(int length, const char *text); void namelist_parse(int length, const char *text);

View File

@ -3,61 +3,42 @@
// $Id: parser_exception.cpp 2269 2008-11-23 14:33:22Z michel $ // $Id: parser_exception.cpp 2269 2008-11-23 14:33:22Z michel $
#include "parser_exception.hh" #include "parser_exception.hh"
#include <cstring>
#include <cstdio>
using namespace ogp; using namespace ogp;
ParserException::ParserException(const char *m, int offset) ParserException::ParserException(string m, int offset)
: mes(new char[strlen(m)+1]), off(offset), : mes(std::move(m)), off(offset),
aux_i1(-1), aux_i2(-1), aux_i3(-1) aux_i1(-1), aux_i2(-1), aux_i3(-1)
{ {
strcpy(mes, m);
} }
ParserException::ParserException(const string &m, int offset) ParserException::ParserException(string m, const char *dum, int i1)
: mes(new char[m.size()+1]), off(offset), : mes(std::move(m)), off(0),
aux_i1(-1), aux_i2(-1), aux_i3(-1)
{
strncpy(mes, m.c_str(), m.size());
mes[m.size()] = '\0';
}
ParserException::ParserException(const string &m, const char *dum, int i1)
: mes(new char[m.size()+1]), off(0),
aux_i1(i1), aux_i2(-1), aux_i3(-1) aux_i1(i1), aux_i2(-1), aux_i3(-1)
{ {
strncpy(mes, m.c_str(), m.size());
mes[m.size()] = '\0';
} }
ParserException::ParserException(const string &m, const char *dum, int i1, int i2) ParserException::ParserException(string m, const char *dum, int i1, int i2)
: mes(new char[m.size()+1]), off(0), : mes(std::move(m)), off(0),
aux_i1(i1), aux_i2(i2), aux_i3(-1) aux_i1(i1), aux_i2(i2), aux_i3(-1)
{ {
strncpy(mes, m.c_str(), m.size());
mes[m.size()] = '\0';
} }
ParserException::ParserException(const string &m, const char *dum, int i1, int i2, int i3) ParserException::ParserException(string m, const char *dum, int i1, int i2, int i3)
: mes(new char[m.size()+1]), off(0), : mes(std::move(m)), off(0),
aux_i1(i1), aux_i2(i2), aux_i3(i3) aux_i1(i1), aux_i2(i2), aux_i3(i3)
{ {
strncpy(mes, m.c_str(), m.size());
mes[m.size()] = '\0';
} }
ParserException::ParserException(const ParserException &m, int plus_offset) ParserException::ParserException(const ParserException &m, int plus_offset)
: mes(nullptr), : aux_i1(-1), aux_i2(-1), aux_i3(-1)
aux_i1(-1), aux_i2(-1), aux_i3(-1)
{ {
copy(m); copy(m);
off += plus_offset; off += plus_offset;
} }
ParserException::ParserException(const ParserException &m, const char *dum, int i) ParserException::ParserException(const ParserException &m, const char *dum, int i)
: mes(nullptr), : aux_i1(-1), aux_i2(-1), aux_i3(-1)
aux_i1(-1), aux_i2(-1), aux_i3(-1)
{ {
copy(m); copy(m);
aux_i3 = m.aux_i2; aux_i3 = m.aux_i2;
@ -66,8 +47,7 @@ ParserException::ParserException(const ParserException &m, const char *dum, int
} }
ParserException::ParserException(const ParserException &m, const char *dum, int i1, int i2) ParserException::ParserException(const ParserException &m, const char *dum, int i1, int i2)
: mes(nullptr), : aux_i1(-1), aux_i2(-1), aux_i3(-1)
aux_i1(-1), aux_i2(-1), aux_i3(-1)
{ {
copy(m); copy(m);
aux_i3 = m.aux_i1; aux_i3 = m.aux_i1;
@ -76,8 +56,7 @@ ParserException::ParserException(const ParserException &m, const char *dum, int
} }
ParserException::ParserException(const ParserException &m, const char *dum, int i1, int i2, int i3) ParserException::ParserException(const ParserException &m, const char *dum, int i1, int i2, int i3)
: mes(nullptr), : aux_i1(-1), aux_i2(-1), aux_i3(-1)
aux_i1(-1), aux_i2(-1), aux_i3(-1)
{ {
copy(m); copy(m);
aux_i3 = i3; aux_i3 = i3;
@ -85,34 +64,12 @@ ParserException::ParserException(const ParserException &m, const char *dum, int
aux_i1 = i1; aux_i1 = i1;
} }
ParserException::ParserException(const ParserException &e)
: mes(nullptr),
aux_i1(-1), aux_i2(-1), aux_i3(-1)
{
copy(e);
}
ParserException::~ParserException()
{
delete [] mes;
}
void void
ParserException::copy(const ParserException &e) ParserException::copy(const ParserException &e)
{ {
if (mes) mes = e.mes;
delete [] mes;
mes = new char[strlen(e.mes)+1];
strcpy(mes, e.mes);
off = e.off; off = e.off;
aux_i1 = e.aux_i1; aux_i1 = e.aux_i1;
aux_i2 = e.aux_i2; aux_i2 = e.aux_i2;
aux_i3 = e.aux_i3; aux_i3 = e.aux_i3;
} }
void
ParserException::print(FILE *fd) const
{
// todo: to be refined
fprintf(fd, "%s: offset %d\n", mes, off);
}

View File

@ -21,17 +21,16 @@ namespace ogp
class ParserException class ParserException
{ {
protected: protected:
char *mes; string mes;
int off; int off;
int aux_i1; int aux_i1;
int aux_i2; int aux_i2;
int aux_i3; int aux_i3;
public: public:
ParserException(const char *m, int offset); ParserException(string m, int offset);
ParserException(const string &m, int offset); ParserException(string m, const char *dum, int i1);
ParserException(const string &m, const char *dum, int i1); ParserException(string m, const char *dum, int i1, int i2);
ParserException(const string &m, const char *dum, int i1, int i2); ParserException(string m, const char *dum, int i1, int i2, int i3);
ParserException(const string &m, const char *dum, int i1, int i2, int i3);
ParserException(const ParserException &e, int plus_offset); ParserException(const ParserException &e, int plus_offset);
/** Makes a copy and pushes given integer to aux_i1 shuffling /** Makes a copy and pushes given integer to aux_i1 shuffling
* others and forgetting the last. */ * others and forgetting the last. */
@ -42,11 +41,9 @@ namespace ogp
/** Makes a copy and pushes given three integers to aux_i1, aux_i2, aus_i3 shuffling /** Makes a copy and pushes given three integers to aux_i1, aux_i2, aus_i3 shuffling
* others and forgetting the last three. */ * others and forgetting the last three. */
ParserException(const ParserException &e, const char *dum, int i1, int i2, int i3); ParserException(const ParserException &e, const char *dum, int i1, int i2, int i3);
ParserException(const ParserException &e); ParserException(const ParserException &e) = default;
virtual virtual ~ParserException() = default;
~ParserException(); const string &
void print(FILE *fd) const;
const char *
message() const message() const
{ {
return mes; return mes;

View File

@ -22,14 +22,14 @@ StaticAtoms::StaticAtoms(const StaticAtoms &a)
for (auto var : a.vars) for (auto var : a.vars)
{ {
const char *s = varnames.query(var.first); const char *s = varnames.query(var.first);
vars.insert(Tvarmap::value_type(s, var.second)); vars.emplace(s, var.second);
} }
// fill indices // fill indices
for (auto indice : a.indices) for (auto indice : a.indices)
{ {
const char *s = varnames.query(indice.second); const char *s = varnames.query(indice.second);
indices.insert(Tinvmap::value_type(indice.first, s)); indices.emplace(indice.first, s);
} }
} }
@ -50,7 +50,7 @@ StaticAtoms::import_atoms(const DynamicAtoms &da, OperationTree &otree, Tintintm
for (auto it : lmap) for (auto it : lmap)
{ {
int told = it.second; int told = it.second;
tmap.insert(Tintintmap::value_type(told, tnew)); tmap.emplace(told, tnew);
} }
} }
} }
@ -60,13 +60,9 @@ int
StaticAtoms::check(const char *name) const StaticAtoms::check(const char *name) const
{ {
if (DynamicAtoms::is_string_constant(name)) if (DynamicAtoms::is_string_constant(name))
{ return Constants::check(name);
return Constants::check(name);
}
else else
{ return check_variable(name);
return check_variable(name);
}
} }
int int
@ -76,7 +72,7 @@ StaticAtoms::index(const char *name) const
if (it == vars.end()) if (it == vars.end())
return -1; return -1;
else else
return (*it).second; return it->second;
} }
const char * const char *
@ -86,7 +82,7 @@ StaticAtoms::inv_index(int t) const
if (it == indices.end()) if (it == indices.end())
return nullptr; return nullptr;
else else
return (*it).second; return it->second;
} }
void void
@ -101,8 +97,8 @@ StaticAtoms::assign(const char *name, int t)
else else
{ {
const char *ss = varnames.insert(name); const char *ss = varnames.insert(name);
vars.insert(Tvarmap::value_type(ss, t)); vars.emplace(ss, t);
indices.insert(Tinvmap::value_type(t, ss)); indices.emplace(t, ss);
} }
} }
@ -111,9 +107,7 @@ StaticAtoms::variables() const
{ {
vector<int> res; vector<int> res;
for (auto var : vars) for (auto var : vars)
{ res.push_back(var.second);
res.push_back(var.second);
}
return res; return res;
} }
@ -133,5 +127,5 @@ StaticAtoms::print() const
varnames.print(); varnames.print();
printf("map to tree indices:\n"); printf("map to tree indices:\n");
for (auto var : vars) for (auto var : vars)
printf("%s\t->\t%d\n", var.first, var.second); printf(u8"%s\t\t%d\n", var.first, var.second);
} }

View File

@ -9,7 +9,6 @@
namespace ogp namespace ogp
{ {
class StaticAtoms : public Atoms, public Constants class StaticAtoms : public Atoms, public Constants
{ {
protected: protected:
@ -42,8 +41,7 @@ namespace ogp
import_atoms(da, otree, tmap); import_atoms(da, otree, tmap);
} }
/* Destructor. */ /* Destructor. */
~StaticAtoms() ~StaticAtoms() override = default;
override = default;
/** This imports atoms from dynamic atoms inserting the new /** This imports atoms from dynamic atoms inserting the new
* tree indices to the given tree (including constants). The * tree indices to the given tree (including constants). The
* mapping from old atoms to new atoms is traced in tmap. */ * mapping from old atoms to new atoms is traced in tmap. */

View File

@ -22,21 +22,21 @@ StaticFineAtoms::StaticFineAtoms(const StaticFineAtoms &sfa)
{ {
const char *name = varnames.query(sfa.params[i]); const char *name = varnames.query(sfa.params[i]);
params.push_back(name); params.push_back(name);
param_outer_map.insert(Tvarintmap::value_type(name, i)); param_outer_map.emplace(name, i);
} }
for (unsigned int i = 0; i < sfa.endovars.size(); i++) for (unsigned int i = 0; i < sfa.endovars.size(); i++)
{ {
const char *name = varnames.query(sfa.endovars[i]); const char *name = varnames.query(sfa.endovars[i]);
endovars.push_back(name); endovars.push_back(name);
endo_outer_map.insert(Tvarintmap::value_type(name, i)); endo_outer_map.emplace(name, i);
} }
for (unsigned int i = 0; i < sfa.exovars.size(); i++) for (unsigned int i = 0; i < sfa.exovars.size(); i++)
{ {
const char *name = varnames.query(sfa.exovars[i]); const char *name = varnames.query(sfa.exovars[i]);
exovars.push_back(name); exovars.push_back(name);
exo_outer_map.insert(Tvarintmap::value_type(name, i)); exo_outer_map.emplace(name, i);
} }
} }
@ -97,7 +97,7 @@ int
StaticFineAtoms::check_variable(const char *name) const StaticFineAtoms::check_variable(const char *name) const
{ {
const char *ss = varnames.query(name); const char *ss = varnames.query(name);
if (ss == nullptr) if (!ss)
throw ParserException(string("Variable <")+name+"> not declared.", 0); throw ParserException(string("Variable <")+name+"> not declared.", 0);
return index(name); return index(name);
} }
@ -139,7 +139,7 @@ StaticFineAtoms::name2outer_param(const char *name) const
if (it == param_outer_map.end()) if (it == param_outer_map.end())
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
"Name is not a parameter in StaticFineAtoms::name2outer_param"); "Name is not a parameter in StaticFineAtoms::name2outer_param");
return (*it).second; return it->second;
} }
int int
@ -149,7 +149,7 @@ StaticFineAtoms::name2outer_endo(const char *name) const
if (it == endo_outer_map.end()) if (it == endo_outer_map.end())
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
"Name is not an endogenous variable in StaticFineAtoms::name2outer_endo"); "Name is not an endogenous variable in StaticFineAtoms::name2outer_endo");
return (*it).second; return it->second;
} }
int int
@ -159,7 +159,7 @@ StaticFineAtoms::name2outer_exo(const char *name) const
if (it == exo_outer_map.end()) if (it == exo_outer_map.end())
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
"Name is not an exogenous variable in StaticFineAtoms::name2outer_exo"); "Name is not an exogenous variable in StaticFineAtoms::name2outer_exo");
return (*it).second; return it->second;
} }
void void
@ -195,10 +195,10 @@ StaticFineAtoms::print() const
StaticAtoms::print(); StaticAtoms::print();
printf("endo atoms map:\n"); printf("endo atoms map:\n");
for (unsigned int i = 0; i < endo_atoms_map.size(); i++) for (unsigned int i = 0; i < endo_atoms_map.size(); i++)
printf("%d --> %d\n", i, endo_atoms_map[i]); printf(u8"%d → %d\n", i, endo_atoms_map[i]);
printf("exo atoms map:\n"); printf("exo atoms map:\n");
for (unsigned int i = 0; i < exo_atoms_map.size(); i++) for (unsigned int i = 0; i < exo_atoms_map.size(); i++)
printf("%d --> %d\n", i, exo_atoms_map[i]); printf(u8"%d → %d\n", i, exo_atoms_map[i]);
printf("der atoms:\n"); printf("der atoms:\n");
for (unsigned int i = 0; i < der_atoms.size(); i++) for (unsigned int i = 0; i < der_atoms.size(); i++)
printf("%d\t%d\n", i, der_atoms[i]); printf("%d\t%d\n", i, der_atoms[i]);
@ -208,30 +208,30 @@ void
StaticFineAtoms::register_endo(const char *name) StaticFineAtoms::register_endo(const char *name)
{ {
const char *ss = varnames.query(name); const char *ss = varnames.query(name);
if (ss == nullptr) if (!ss)
throw ogp::ParserException(string("Endogenous variable <") throw ogp::ParserException(string("Endogenous variable <")
+name+"> not found in storage.", 0); +name+"> not found in storage.", 0);
endovars.push_back(ss); endovars.push_back(ss);
endo_outer_map.insert(Tvarintmap::value_type(ss, endovars.size()-1)); endo_outer_map.emplace(ss, endovars.size()-1);
} }
void void
StaticFineAtoms::register_exo(const char *name) StaticFineAtoms::register_exo(const char *name)
{ {
const char *ss = varnames.query(name); const char *ss = varnames.query(name);
if (ss == nullptr) if (!ss)
throw ogp::ParserException(string("Exogenous variable <") throw ogp::ParserException(string("Exogenous variable <")
+name+"> not found in storage.", 0); +name+"> not found in storage.", 0);
exovars.push_back(ss); exovars.push_back(ss);
exo_outer_map.insert(Tvarintmap::value_type(ss, exovars.size()-1)); exo_outer_map.emplace(ss, exovars.size()-1);
} }
void void
StaticFineAtoms::register_param(const char *name) StaticFineAtoms::register_param(const char *name)
{ {
const char *ss = varnames.query(name); const char *ss = varnames.query(name);
if (ss == nullptr) if (!ss)
throw ogp::ParserException(string("Parameter <")+name+"> not found in storage.", 0); throw ogp::ParserException(string("Parameter <")+name+"> not found in storage.", 0);
params.push_back(ss); params.push_back(ss);
param_outer_map.insert(Tvarintmap::value_type(ss, params.size()-1)); param_outer_map.emplace(ss, params.size()-1);
} }

View File

@ -10,7 +10,6 @@
namespace ogp namespace ogp
{ {
/** This class represents static atoms distinguishing between /** This class represents static atoms distinguishing between
* parameters, endogenous and exogenous variables. The class * parameters, endogenous and exogenous variables. The class
* maintains also ordering of all three categories (referenced as * maintains also ordering of all three categories (referenced as
@ -61,8 +60,7 @@ namespace ogp
* atoms of exogenous variables. */ * atoms of exogenous variables. */
vector<int> exo_atoms_map; vector<int> exo_atoms_map;
public: public:
StaticFineAtoms() StaticFineAtoms() = default;
= default;
/** Copy constructor making a new storage for atom names. */ /** Copy constructor making a new storage for atom names. */
StaticFineAtoms(const StaticFineAtoms &sfa); StaticFineAtoms(const StaticFineAtoms &sfa);
/** Conversion from dynamic FineAtoms taking its outer /** Conversion from dynamic FineAtoms taking its outer
@ -84,8 +82,7 @@ namespace ogp
{ {
StaticFineAtoms::import_atoms(fa, otree, tmap, dummy); StaticFineAtoms::import_atoms(fa, otree, tmap, dummy);
} }
~StaticFineAtoms() ~StaticFineAtoms() override = default;
override = default;
/** This adds atoms from dynamic atoms inserting new tree /** This adds atoms from dynamic atoms inserting new tree
* indices to the given tree and tracing the mapping from old * indices to the given tree and tracing the mapping from old
* atoms to new atoms in tmap. The ordering of the static * atoms to new atoms in tmap. The ordering of the static
@ -166,13 +163,13 @@ namespace ogp
int int
nexo() const nexo() const
{ {
return (int) exovars.size(); return static_cast<int>(exovars.size());
} }
/** Return the number of parameters. */ /** Return the number of parameters. */
int int
np() const np() const
{ {
return (int) (params.size()); return static_cast<int>(params.size());
} }
/** Register unique endogenous variable name. The order of /** Register unique endogenous variable name. The order of
* calls defines the endo outer ordering. The method is * calls defines the endo outer ordering. The method is
@ -202,7 +199,6 @@ namespace ogp
* storage. */ * storage. */
void register_param(const char *name); void register_param(const char *name);
}; };
}; };
#endif #endif

View File

@ -4,8 +4,6 @@
#include "tree.hh" #include "tree.hh"
#include <cstdlib>
#include <cmath> #include <cmath>
#include <limits> #include <limits>
@ -25,13 +23,11 @@ int
OperationTree::add_nulary() OperationTree::add_nulary()
{ {
int op = terms.size(); int op = terms.size();
Operation nulary; terms.push_back({});
terms.push_back(nulary);
_Tintset s; _Tintset s;
s.insert(op); s.insert(op);
nul_incidence.push_back(s); nul_incidence.push_back(s);
_Tderivmap empty; derivatives.push_back({});
derivatives.push_back(empty);
last_nulary = op; last_nulary = op;
return op; return op;
} }
@ -40,21 +36,21 @@ int
OperationTree::add_unary(code_t code, int op) OperationTree::add_unary(code_t code, int op)
{ {
if (op == zero if (op == zero
&& (code == UMINUS && (code == code_t::UMINUS
|| code == SIN || code == code_t::SIN
|| code == TAN || code == code_t::TAN
|| code == SQRT || code == code_t::SQRT
|| code == ERF)) || code == code_t::ERF))
return zero; return zero;
if ((op == zero && code == LOG) || op == nan) if ((op == zero && code == code_t::LOG) || op == nan)
return nan; return nan;
if (op == zero && (code == EXP if (op == zero && (code == code_t::EXP
|| code == COS || code == code_t::COS
|| code == ERFC)) || code == code_t::ERFC))
return one; return one;
Operation unary(code, op); Operation unary(code, op);
auto i = ((const _Topmap &) opmap).find(unary); auto i = opmap.find(unary);
if (i == opmap.end()) if (i == opmap.end())
{ {
int newop = terms.size(); int newop = terms.size();
@ -63,13 +59,13 @@ OperationTree::add_unary(code_t code, int op)
// copy incidence of the operand // copy incidence of the operand
nul_incidence.push_back(nul_incidence[op]); nul_incidence.push_back(nul_incidence[op]);
// insert it to opmap // insert it to opmap
opmap.insert(_Topval(unary, newop)); opmap.emplace(unary, newop);
// add empty map of derivatives // add empty map of derivatives
_Tderivmap empty; _Tderivmap empty;
derivatives.push_back(empty); derivatives.push_back(empty);
return newop; return newop;
} }
return (*i).second; return i->second;
} }
int int
@ -79,7 +75,7 @@ OperationTree::add_binary(code_t code, int op1, int op2)
if (op1 == nan || op2 == nan) if (op1 == nan || op2 == nan)
return nan; return nan;
// for plus // for plus
if (code == PLUS) if (code == code_t::PLUS)
{ {
if (op1 == zero && op2 == zero) if (op1 == zero && op2 == zero)
return zero; return zero;
@ -89,17 +85,17 @@ OperationTree::add_binary(code_t code, int op1, int op2)
return op1; return op1;
} }
// for minus // for minus
if (code == MINUS) if (code == code_t::MINUS)
{ {
if (op1 == zero && op2 == zero) if (op1 == zero && op2 == zero)
return zero; return zero;
else if (op1 == zero) else if (op1 == zero)
return add_unary(UMINUS, op2); return add_unary(code_t::UMINUS, op2);
else if (op2 == zero) else if (op2 == zero)
return op1; return op1;
} }
// for times // for times
if (code == TIMES) if (code == code_t::TIMES)
{ {
if (op1 == zero || op2 == zero) if (op1 == zero || op2 == zero)
return zero; return zero;
@ -109,7 +105,7 @@ OperationTree::add_binary(code_t code, int op1, int op2)
return op1; return op1;
} }
// for divide // for divide
if (code == DIVIDE) if (code == code_t::DIVIDE)
{ {
if (op1 == op2) if (op1 == op2)
return one; return one;
@ -119,7 +115,7 @@ OperationTree::add_binary(code_t code, int op1, int op2)
return nan; return nan;
} }
// for power // for power
if (code == POWER) if (code == code_t::POWER)
{ {
if (op1 == zero && op2 == zero) if (op1 == zero && op2 == zero)
return nan; return nan;
@ -134,7 +130,7 @@ OperationTree::add_binary(code_t code, int op1, int op2)
} }
// order operands of commutative operations // order operands of commutative operations
if (code == TIMES || code == PLUS) if (code == code_t::TIMES || code == code_t::PLUS)
if (op1 > op2) if (op1 > op2)
{ {
int tmp = op1; int tmp = op1;
@ -144,7 +140,7 @@ OperationTree::add_binary(code_t code, int op1, int op2)
// construct operation and check/add it // construct operation and check/add it
Operation binary(code, op1, op2); Operation binary(code, op1, op2);
auto i = ((const _Topmap &) opmap).find(binary); auto i = opmap.find(binary);
if (i == opmap.end()) if (i == opmap.end())
{ {
int newop = terms.size(); int newop = terms.size();
@ -153,164 +149,159 @@ OperationTree::add_binary(code_t code, int op1, int op2)
nul_incidence.push_back(nul_incidence[op1]); nul_incidence.push_back(nul_incidence[op1]);
nul_incidence.back().insert(nul_incidence[op2].begin(), nul_incidence[op2].end()); nul_incidence.back().insert(nul_incidence[op2].begin(), nul_incidence[op2].end());
// add to opmap // add to opmap
opmap.insert(_Topval(binary, newop)); opmap.emplace(binary, newop);
// add empty map of derivatives // add empty map of derivatives
_Tderivmap empty; _Tderivmap empty;
derivatives.push_back(empty); derivatives.push_back(empty);
return newop; return newop;
} }
return (*i).second; return i->second;
} }
int int
OperationTree::add_derivative(int t, int v) OperationTree::add_derivative(int t, int v)
{ {
if (t < 0 || t >= (int) terms.size()) if (t < 0 || t >= static_cast<int>(terms.size()))
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
"Wrong value for tree index in OperationTree::add_derivative"); "Wrong value for tree index in OperationTree::add_derivative");
// quick returns for nulary terms or empty incidence // quick returns for nulary terms or empty incidence
if (terms[t].nary() == 0 && t != v) if (terms[t].nary() == 0 && t != v)
{ return zero;
return zero;
}
if (terms[t].nary() == 0 && t == v) if (terms[t].nary() == 0 && t == v)
{ return one;
return one;
}
if (nul_incidence[t].end() == nul_incidence[t].find(v)) if (nul_incidence[t].end() == nul_incidence[t].find(v))
{ return zero;
return zero;
}
// quick return if the derivative has been registered // quick return if the derivative has been registered
_Tderivmap::const_iterator i = derivatives[t].find(v); auto i = derivatives[t].find(v);
if (i != derivatives[t].end()) if (i != derivatives[t].end())
return (*i).second; return i->second;
int res = -1; int res = -1;
switch (terms[t].getCode()) switch (terms[t].getCode())
{ {
case code_t::UMINUS:
case UMINUS:
{ {
int tmp = add_derivative(terms[t].getOp1(), v); int tmp = add_derivative(terms[t].getOp1(), v);
res = add_unary(UMINUS, tmp); res = add_unary(code_t::UMINUS, tmp);
break; break;
} }
case LOG: case code_t::LOG:
{ {
int tmp = add_derivative(terms[t].getOp1(), v); int tmp = add_derivative(terms[t].getOp1(), v);
res = add_binary(DIVIDE, tmp, terms[t].getOp1()); res = add_binary(code_t::DIVIDE, tmp, terms[t].getOp1());
break; break;
} }
case EXP: case code_t::EXP:
{ {
int tmp = add_derivative(terms[t].getOp1(), v); int tmp = add_derivative(terms[t].getOp1(), v);
res = add_binary(TIMES, t, tmp); res = add_binary(code_t::TIMES, t, tmp);
break; break;
} }
case SIN: case code_t::SIN:
{ {
int tmp = add_derivative(terms[t].getOp1(), v); int tmp = add_derivative(terms[t].getOp1(), v);
res = add_binary(TIMES, add_unary(COS, terms[t].getOp1()), tmp); res = add_binary(code_t::TIMES, add_unary(code_t::COS, terms[t].getOp1()), tmp);
break; break;
} }
case COS: case code_t::COS:
{ {
int tmp = add_derivative(terms[t].getOp1(), v); int tmp = add_derivative(terms[t].getOp1(), v);
res = add_unary(UMINUS, add_binary(TIMES, add_unary(SIN, terms[t].getOp1()), tmp)); res = add_unary(code_t::UMINUS, add_binary(code_t::TIMES, add_unary(code_t::SIN, terms[t].getOp1()), tmp));
break; break;
} }
case TAN: case code_t::TAN:
{ {
int tmp = add_derivative(terms[t].getOp1(), v); int tmp = add_derivative(terms[t].getOp1(), v);
int tmp2 = add_unary(COS, terms[t].getOp1()); int tmp2 = add_unary(code_t::COS, terms[t].getOp1());
res = add_binary(DIVIDE, tmp, add_binary(TIMES, tmp2, tmp2)); res = add_binary(code_t::DIVIDE, tmp, add_binary(code_t::TIMES, tmp2, tmp2));
break; break;
} }
case SQRT: case code_t::SQRT:
{ {
int tmp = add_derivative(terms[t].getOp1(), v); int tmp = add_derivative(terms[t].getOp1(), v);
res = add_binary(DIVIDE, tmp, res = add_binary(code_t::DIVIDE, tmp,
add_binary(PLUS, t, t)); add_binary(code_t::PLUS, t, t));
break; break;
} }
case ERF: case code_t::ERF:
{ {
int tmp = add_binary(TIMES, terms[t].getOp1(), terms[t].getOp1()); int tmp = add_binary(code_t::TIMES, terms[t].getOp1(), terms[t].getOp1());
tmp = add_unary(UMINUS, tmp); tmp = add_unary(code_t::UMINUS, tmp);
tmp = add_unary(EXP, tmp); tmp = add_unary(code_t::EXP, tmp);
int der = add_derivative(terms[t].getOp1(), v); int der = add_derivative(terms[t].getOp1(), v);
tmp = add_binary(TIMES, tmp, der); tmp = add_binary(code_t::TIMES, tmp, der);
res = add_binary(TIMES, two_over_pi, tmp); res = add_binary(code_t::TIMES, two_over_pi, tmp);
break; break;
} }
case ERFC: case code_t::ERFC:
{ {
int tmp = add_binary(TIMES, terms[t].getOp1(), terms[t].getOp1()); int tmp = add_binary(code_t::TIMES, terms[t].getOp1(), terms[t].getOp1());
tmp = add_unary(UMINUS, tmp); tmp = add_unary(code_t::UMINUS, tmp);
tmp = add_unary(EXP, tmp); tmp = add_unary(code_t::EXP, tmp);
int der = add_derivative(terms[t].getOp1(), v); int der = add_derivative(terms[t].getOp1(), v);
tmp = add_binary(TIMES, tmp, der); tmp = add_binary(code_t::TIMES, tmp, der);
tmp = add_binary(TIMES, two_over_pi, tmp); tmp = add_binary(code_t::TIMES, two_over_pi, tmp);
res = add_unary(UMINUS, tmp); res = add_unary(code_t::UMINUS, tmp);
break; break;
} }
case PLUS: case code_t::PLUS:
{ {
int tmp1 = add_derivative(terms[t].getOp1(), v); int tmp1 = add_derivative(terms[t].getOp1(), v);
int tmp2 = add_derivative(terms[t].getOp2(), v); int tmp2 = add_derivative(terms[t].getOp2(), v);
res = add_binary(PLUS, tmp1, tmp2); res = add_binary(code_t::PLUS, tmp1, tmp2);
break; break;
} }
case MINUS: case code_t::MINUS:
{ {
int tmp1 = add_derivative(terms[t].getOp1(), v); int tmp1 = add_derivative(terms[t].getOp1(), v);
int tmp2 = add_derivative(terms[t].getOp2(), v); int tmp2 = add_derivative(terms[t].getOp2(), v);
res = add_binary(MINUS, tmp1, tmp2); res = add_binary(code_t::MINUS, tmp1, tmp2);
break; break;
} }
case TIMES: case code_t::TIMES:
{ {
int tmp1 = add_derivative(terms[t].getOp1(), v); int tmp1 = add_derivative(terms[t].getOp1(), v);
int tmp2 = add_derivative(terms[t].getOp2(), v); int tmp2 = add_derivative(terms[t].getOp2(), v);
int res1 = add_binary(TIMES, terms[t].getOp1(), tmp2); int res1 = add_binary(code_t::TIMES, terms[t].getOp1(), tmp2);
int res2 = add_binary(TIMES, tmp1, terms[t].getOp2()); int res2 = add_binary(code_t::TIMES, tmp1, terms[t].getOp2());
res = add_binary(PLUS, res1, res2); res = add_binary(code_t::PLUS, res1, res2);
break; break;
} }
case DIVIDE: case code_t::DIVIDE:
{ {
int tmp1 = add_derivative(terms[t].getOp1(), v); int tmp1 = add_derivative(terms[t].getOp1(), v);
int tmp2 = add_derivative(terms[t].getOp2(), v); int tmp2 = add_derivative(terms[t].getOp2(), v);
if (tmp2 == zero) if (tmp2 == zero)
res = add_binary(DIVIDE, tmp1, terms[t].getOp2()); res = add_binary(code_t::DIVIDE, tmp1, terms[t].getOp2());
else else
{ {
int nom = add_binary(MINUS, int nom = add_binary(code_t::MINUS,
add_binary(TIMES, tmp1, terms[t].getOp2()), add_binary(code_t::TIMES, tmp1, terms[t].getOp2()),
add_binary(TIMES, tmp2, terms[t].getOp1())); add_binary(code_t::TIMES, tmp2, terms[t].getOp1()));
int den = add_binary(TIMES, terms[t].getOp2(), terms[t].getOp2()); int den = add_binary(code_t::TIMES, terms[t].getOp2(), terms[t].getOp2());
res = add_binary(DIVIDE, nom, den); res = add_binary(code_t::DIVIDE, nom, den);
} }
break; break;
} }
case POWER: case code_t::POWER:
{ {
int tmp1 = add_derivative(terms[t].getOp1(), v); int tmp1 = add_derivative(terms[t].getOp1(), v);
int tmp2 = add_derivative(terms[t].getOp2(), v); int tmp2 = add_derivative(terms[t].getOp2(), v);
int s1 = add_binary(TIMES, tmp2, int s1 = add_binary(code_t::TIMES, tmp2,
add_binary(TIMES, t, add_binary(code_t::TIMES, t,
add_unary(LOG, terms[t].getOp1()))); add_unary(code_t::LOG, terms[t].getOp1())));
int s2 = add_binary(TIMES, tmp1, int s2 = add_binary(code_t::TIMES, tmp1,
add_binary(TIMES, terms[t].getOp2(), add_binary(code_t::TIMES, terms[t].getOp2(),
add_binary(POWER, terms[t].getOp1(), add_binary(code_t::POWER, terms[t].getOp1(),
add_binary(MINUS, terms[t].getOp2(), one)))); add_binary(code_t::MINUS, terms[t].getOp2(), one))));
res = add_binary(PLUS, s1, s2); res = add_binary(code_t::PLUS, s1, s2);
break; break;
} }
case NONE: case code_t::NONE:
break; break;
} }
@ -336,7 +327,7 @@ OperationTree::add_substitution(int t, const map<int, int> &subst,
// return substitution of t if it is in the map // return substitution of t if it is in the map
auto it = subst.find(t); auto it = subst.find(t);
if (subst.end() != it) if (subst.end() != it)
return (*it).second; return it->second;
int nary = otree.terms[t].nary(); int nary = otree.terms[t].nary();
if (nary == 2) if (nary == 2)
@ -391,7 +382,7 @@ void
OperationTree::register_derivative(int t, int v, int tder) OperationTree::register_derivative(int t, int v, int tder)
{ {
// todo: might check that the insert inserts a new pair // todo: might check that the insert inserts a new pair
derivatives[t].insert(_Tderivmap::value_type(v, tder)); derivatives[t].emplace(v, tder);
} }
unordered_set<int> unordered_set<int>
@ -416,9 +407,7 @@ OperationTree::select_terms(int t, const opselector &sel, unordered_set<int> &su
select_terms(op.getOp2(), sel, subterms); select_terms(op.getOp2(), sel, subterms);
} }
else if (op.nary() == 1) else if (op.nary() == 1)
{ select_terms(op.getOp1(), sel, subterms);
select_terms(op.getOp1(), sel, subterms);
}
} }
unordered_set<int> unordered_set<int>
@ -473,23 +462,23 @@ OperationTree::forget_derivative_maps()
} }
void void
OperationTree::print_operation_tree(int t, FILE *fd, OperationFormatter &f) const OperationTree::print_operation_tree(int t, std::ostream &os, OperationFormatter &f) const
{ {
f.format(terms[t], t, fd); f.format(terms[t], t, os);
} }
void void
OperationTree::print_operation(int t) const OperationTree::print_operation(int t) const
{ {
DefaultOperationFormatter dof(*this); DefaultOperationFormatter dof(*this);
print_operation_tree(t, stdout, dof); print_operation_tree(t, std::cout, dof);
} }
void void
OperationTree::update_nul_incidence_after_nularify(int t) OperationTree::update_nul_incidence_after_nularify(int t)
{ {
unordered_set<int> updated; unordered_set<int> updated;
for (int tnode = num_constants; tnode < (int) terms.size(); tnode++) for (int tnode = num_constants; tnode < static_cast<int>(terms.size()); tnode++)
{ {
const Operation &op = terms[tnode]; const Operation &op = terms[tnode];
if (op.nary() == 2) if (op.nary() == 2)
@ -535,12 +524,12 @@ OperationTree::update_nul_incidence_after_nularify(int t)
EvalTree::EvalTree(const OperationTree &ot, int last) EvalTree::EvalTree(const OperationTree &ot, int last)
: otree(ot), : otree(ot),
values(new double[(last == -1) ? ot.terms.size() : last+1]), values(std::make_unique<double[]>((last == -1) ? ot.terms.size() : last+1)),
flags(new bool[(last == -1) ? ot.terms.size() : last+1]), flags(std::make_unique<bool[]>((last == -1) ? ot.terms.size() : last+1)),
last_operation((last == -1) ? ot.terms.size()-1 : last) last_operation((last == -1) ? ot.terms.size()-1 : last)
{ {
if (last_operation < OperationTree::num_constants-1 if (last_operation < OperationTree::num_constants-1
|| last_operation > (int) ot.terms.size()-1) || last_operation > static_cast<int>(ot.terms.size())-1)
throw ogu::Exception(__FILE__, __LINE__, throw ogu::Exception(__FILE__, __LINE__,
"Wrong last in EvalTree constructor."); "Wrong last in EvalTree constructor.");
@ -594,23 +583,23 @@ EvalTree::eval(int t)
{ {
double r1 = eval(op.getOp1()); double r1 = eval(op.getOp1());
double res; double res;
if (op.getCode() == UMINUS) if (op.getCode() == code_t::UMINUS)
res = -r1; res = -r1;
else if (op.getCode() == LOG) else if (op.getCode() == code_t::LOG)
res = log(r1); res = log(r1);
else if (op.getCode() == EXP) else if (op.getCode() == code_t::EXP)
res = exp(r1); res = exp(r1);
else if (op.getCode() == SIN) else if (op.getCode() == code_t::SIN)
res = sin(r1); res = sin(r1);
else if (op.getCode() == COS) else if (op.getCode() == code_t::COS)
res = cos(r1); res = cos(r1);
else if (op.getCode() == TAN) else if (op.getCode() == code_t::TAN)
res = tan(r1); res = tan(r1);
else if (op.getCode() == SQRT) else if (op.getCode() == code_t::SQRT)
res = sqrt(r1); res = sqrt(r1);
else if (op.getCode() == ERF) else if (op.getCode() == code_t::ERF)
res = erf(r1); res = erf(r1);
else if (op.getCode() == ERFC) else if (op.getCode() == code_t::ERFC)
res = erfc(r1); res = erfc(r1);
else else
{ {
@ -624,19 +613,19 @@ EvalTree::eval(int t)
else if (op.nary() == 2) else if (op.nary() == 2)
{ {
double res; double res;
if (op.getCode() == PLUS) if (op.getCode() == code_t::PLUS)
{ {
double r1 = eval(op.getOp1()); double r1 = eval(op.getOp1());
double r2 = eval(op.getOp2()); double r2 = eval(op.getOp2());
res = r1 + r2; res = r1 + r2;
} }
else if (op.getCode() == MINUS) else if (op.getCode() == code_t::MINUS)
{ {
double r1 = eval(op.getOp1()); double r1 = eval(op.getOp1());
double r2 = eval(op.getOp2()); double r2 = eval(op.getOp2());
res = r1 - r2; res = r1 - r2;
} }
else if (op.getCode() == TIMES) else if (op.getCode() == code_t::TIMES)
{ {
// pickup less complex formula first // pickup less complex formula first
unsigned int nul1 = otree.nulary_of_term(op.getOp1()).size(); unsigned int nul1 = otree.nulary_of_term(op.getOp1()).size();
@ -664,7 +653,7 @@ EvalTree::eval(int t)
} }
} }
} }
else if (op.getCode() == DIVIDE) else if (op.getCode() == code_t::DIVIDE)
{ {
double r1 = eval(op.getOp1()); double r1 = eval(op.getOp1());
if (r1 == 0) if (r1 == 0)
@ -675,7 +664,7 @@ EvalTree::eval(int t)
res = r1 / r2; res = r1 / r2;
} }
} }
else if (op.getCode() == POWER) else if (op.getCode() == code_t::POWER)
{ {
// suppose that more complex is the first op in average // suppose that more complex is the first op in average
double r2 = eval(op.getOp2()); double r2 = eval(op.getOp2());
@ -729,7 +718,7 @@ EvalTree::print() const
} }
void void
DefaultOperationFormatter::format(const Operation &op, int t, FILE *fd) DefaultOperationFormatter::format(const Operation &op, int t, std::ostream &os)
{ {
// add to the stop_set // add to the stop_set
if (stop_set.end() == stop_set.find(t)) if (stop_set.end() == stop_set.find(t))
@ -745,68 +734,66 @@ DefaultOperationFormatter::format(const Operation &op, int t, FILE *fd)
int t2 = op.getOp2(); int t2 = op.getOp2();
const Operation &op2 = otree.terms[t2]; const Operation &op2 = otree.terms[t2];
if (op1.nary() > 0) if (op1.nary() > 0)
format(op1, t1, fd); format(op1, t1, os);
if (op2.nary() > 0) if (op2.nary() > 0)
format(op2, t2, fd); format(op2, t2, os);
} }
if (op.nary() == 1) if (op.nary() == 1)
{ {
int t1 = op.getOp1(); int t1 = op.getOp1();
const Operation &op1 = otree.terms[t1]; const Operation &op1 = otree.terms[t1];
if (op1.nary() > 0) if (op1.nary() > 0)
format(op1, t1, fd); format(op1, t1, os);
} }
// print 'term =' // print 'term ='
format_term(t, fd); format_term(t, os);
fprintf(fd, " = "); os << " = ";
if (op.nary() == 0) if (op.nary() == 0)
{ format_nulary(t, os);
format_nulary(t, fd);
}
else if (op.nary() == 1) else if (op.nary() == 1)
{ {
int t1 = op.getOp1(); int t1 = op.getOp1();
const Operation &op1 = otree.terms[t1]; const Operation &op1 = otree.terms[t1];
const char *opname = "unknown"; std::string opname = "unknown";
switch (op.getCode()) switch (op.getCode())
{ {
case UMINUS: case code_t::UMINUS:
opname = "-"; opname = "-";
break; break;
case LOG: case code_t::LOG:
opname = "log"; opname = "log";
break; break;
case EXP: case code_t::EXP:
opname = "exp"; opname = "exp";
break; break;
case SIN: case code_t::SIN:
opname = "sin"; opname = "sin";
break; break;
case COS: case code_t::COS:
opname = "cos"; opname = "cos";
break; break;
case TAN: case code_t::TAN:
opname = "tan"; opname = "tan";
break; break;
case SQRT: case code_t::SQRT:
opname = "sqrt"; opname = "sqrt";
break; break;
case ERF: case code_t::ERF:
opname = "erf"; opname = "erf";
break; break;
case ERFC: case code_t::ERFC:
opname = "erfc"; opname = "erfc";
break; break;
default: default:
break; break;
} }
fprintf(fd, "%s(", opname); os << opname << '(';
if (op1.nary() == 0) if (op1.nary() == 0)
format_nulary(t1, fd); format_nulary(t1, os);
else else
format_term(t1, fd); format_term(t1, os);
fprintf(fd, ")"); os << ")";
} }
else else
{ {
@ -814,65 +801,64 @@ DefaultOperationFormatter::format(const Operation &op, int t, FILE *fd)
const Operation &op1 = otree.terms[t1]; const Operation &op1 = otree.terms[t1];
int t2 = op.getOp2(); int t2 = op.getOp2();
const Operation &op2 = otree.terms[t2]; const Operation &op2 = otree.terms[t2];
const char *opname = "unknown"; std::string opname = "unknown";
switch (op.getCode()) switch (op.getCode())
{ {
case PLUS: case code_t::PLUS:
opname = "+"; opname = "+";
break; break;
case MINUS: case code_t::MINUS:
opname = "-"; opname = "-";
break; break;
case TIMES: case code_t::TIMES:
opname = "*"; opname = "*";
break; break;
case DIVIDE: case code_t::DIVIDE:
opname = "/"; opname = "/";
break; break;
case POWER: case code_t::POWER:
opname = "^"; opname = "^";
break; break;
default: default:
break; break;
} }
if (op1.nary() == 0) if (op1.nary() == 0)
format_nulary(t1, fd); format_nulary(t1, os);
else else
format_term(t1, fd); format_term(t1, os);
fprintf(fd, " %s ", opname); os << ' ' << opname << ' ';
if (op2.nary() == 0) if (op2.nary() == 0)
format_nulary(t2, fd); format_nulary(t2, os);
else else
format_term(t2, fd); format_term(t2, os);
} }
print_delim(fd); print_delim(os);
} }
void void
DefaultOperationFormatter::format_term(int t, FILE *fd) const DefaultOperationFormatter::format_term(int t, std::ostream &os) const
{ {
fprintf(fd, "$%d", t); os << '$' << t;
} }
void void
DefaultOperationFormatter::format_nulary(int t, FILE *fd) const DefaultOperationFormatter::format_nulary(int t, std::ostream &os) const
{ {
if (t == OperationTree::zero) if (t == OperationTree::zero)
fprintf(fd, "0"); os << '0';
else if (t == OperationTree::one) else if (t == OperationTree::one)
fprintf(fd, "1"); os << '1';
else if (t == OperationTree::nan) else if (t == OperationTree::nan)
fprintf(fd, "NaN"); os << "NaN";
else else
fprintf(fd, "$%d", t); os << '$' << t;
} }
void void
DefaultOperationFormatter::print_delim(FILE *fd) const DefaultOperationFormatter::print_delim(std::ostream &os) const
{ {
fprintf(fd, ";\n"); os << ";\n";
} }
std::string std::string
@ -907,31 +893,31 @@ OperationStringConvertor::convert(const Operation &op, int t) const
const char *opname = "unknown"; const char *opname = "unknown";
switch (op.getCode()) switch (op.getCode())
{ {
case UMINUS: case code_t::UMINUS:
opname = "-"; opname = "-";
break; break;
case LOG: case code_t::LOG:
opname = "log"; opname = "log";
break; break;
case EXP: case code_t::EXP:
opname = "exp"; opname = "exp";
break; break;
case SIN: case code_t::SIN:
opname = "sin"; opname = "sin";
break; break;
case COS: case code_t::COS:
opname = "cos"; opname = "cos";
break; break;
case TAN: case code_t::TAN:
opname = "tan"; opname = "tan";
break; break;
case SQRT: case code_t::SQRT:
opname = "sqrt"; opname = "sqrt";
break; break;
case ERF: case code_t::ERF:
opname = "erf"; opname = "erf";
break; break;
case ERFC: case code_t::ERFC:
opname = "erfc"; opname = "erfc";
break; break;
default: default:
@ -949,19 +935,19 @@ OperationStringConvertor::convert(const Operation &op, int t) const
const char *opname = "unknown"; const char *opname = "unknown";
switch (op.getCode()) switch (op.getCode())
{ {
case PLUS: case code_t::PLUS:
opname = "+"; opname = "+";
break; break;
case MINUS: case code_t::MINUS:
opname = "-"; opname = "-";
break; break;
case TIMES: case code_t::TIMES:
opname = "*"; opname = "*";
break; break;
case DIVIDE: case code_t::DIVIDE:
opname = "/"; opname = "/";
break; break;
case POWER: case code_t::POWER:
opname = "^"; opname = "^";
break; break;
default: default:
@ -970,15 +956,15 @@ OperationStringConvertor::convert(const Operation &op, int t) const
// decide about parenthesis // decide about parenthesis
bool op1_par = true; bool op1_par = true;
bool op2_par = true; bool op2_par = true;
if (op.getCode() == PLUS) if (op.getCode() == code_t::PLUS)
{ {
op1_par = false; op1_par = false;
op2_par = false; op2_par = false;
} }
else if (op.getCode() == MINUS) else if (op.getCode() == code_t::MINUS)
{ {
op1_par = false; op1_par = false;
if (op2.getCode() != MINUS && op2.getCode() != PLUS) if (op2.getCode() != code_t::MINUS && op2.getCode() != code_t::PLUS)
op2_par = false; op2_par = false;
} }
else else

View File

@ -8,11 +8,11 @@
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <cstdio> #include <ostream>
#include <memory>
namespace ogp namespace ogp
{ {
using std::unordered_set; using std::unordered_set;
using std::unordered_map; using std::unordered_map;
using std::vector; using std::vector;
@ -24,15 +24,15 @@ namespace ogp
* codes, he should update the code of #OperationTree::add_unary, * codes, he should update the code of #OperationTree::add_unary,
* #OperationTree::add_binary, and of course * #OperationTree::add_binary, and of course
* #OperationTree::add_derivative. */ * #OperationTree::add_derivative. */
enum code_t {NONE, UMINUS, LOG, EXP, SIN, COS, TAN, SQRT, ERF, enum class code_t {NONE, UMINUS, LOG, EXP, SIN, COS, TAN, SQRT, ERF,
ERFC, PLUS, MINUS, TIMES, DIVIDE, POWER}; ERFC, PLUS, MINUS, TIMES, DIVIDE, POWER};
/** Class representing a nulary, unary, or binary operation. */ /** Class representing a nulary, unary, or binary operation. */
class Operation class Operation
{ {
protected: protected:
/** Code of the operation. */ /** Code of the operation. */
code_t code{NONE}; code_t code{code_t::NONE};
/** First operand. If none, then it is -1. */ /** First operand. If none, then it is -1. */
int op1{-1}; int op1{-1};
/** Second operand. If none, then it is -1. */ /** Second operand. If none, then it is -1. */
@ -50,18 +50,12 @@ namespace ogp
{ {
} }
/** Constructs a nulary operation. */ /** Constructs a nulary operation. */
Operation() Operation() = default;
= default;
/** A copy constructor. */ /** A copy constructor. */
Operation(const Operation &op) Operation(const Operation &op) = default;
= default;
/** Operator =. */ /** Operator =. */
Operation & Operation &operator=(const Operation &op) = default;
operator=(const Operation &op)
= default;
/** Operator ==. */ /** Operator ==. */
bool bool
operator==(const Operation &op) const operator==(const Operation &op) const
@ -86,7 +80,7 @@ namespace ogp
size_t size_t
hashval() const hashval() const
{ {
return op2+1 + (op1+1)^15 + code^30; return op2+1 + (op1+1)^15 + static_cast<int>(code)^30;
} }
code_t code_t
@ -104,7 +98,6 @@ namespace ogp
{ {
return op2; return op2;
} }
}; };
/** This struct is a predicate for ordering of the operations in /** This struct is a predicate for ordering of the operations in
@ -133,8 +126,7 @@ namespace ogp
struct opselector struct opselector
{ {
virtual bool operator()(int t) const = 0; virtual bool operator()(int t) const = 0;
virtual ~opselector() virtual ~opselector() = default;
= default;
}; };
/** Forward declaration of OperationFormatter. */ /** Forward declaration of OperationFormatter. */
@ -182,7 +174,6 @@ namespace ogp
/** This defines a type for a map mapping the unary and binary /** This defines a type for a map mapping the unary and binary
* operations to their indices. */ * operations to their indices. */
using _Topmap = unordered_map<Operation, int, ophash>; using _Topmap = unordered_map<Operation, int, ophash>;
using _Topval = _Topmap::value_type;
/** This is the map mapping the unary and binary operations to /** This is the map mapping the unary and binary operations to
* the indices of the terms.*/ * the indices of the terms.*/
@ -205,25 +196,18 @@ namespace ogp
/** The tree index of the last nulary term. */ /** The tree index of the last nulary term. */
int last_nulary; int last_nulary;
public: public:
/** This is a number of constants set in the following
* enum. This number reserves space in a vector of terms for
* the constants. */
static const int num_constants = 4;
/** Enumeration for special terms. We need zero, one, nan and /** Enumeration for special terms. We need zero, one, nan and
* 2/pi. These will be always first four terms having indices * 2/pi. These will be always first four terms having indices
* zero, one and two, three. If adding anything to this * zero, one and two, three. If adding anything to this
* enumeration, make sure you have updated num_constants above.*/ * enumeration, make sure num_constants remains the last one.*/
enum {zero = 0, one = 1, nan = 2, two_over_pi = 3}; enum {zero, one, nan, two_over_pi, num_constants};
/** The unique constructor which initializes the object to /** The unique constructor which initializes the object to
* contain only zero, one and nan and two_over_pi.*/ * contain only zero, one and nan and two_over_pi.*/
OperationTree(); OperationTree();
/** Copy constructor. */ /** Copy constructor. */
OperationTree(const OperationTree &ot) OperationTree(const OperationTree &ot) = default;
= default;
/** Add a nulary operation. The caller is responsible for not /** Add a nulary operation. The caller is responsible for not
* inserting two semantically equivalent nulary operations. * inserting two semantically equivalent nulary operations.
@ -323,7 +307,7 @@ namespace ogp
/** This outputs the operation to the given file descriptor /** This outputs the operation to the given file descriptor
* using the given OperationFormatter. */ * using the given OperationFormatter. */
void print_operation_tree(int t, FILE *fd, OperationFormatter &f) const; void print_operation_tree(int t, std::ostream &os, OperationFormatter &f) const;
/** Debug print of a given operation: */ /** Debug print of a given operation: */
void print_operation(int t) const; void print_operation(int t) const;
@ -339,7 +323,7 @@ namespace ogp
int int
get_num_op() const get_num_op() const
{ {
return (int) (terms.size()); return static_cast<int>(terms.size());
} }
private: private:
/** This registers a calculated derivative of the term in the /** This registers a calculated derivative of the term in the
@ -391,9 +375,9 @@ namespace ogp
* are done. */ * are done. */
const OperationTree &otree; const OperationTree &otree;
/** The array of values. */ /** The array of values. */
double *const values; const std::unique_ptr<double[]> values;
/** The array of evaluation flags. */ /** The array of evaluation flags. */
bool *const flags; const std::unique_ptr<bool[]> flags;
/** The index of last operation in the EvalTree. Length of /** The index of last operation in the EvalTree. Length of
* values and flags will be then last_operation+1. */ * values and flags will be then last_operation+1. */
int last_operation; int last_operation;
@ -404,10 +388,7 @@ namespace ogp
* (included). */ * (included). */
EvalTree(const OperationTree &otree, int last = -1); EvalTree(const OperationTree &otree, int last = -1);
EvalTree(const EvalTree &) = delete; EvalTree(const EvalTree &) = delete;
virtual ~EvalTree() virtual ~EvalTree() = default;
{
delete [] values; delete [] flags;
}
/** Set evaluation flag to all terms (besides the first /** Set evaluation flag to all terms (besides the first
* special terms) to false. */ * special terms) to false. */
void reset_all(); void reset_all();
@ -431,8 +412,7 @@ namespace ogp
{ {
public: public:
/** Empty virtual destructor. */ /** Empty virtual destructor. */
virtual ~OperationFormatter() virtual ~OperationFormatter() = default;
= default;
/** Print the formatted operation op with a given tree index t /** Print the formatted operation op with a given tree index t
* to a given descriptor. (See class OperationTree to know * to a given descriptor. (See class OperationTree to know
* what is a tree index.) This prints all the tree. This * what is a tree index.) This prints all the tree. This
@ -441,7 +421,7 @@ namespace ogp
* term, the right hand side is a string representation of the * term, the right hand side is a string representation of the
* operation (which will refer to other string representation * operation (which will refer to other string representation
* of subterms). */ * of subterms). */
virtual void format(const Operation &op, int t, FILE *fd) = 0; virtual void format(const Operation &op, int t, std::ostream &os) = 0;
}; };
/** The default formatter formats the formulas with a usual syntax /** The default formatter formats the formulas with a usual syntax
@ -460,23 +440,22 @@ namespace ogp
{ {
} }
/** Format the operation with the default syntax. */ /** Format the operation with the default syntax. */
void format(const Operation &op, int t, FILE *fd) override; void format(const Operation &op, int t, std::ostream &os) override;
/** This prints a string represenation of the given term, for /** This prints a string represenation of the given term, for
* example 'tmp10' for term 10. In this implementation it * example 'tmp10' for term 10. In this implementation it
* prints $10. */ * prints $10. */
virtual void format_term(int t, FILE *fd) const; virtual void format_term(int t, std::ostream &os) const;
/** Print a string representation of the nulary term. */ /** Print a string representation of the nulary term. */
virtual void format_nulary(int t, FILE *fd) const; virtual void format_nulary(int t, std::ostream &os) const;
/** Print a delimiter between two statements. By default it is /** Print a delimiter between two statements. By default it is
* "\n". */ * "\n". */
virtual void print_delim(FILE *fd) const; virtual void print_delim(std::ostream &os) const;
}; };
class NularyStringConvertor class NularyStringConvertor
{ {
public: public:
virtual ~NularyStringConvertor() virtual ~NularyStringConvertor() = default;
= default;
/** Return the string representation of the atom with the tree /** Return the string representation of the atom with the tree
* index t. */ * index t. */
virtual std::string convert(int t) const = 0; virtual std::string convert(int t) const = 0;
@ -494,8 +473,7 @@ namespace ogp
{ {
} }
/** Empty virtual destructor. */ /** Empty virtual destructor. */
virtual ~OperationStringConvertor() virtual ~OperationStringConvertor() = default;
= default;
/** Convert the operation to the string mathematical /** Convert the operation to the string mathematical
* representation. This does not write any equation, just * representation. This does not write any equation, just
* returns a string representation of the formula. */ * returns a string representation of the formula. */

View File

@ -14,6 +14,9 @@
#include <cmath> #include <cmath>
#include <climits> #include <climits>
#include <ostream> #include <ostream>
#include <memory>
#include <algorithm>
#include <iomanip>
using namespace ogdyn; using namespace ogdyn;
@ -117,7 +120,7 @@ DynareModel::print() const
{ {
int tf = eqs.formula(i); int tf = eqs.formula(i);
printf("formula %d:\n", tf); printf("formula %d:\n", tf);
eqs.getTree().print_operation_tree(tf, stdout, dof); eqs.getTree().print_operation_tree(tf, std::cout, dof);
} }
} }
@ -588,43 +591,40 @@ extern ogp::location_type dynglob_lloc;
void void
DynareParser::parse_glob(int length, const char *stream) DynareParser::parse_glob(int length, const char *stream)
{ {
auto *buffer = new char[length+2]; auto buffer = std::make_unique<char[]>(length+2);
strncpy(buffer, stream, length); std::copy_n(stream, length, buffer.get());
buffer[length] = '\0'; buffer[length] = '\0';
buffer[length+1] = '\0'; buffer[length+1] = '\0';
void *p = dynglob__scan_buffer(buffer, (unsigned int) length+2); void *p = dynglob__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
dynare_parser = this; dynare_parser = this;
dynglob_parse(); dynglob_parse();
delete [] buffer;
dynglob__destroy_buffer(p); dynglob__destroy_buffer(p);
} }
int int
DynareParser::parse_order(int len, const char *str) DynareParser::parse_order(int len, const char *str)
{ {
auto *buf = new char[len+1]; auto buf = std::make_unique<char[]>(len+1);
strncpy(buf, str, len); std::copy_n(str, len, buf.get());
buf[len] = '\0'; buf[len] = '\0';
int res; int res;
sscanf(buf, "%d", &res); sscanf(buf.get(), "%d", &res);
delete [] buf;
return res; return res;
} }
int int
DynareParser::parse_pldiscount(int len, const char *str) DynareParser::parse_pldiscount(int len, const char *str)
{ {
auto *buf = new char[len+1]; auto buf = std::make_unique<char[]>(len+1);
strncpy(buf, str, len); std::copy_n(str, len, buf.get());
buf[len] = '\0'; buf[len] = '\0';
if (!atoms.is_type(buf, DynareDynamicAtoms::param)) if (!atoms.is_type(buf.get(), DynareDynamicAtoms::param))
throw ogp::ParserException(std::string("Name ") + buf + " is not a parameter", 0); throw ogp::ParserException(std::string("Name ") + buf.get() + " is not a parameter", 0);
int t = atoms.index(buf, 0); int t = atoms.index(buf.get(), 0);
if (t == -1) if (t == -1)
t = eqs.add_nulary(buf); t = eqs.add_nulary(buf.get());
delete [] buf;
return t; return t;
} }
@ -712,14 +712,14 @@ NLSelector::operator()(int t) const
} }
else if (nary == 1) else if (nary == 1)
{ {
if (op.getCode() == ogp::UMINUS) if (op.getCode() == ogp::code_t::UMINUS)
return false; return false;
else else
return true; return true;
} }
else else
{ {
if (op.getCode() == ogp::TIMES) if (op.getCode() == ogp::code_t::TIMES)
// if at least one operand is constant, than the TIMES is linear // if at least one operand is constant, than the TIMES is linear
if (model.is_constant_term(op.getOp1()) if (model.is_constant_term(op.getOp1())
|| model.is_constant_term(op.getOp2())) || model.is_constant_term(op.getOp2()))
@ -727,11 +727,11 @@ NLSelector::operator()(int t) const
else else
return true; return true;
// both PLUS and MINUS are linear // both PLUS and MINUS are linear
if (op.getCode() == ogp::PLUS if (op.getCode() == ogp::code_t::PLUS
|| op.getCode() == ogp::MINUS) || op.getCode() == ogp::code_t::MINUS)
return false; return false;
// POWER is linear if exponent or base is 0 or one // POWER is linear if exponent or base is 0 or one
if (op.getCode() == ogp::POWER if (op.getCode() == ogp::code_t::POWER
&& (op.getOp1() == ogp::OperationTree::zero && (op.getOp1() == ogp::OperationTree::zero
|| op.getOp1() == ogp::OperationTree::one || op.getOp1() == ogp::OperationTree::one
|| op.getOp2() == ogp::OperationTree::zero || op.getOp2() == ogp::OperationTree::zero
@ -741,7 +741,7 @@ NLSelector::operator()(int t) const
return true; return true;
// DIVIDE is linear if the denominator is constant, or if // DIVIDE is linear if the denominator is constant, or if
// the nominator is zero // the nominator is zero
if (op.getCode() == ogp::DIVIDE if (op.getCode() == ogp::code_t::DIVIDE
&& (op.getOp1() == ogp::OperationTree::zero && (op.getOp1() == ogp::OperationTree::zero
|| model.is_constant_term(op.getOp2()))) || model.is_constant_term(op.getOp2())))
return false; return false;
@ -792,23 +792,23 @@ DynareSPModel::DynareSPModel(const char **endo, int num_endo,
} }
void void
ModelSSWriter::write_der0(FILE *fd) ModelSSWriter::write_der0(std::ostream &os)
{ {
write_der0_preamble(fd); write_der0_preamble(os);
write_atom_assignment(fd); write_atom_assignment(os);
stop_set.clear(); stop_set.clear();
for (int fi = 0; fi < model.eqs.nformulas(); fi++) for (int fi = 0; fi < model.eqs.nformulas(); fi++)
otree.print_operation_tree(model.eqs.formula(fi), fd, *this); otree.print_operation_tree(model.eqs.formula(fi), os, *this);
write_der0_assignment(fd); write_der0_assignment(os);
} }
void void
ModelSSWriter::write_der1(FILE *fd) ModelSSWriter::write_der1(std::ostream &os)
{ {
write_der1_preamble(fd); write_der1_preamble(os);
write_atom_assignment(fd); write_atom_assignment(os);
stop_set.clear(); stop_set.clear();
@ -821,11 +821,11 @@ ModelSSWriter::write_der1(FILE *fd)
{ {
int t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, j)); int t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, j));
if (t > 0) if (t > 0)
otree.print_operation_tree(t, fd, *this); otree.print_operation_tree(t, os, *this);
} }
} }
write_der1_assignment(fd); write_der1_assignment(os);
} }
MatlabSSWriter::MatlabSSWriter(const DynareModel &dm, const char *idd) MatlabSSWriter::MatlabSSWriter(const DynareModel &dm, const char *idd)
@ -835,115 +835,102 @@ MatlabSSWriter::MatlabSSWriter(const DynareModel &dm, const char *idd)
} }
void void
MatlabSSWriter::write_der0_preamble(FILE *fd) const MatlabSSWriter::write_der0_preamble(std::ostream &os) const
{ {
fprintf(fd, os << "% Usage:\n"
"%% Usage:\n" << "% out = " << id << "_f(params, y)\n"
"%% out = %s_f(params, y)\n" << "% where\n"
"%% where\n" << "% out is a (" << model.getAtoms().ny() << ",1) column vector of the residuals\n"
"%% out is a (%d,1) column vector of the residuals\n" << "% of the static system\n";
"%% of the static system\n", write_common1_preamble(os);
id, model.getAtoms().ny()); os << "function out = " << id << "_f(params, y)\n";
write_common1_preamble(fd); write_common2_preamble(os);
fprintf(fd,
"function out = %s_f(params, y)\n", id);
write_common2_preamble(fd);
} }
void void
MatlabSSWriter::write_der1_preamble(FILE *fd) const MatlabSSWriter::write_der1_preamble(std::ostream &os) const
{ {
fprintf(fd, os << "% Usage:\n"
"%% Usage:\n" << "% out = " << id << "_ff(params, y)\n"
"%% out = %s_ff(params, y)\n" << "% where\n"
"%% where\n" << "% out is a (" << model.getAtoms().ny() << "," << model.getAtoms().ny() << ") matrix of the first order\n"
"%% out is a (%d,%d) matrix of the first order\n" << "% derivatives of the static system residuals\n"
"%% derivatives of the static system residuals\n" << "% columns correspond to endo variables in\n"
"%% columns correspond to endo variables in\n" << "% the ordering as declared\n";
"%% the ordering as declared\n", write_common1_preamble(os);
id, model.getAtoms().ny(), model.getAtoms().ny()); os << "function out = " << id << "_ff(params, y)\n";
write_common1_preamble(fd); write_common2_preamble(os);
fprintf(fd,
"function out = %s_ff(params, y)\n", id);
write_common2_preamble(fd);
} }
void void
MatlabSSWriter::write_common1_preamble(FILE *fd) const MatlabSSWriter::write_common1_preamble(std::ostream &os) const
{ {
fprintf(fd, os << "% params is a (" << model.getAtoms().np() << ",1) vector of parameter values\n"
"%% params is a (%d,1) vector of parameter values\n" << "% in the ordering as declared\n"
"%% in the ordering as declared\n" << "% y is a (" << model.getAtoms().ny() << ",1) vector of endogenous variables\n"
"%% y is a (%d,1) vector of endogenous variables\n" << "% in the ordering as declared\n"
"%% in the ordering as declared\n" << "%\n"
"%%\n" << "% Created by Dynare++ v. " << DYNVERSION << "\n";
"%% Created by Dynare++ v. %s\n", model.getAtoms().np(),
model.getAtoms().ny(), DYNVERSION);
// write ordering of parameters // write ordering of parameters
fprintf(fd, "\n%% params ordering\n%% =====================\n"); os << "\n% params ordering\n% =====================\n";
for (auto parname : model.getAtoms().get_params()) for (auto parname : model.getAtoms().get_params())
{ os << "% " << parname << "\n";
fprintf(fd, "%% %s\n", parname);
}
// write endogenous variables // write endogenous variables
fprintf(fd, "%%\n%% y ordering\n%% =====================\n"); os << "%\n% y ordering\n% =====================\n";
for (auto endoname : model.getAtoms().get_endovars()) for (auto endoname : model.getAtoms().get_endovars())
{ os << "% " << endoname << "\n";
fprintf(fd, "%% %s\n", endoname); os << "\n";
}
fprintf(fd, "\n");
} }
void void
MatlabSSWriter::write_common2_preamble(FILE *fd) const MatlabSSWriter::write_common2_preamble(std::ostream &os) const
{ {
fprintf(fd, "if size(y) ~= [%d,1]\n\terror('Wrong size of y, must be [%d,1]');\nend\n", os << "if size(y) ~= [" << model.getAtoms().ny() << ",1]\n"
model.getAtoms().ny(), model.getAtoms().ny()); << "\terror('Wrong size of y, must be [" << model.getAtoms().ny() << ",1]');\nend\n"
fprintf(fd, "if size(params) ~= [%d,1]\n\terror('Wrong size of params, must be [%d,1]');\nend\n\n", << "if size(params) ~= [" << model.getAtoms().np() << ",1]\n"
model.getAtoms().np(), model.getAtoms().np()); << "\terror('Wrong size of params, must be [" << model.getAtoms().np() << ",1]');\nend\n\n";
} }
void void
MatlabSSWriter::write_atom_assignment(FILE *fd) const MatlabSSWriter::write_atom_assignment(std::ostream &os) const
{ {
// write OperationTree::num_constants // write OperationTree::num_constants
fprintf(fd, "%% hardwired constants\n"); os << "% hardwired constants\n";
ogp::EvalTree etree(model.getParser().getTree(), ogp::OperationTree::num_constants-1); ogp::EvalTree etree(model.getParser().getTree(), ogp::OperationTree::num_constants-1);
for (int i = 0; i < ogp::OperationTree::num_constants; i++) for (int i = 0; i < ogp::OperationTree::num_constants; i++)
{ {
format_nulary(i, fd); format_nulary(i, os);
double g = etree.eval(i); double g = etree.eval(i);
if (std::isnan(g)) if (std::isnan(g))
fprintf(fd, " = NaN;\n"); os << " = NaN;\n";
else else
fprintf(fd, " = %12.8g;\n", etree.eval(i)); os << " = " << std::defaultfloat << std::setprecision(8) << etree.eval(i) << ";\n";
} }
// write numerical constants // write numerical constants
fprintf(fd, "%% numerical constants\n"); os << "% numerical constants\n";
const ogp::Constants::Tconstantmap &cmap = model.getAtoms().get_constantmap(); const ogp::Constants::Tconstantmap &cmap = model.getAtoms().get_constantmap();
for (auto it : cmap) for (auto it : cmap)
{ {
format_nulary(it.first, fd); format_nulary(it.first, os);
fprintf(fd, " = %12.8g;\n", it.second); os << " = " << std::defaultfloat << std::setprecision(8) << it.second << ";\n";
} }
// write parameters // write parameters
fprintf(fd, "%% parameter values\n"); os << "% parameter values\n";
for (unsigned int ip = 0; ip < model.getAtoms().get_params().size(); ip++) for (unsigned int ip = 0; ip < model.getAtoms().get_params().size(); ip++)
{ {
const char *parname = model.getAtoms().get_params()[ip]; const char *parname = model.getAtoms().get_params()[ip];
int t = model.getAtoms().index(parname, 0); int t = model.getAtoms().index(parname, 0);
if (t == -1) if (t == -1)
{ os << "% " << parname << " not used in the model\n";
fprintf(fd, "%% %s not used in the model\n", parname);
}
else else
{ {
format_nulary(t, fd); format_nulary(t, os);
fprintf(fd, " = params(%d); %% %s\n", ip+1, parname); os << " = params(" << ip+1 << "); % " << parname << "\n";
} }
} }
// write exogenous variables // write exogenous variables
fprintf(fd, "%% exogenous variables to zeros\n"); os << "% exogenous variables to zeros\n";
for (unsigned int ie = 0; ie < model.getAtoms().get_exovars().size(); ie++) for (unsigned int ie = 0; ie < model.getAtoms().get_exovars().size(); ie++)
{ {
const char *exoname = model.getAtoms().get_exovars()[ie]; const char *exoname = model.getAtoms().get_exovars()[ie];
@ -952,8 +939,8 @@ MatlabSSWriter::write_atom_assignment(FILE *fd) const
const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(exoname); const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(exoname);
for (auto it : lmap) for (auto it : lmap)
{ {
format_nulary(it.second, fd); format_nulary(it.second, os);
fprintf(fd, " = 0.0; %% %s\n", exoname); os << " = 0.0; % " << exoname << "\n";
} }
} }
catch (const ogu::Exception &e) catch (const ogu::Exception &e)
@ -962,43 +949,43 @@ MatlabSSWriter::write_atom_assignment(FILE *fd) const
} }
} }
// write endogenous variables // write endogenous variables
fprintf(fd, "%% endogenous variables to y\n"); os << "% endogenous variables to y\n";
for (unsigned int ie = 0; ie < model.getAtoms().get_endovars().size(); ie++) for (unsigned int ie = 0; ie < model.getAtoms().get_endovars().size(); ie++)
{ {
const char *endoname = model.getAtoms().get_endovars()[ie]; const char *endoname = model.getAtoms().get_endovars()[ie];
const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(endoname); const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(endoname);
for (auto it : lmap) for (auto it : lmap)
{ {
format_nulary(it.second, fd); format_nulary(it.second, os);
fprintf(fd, " = y(%d); %% %s\n", ie+1, endoname); os << " = y(" << ie+1 << "); % " << endoname << "\n";
} }
} }
fprintf(fd, "\n"); os << "\n";
} }
void void
MatlabSSWriter::write_der0_assignment(FILE *fd) const MatlabSSWriter::write_der0_assignment(std::ostream &os) const
{ {
// initialize out variable // initialize out variable
fprintf(fd, "%% setting the output variable\n"); os << "% setting the output variable\n"
fprintf(fd, "out = zeros(%d, 1);\n", model.getParser().nformulas()); << "out = zeros(" << model.getParser().nformulas() << ", 1);\n";
// fill out with the terms // fill out with the terms
for (int i = 0; i < model.getParser().nformulas(); i++) for (int i = 0; i < model.getParser().nformulas(); i++)
{ {
fprintf(fd, "out(%d) = ", i+1); os << "out(" << i+1 << ") = ";
format_term(model.getParser().formula(i), fd); format_term(model.getParser().formula(i), os);
fprintf(fd, ";\n"); os << ";\n";
} }
} }
void void
MatlabSSWriter::write_der1_assignment(FILE *fd) const MatlabSSWriter::write_der1_assignment(std::ostream &os) const
{ {
// initialize out variable // initialize out variable
fprintf(fd, "%% setting the output variable\n"); os << "% setting the output variable\n";
fprintf(fd, "out = zeros(%d, %d);\n", model.getParser().nformulas(), model.getAtoms().ny()); os << "out = zeros(" << model.getParser().nformulas() << ", " << model.getAtoms().ny() << ");\n";
// fill out with the terms // fill out with the terms
const vector<int> &variables = model.getAtoms().variables(); const vector<int> &variables = model.getAtoms().variables();
@ -1014,48 +1001,48 @@ MatlabSSWriter::write_der1_assignment(FILE *fd) const
int t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, j)); int t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, j));
if (t != ogp::OperationTree::zero) if (t != ogp::OperationTree::zero)
{ {
fprintf(fd, "out(%d,%d) = out(%d,%d) + ", i+1, yi+1, i+1, yi+1); os << "out(" << i+1 << "," << yi+1 << ") = out("<< i+1 << "," << yi+1 << ") + ";
format_term(t, fd); format_term(t, os);
fprintf(fd, "; %% %s(%d)\n", name, model.getAtoms().lead(tvar)); os << "; % " << name << "(" << model.getAtoms().lead(tvar) << ")\n";
} }
} }
} }
} }
void void
MatlabSSWriter::format_term(int t, FILE *fd) const MatlabSSWriter::format_term(int t, std::ostream &os) const
{ {
fprintf(fd, "t%d", t); os << 't' << t;
} }
void void
MatlabSSWriter::format_nulary(int t, FILE *fd) const MatlabSSWriter::format_nulary(int t, std::ostream &os) const
{ {
fprintf(fd, "a%d", t); os << 'a' << t;
} }
void void
DebugOperationFormatter::format_nulary(int t, FILE *fd) const DebugOperationFormatter::format_nulary(int t, std::ostream &os) const
{ {
const DynareDynamicAtoms &a = model.getAtoms(); const DynareDynamicAtoms &a = model.getAtoms();
if (t == ogp::OperationTree::zero) if (t == ogp::OperationTree::zero)
fprintf(fd, "0"); os << '0';
else if (t == ogp::OperationTree::one) else if (t == ogp::OperationTree::one)
fprintf(fd, "1"); os << '1';
else if (t == ogp::OperationTree::nan) else if (t == ogp::OperationTree::nan)
fprintf(fd, "NaN"); os << "NaN";
else if (t == ogp::OperationTree::two_over_pi) else if (t == ogp::OperationTree::two_over_pi)
fprintf(fd, "2/sqrt(PI)"); os << "2/sqrt(PI)";
else if (a.is_constant(t)) else if (a.is_constant(t))
fprintf(fd, "%g", a.get_constant_value(t)); os << a.get_constant_value(t);
else else
{ {
int ll = a.lead(t); int ll = a.lead(t);
const char *name = a.name(t); std::string name{a.name(t)};
if (ll == 0) if (ll == 0)
fprintf(fd, "%s", name); os << name;
else else
fprintf(fd, "%s(%d)", name, ll); os << name << '(' << ll << ')';
} }
} }

View File

@ -14,6 +14,7 @@
#include <map> #include <map>
#include <unordered_set> #include <unordered_set>
#include <ostream>
namespace ogdyn namespace ogdyn
{ {
@ -405,18 +406,18 @@ namespace ogdyn
* virtual methods for writing a preamble, then assignment of * virtual methods for writing a preamble, then assignment of
* atoms, and then assignment for resulting object. These are * atoms, and then assignment for resulting object. These are
* language dependent and are implemented in the subclass. */ * language dependent and are implemented in the subclass. */
void write_der0(FILE *fd); void write_der0(std::ostream &os);
/** This writes the evaluation of the first order derivative of /** This writes the evaluation of the first order derivative of
the system. It calls pure virtual methods for writing a the system. It calls pure virtual methods for writing a
preamble, assignment, and assignemnt of the resulting preamble, assignment, and assignemnt of the resulting
objects. */ objects. */
void write_der1(FILE *fd); void write_der1(std::ostream &os);
protected: protected:
virtual void write_der0_preamble(FILE *fd) const = 0; virtual void write_der0_preamble(std::ostream &os) const = 0;
virtual void write_der1_preamble(FILE *fd) const = 0; virtual void write_der1_preamble(std::ostream &os) const = 0;
virtual void write_atom_assignment(FILE *fd) const = 0; virtual void write_atom_assignment(std::ostream &os) const = 0;
virtual void write_der0_assignment(FILE *fd) const = 0; virtual void write_der0_assignment(std::ostream &os) const = 0;
virtual void write_der1_assignment(FILE *fd) const = 0; virtual void write_der1_assignment(std::ostream &os) const = 0;
}; };
class MatlabSSWriter : public ModelSSWriter class MatlabSSWriter : public ModelSSWriter
@ -432,24 +433,24 @@ namespace ogdyn
} }
protected: protected:
// from ModelSSWriter // from ModelSSWriter
void write_der0_preamble(FILE *fd) const override; void write_der0_preamble(std::ostream &os) const override;
void write_der1_preamble(FILE *fd) const override; void write_der1_preamble(std::ostream &os) const override;
/** This writes atom assignments. We have four kinds of atoms /** This writes atom assignments. We have four kinds of atoms
* set here: endogenous vars coming from one parameter, * set here: endogenous vars coming from one parameter,
* parameter values given by the second parameter, constants, * parameter values given by the second parameter, constants,
* and the OperationTree::num_constants hardwired constants in * and the OperationTree::num_constants hardwired constants in
* ogp::OperationTree. */ * ogp::OperationTree. */
void write_atom_assignment(FILE *fd) const override; void write_atom_assignment(std::ostream &os) const override;
void write_der0_assignment(FILE *fd) const override; void write_der0_assignment(std::ostream &os) const override;
void write_der1_assignment(FILE *fd) const override; void write_der1_assignment(std::ostream &os) const override;
/** This prints t10 for t=10. */ /** This prints t10 for t=10. */
void format_term(int t, FILE *fd) const override; void format_term(int t, std::ostream &os) const override;
/** This prints a10 for t=10. The atoms a10 are supposed to be /** This prints a10 for t=10. The atoms a10 are supposed to be
* set by write_atom_assignments(). */ * set by write_atom_assignments(). */
void format_nulary(int t, FILE *fd) const override; void format_nulary(int t, std::ostream &os) const override;
private: private:
void write_common1_preamble(FILE *fd) const; void write_common1_preamble(std::ostream &os) const;
void write_common2_preamble(FILE *fd) const; void write_common2_preamble(std::ostream &os) const;
}; };
/** This class implements OperationFormatter for debugging /** This class implements OperationFormatter for debugging
@ -465,7 +466,7 @@ namespace ogdyn
model(m) model(m)
{ {
} }
void format_nulary(int t, FILE *fd) const override; void format_nulary(int t, std::ostream &os) const override;
}; };
}; };

View File

@ -63,7 +63,7 @@ ForwSubstBuilder::substitute_for_term(int t, int i, int j)
info.num_aux_variables++; info.num_aux_variables++;
const char *ss = model.atoms.get_name_storage().query(name); const char *ss = model.atoms.get_name_storage().query(name);
int auxt = model.eqs.add_nulary(name); int auxt = model.eqs.add_nulary(name);
model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, auxt, lagt)); model.eqs.add_formula(model.eqs.add_binary(ogp::code_t::MINUS, auxt, lagt));
aux_map.insert(Tsubstmap::value_type(ss, lagt)); aux_map.insert(Tsubstmap::value_type(ss, lagt));
// now add variables and equations // now add variables and equations
// AUXLD_*_*_2 = AUXLD_*_*_1(+1) through // AUXLD_*_*_2 = AUXLD_*_*_1(+1) through
@ -80,7 +80,7 @@ ForwSubstBuilder::substitute_for_term(int t, int i, int j)
ss = model.atoms.get_name_storage().query(name); ss = model.atoms.get_name_storage().query(name);
auxt = model.eqs.add_nulary(name); auxt = model.eqs.add_nulary(name);
// add AUXLD_*_*_{ll+1} = AUXLD_*_*_{ll}(+1) // add AUXLD_*_*_{ll+1} = AUXLD_*_*_{ll}(+1)
model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, auxt, lastauxt_lead)); model.eqs.add_formula(model.eqs.add_binary(ogp::code_t::MINUS, auxt, lastauxt_lead));
// add substitution to the map; todo: this // add substitution to the map; todo: this
// works well because in the context where // works well because in the context where
// aux_map is used the timing doesn't matter, // aux_map is used the timing doesn't matter,

View File

@ -11,6 +11,8 @@
#include "../kord/global_check.hh" #include "../kord/global_check.hh"
#include "../kord/approximation.hh" #include "../kord/approximation.hh"
#include <fstream>
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
@ -51,28 +53,29 @@ main(int argc, char **argv)
irf_list_ind = ((const DynareNameList &) dynare.getExogNames()).selectIndices(params.irf_list); irf_list_ind = ((const DynareNameList &) dynare.getExogNames()).selectIndices(params.irf_list);
// write matlab files // write matlab files
FILE *mfd;
std::string mfile1(params.basename); std::string mfile1(params.basename);
mfile1 += "_f.m"; mfile1 += "_f.m";
if (nullptr == (mfd = fopen(mfile1.c_str(), "w"))) 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()); fprintf(stderr, "Couldn't open %s for writing.\n", mfile1.c_str());
exit(1); exit(1);
} }
ogdyn::MatlabSSWriter writer0(dynare.getModel(), params.basename.c_str()); ogdyn::MatlabSSWriter writer0(dynare.getModel(), params.basename.c_str());
writer0.write_der0(mfd); writer0.write_der0(mfd);
fclose(mfd); mfd.close();
std::string mfile2(params.basename); std::string mfile2(params.basename);
mfile2 += "_ff.m"; mfile2 += "_ff.m";
if (nullptr == (mfd = fopen(mfile2.c_str(), "w"))) mfd.open(mfile2, std::ios::out | std::ios::trunc);
if (mfd.fail())
{ {
fprintf(stderr, "Couldn't open %s for writing.\n", mfile2.c_str()); fprintf(stderr, "Couldn't open %s for writing.\n", mfile2.c_str());
exit(1); exit(1);
} }
ogdyn::MatlabSSWriter writer1(dynare.getModel(), params.basename.c_str()); ogdyn::MatlabSSWriter writer1(dynare.getModel(), params.basename.c_str());
writer1.write_der1(mfd); writer1.write_der1(mfd);
fclose(mfd); mfd.close();
// open mat file // open mat file
std::string matfile(params.basename); std::string matfile(params.basename);
@ -206,7 +209,7 @@ main(int argc, char **argv)
} }
catch (const ogp::ParserException &e) catch (const ogp::ParserException &e)
{ {
printf("Caught parser exception: %s\n", e.message()); std::cout << "Caught parser exception: " << e.message() << std::endl;
return 255; return 255;
} }

View File

@ -188,11 +188,11 @@ PlannerBuilder::beta_multiply_b()
{ {
int beta_pow = ogp::OperationTree::one; int beta_pow = ogp::OperationTree::one;
for (int ll = 0; ll >= minlag; ll--, for (int ll = 0; ll >= minlag; ll--,
beta_pow = model.eqs.add_binary(ogp::TIMES, beta_pow, tbeta)) beta_pow = model.eqs.add_binary(ogp::code_t::TIMES, beta_pow, tbeta))
for (int yi = 0; yi < diff_b.nrows(); yi++) for (int yi = 0; yi < diff_b.nrows(); yi++)
if (diff_b(yi, ll-minlag) != ogp::OperationTree::zero) if (diff_b(yi, ll-minlag) != ogp::OperationTree::zero)
diff_b(yi, ll-minlag) diff_b(yi, ll-minlag)
= model.eqs.add_binary(ogp::TIMES, beta_pow, diff_b(yi, ll-minlag)); = model.eqs.add_binary(ogp::code_t::TIMES, beta_pow, diff_b(yi, ll-minlag));
} }
void void
@ -200,21 +200,21 @@ PlannerBuilder::beta_multiply_f()
{ {
int beta_pow = ogp::OperationTree::one; int beta_pow = ogp::OperationTree::one;
for (int ll = 0; ll <= maxlead; ll++, for (int ll = 0; ll <= maxlead; ll++,
beta_pow = model.eqs.add_binary(ogp::DIVIDE, beta_pow, tbeta)) beta_pow = model.eqs.add_binary(ogp::code_t::DIVIDE, beta_pow, tbeta))
for (int yi = 0; yi < diff_f.dim1(); yi++) for (int yi = 0; yi < diff_f.dim1(); yi++)
for (int fi = 0; fi < diff_f.dim2(); fi++) for (int fi = 0; fi < diff_f.dim2(); fi++)
if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero) if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero)
diff_f(yi, fi, ll-minlag) diff_f(yi, fi, ll-minlag)
= model.eqs.add_binary(ogp::TIMES, beta_pow, diff_f(yi, fi, ll-minlag)); = model.eqs.add_binary(ogp::code_t::TIMES, beta_pow, diff_f(yi, fi, ll-minlag));
beta_pow = ogp::OperationTree::one; beta_pow = ogp::OperationTree::one;
for (int ll = 0; ll >= minlag; ll--, for (int ll = 0; ll >= minlag; ll--,
beta_pow = model.eqs.add_binary(ogp::TIMES, beta_pow, tbeta)) beta_pow = model.eqs.add_binary(ogp::code_t::TIMES, beta_pow, tbeta))
for (int yi = 0; yi < diff_f.dim1(); yi++) for (int yi = 0; yi < diff_f.dim1(); yi++)
for (int fi = 0; fi < diff_f.dim2(); fi++) for (int fi = 0; fi < diff_f.dim2(); fi++)
if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero) if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero)
diff_f(yi, fi, ll-minlag) diff_f(yi, fi, ll-minlag)
= model.eqs.add_binary(ogp::TIMES, beta_pow, diff_f(yi, fi, ll-minlag)); = model.eqs.add_binary(ogp::code_t::TIMES, beta_pow, diff_f(yi, fi, ll-minlag));
} }
void void
@ -271,7 +271,7 @@ PlannerBuilder::lagrange_mult_f()
sprintf(mult_name, "MULT%d(%d)", fset[fi], -ll); sprintf(mult_name, "MULT%d(%d)", fset[fi], -ll);
int tm = model.eqs.add_nulary(mult_name); int tm = model.eqs.add_nulary(mult_name);
diff_f(yi, fi, ll-minlag) diff_f(yi, fi, ll-minlag)
= model.eqs.add_binary(ogp::TIMES, tm, diff_f(yi, fi, ll-minlag)); = model.eqs.add_binary(ogp::code_t::TIMES, tm, diff_f(yi, fi, ll-minlag));
} }
} }
@ -283,10 +283,10 @@ PlannerBuilder::form_equations()
{ {
int eq = ogp::OperationTree::zero; int eq = ogp::OperationTree::zero;
for (int ll = minlag; ll <= 0; ll++) for (int ll = minlag; ll <= 0; ll++)
eq = model.eqs.add_binary(ogp::PLUS, eq, diff_b(yi, ll-minlag)); eq = model.eqs.add_binary(ogp::code_t::PLUS, eq, diff_b(yi, ll-minlag));
for (int fi = 0; fi < diff_f.dim2(); fi++) for (int fi = 0; fi < diff_f.dim2(); fi++)
for (int ll = minlag; ll <= maxlead; ll++) for (int ll = minlag; ll <= maxlead; ll++)
eq = model.eqs.add_binary(ogp::PLUS, eq, diff_f(yi, fi, ll-minlag)); eq = model.eqs.add_binary(ogp::code_t::PLUS, eq, diff_f(yi, fi, ll-minlag));
model.eqs.add_formula(eq); model.eqs.add_formula(eq);
} }
@ -295,7 +295,7 @@ PlannerBuilder::form_equations()
it != aux_map.end(); ++it) it != aux_map.end(); ++it)
{ {
int t = model.atoms.index((*it).first, 0); int t = model.atoms.index((*it).first, 0);
model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, t, (*it).second)); model.eqs.add_formula(model.eqs.add_binary(ogp::code_t::MINUS, t, (*it).second));
} }
} }