Dynare++ parser: various modernizations
parent
ee891948e0
commit
3915299334
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <limits>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
|
@ -19,7 +20,7 @@ AtomAssignings::AtomAssignings(const AtomAssignings &aa, ogp::StaticAtoms &a)
|
|||
{
|
||||
// fill the 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
|
||||
|
@ -36,16 +37,15 @@ extern location_type asgn_lloc;
|
|||
void
|
||||
AtomAssignings::parse(int length, const char *stream)
|
||||
{
|
||||
auto *buffer = new char[length+2];
|
||||
strncpy(buffer, stream, length);
|
||||
auto buffer = std::make_unique<char[]>(length+2);
|
||||
std::copy_n(stream, length, buffer.get());
|
||||
buffer[length] = '\0';
|
||||
buffer[length+1] = '\0';
|
||||
asgn_lloc.off = 0;
|
||||
asgn_lloc.ll = 0;
|
||||
void *p = asgn__scan_buffer(buffer, (unsigned int) length+2);
|
||||
void *p = asgn__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
|
||||
aparser = this;
|
||||
asgn_parse();
|
||||
delete [] buffer;
|
||||
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
|
||||
const char *ss = left_names.insert(name);
|
||||
lname2expr.insert(Tvarintmap::value_type(ss, order.size()-1));
|
||||
lname2expr.emplace(ss, order.size()-1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -173,7 +173,7 @@ AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm)
|
|||
{
|
||||
const char *newname = itt.first;
|
||||
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
|
||||
AtomAssignings::print() const
|
||||
{
|
||||
printf("Atom Assignings\nExpressions:\n");
|
||||
std::cout << "Atom Assignings\nExpressions:\n";
|
||||
expr.print();
|
||||
printf("Left names:\n");
|
||||
std::cout << "Left names:\n";
|
||||
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
|
||||
|
@ -207,7 +207,7 @@ AtomAsgnEvaluator::setValues(EvalTree &et) const
|
|||
if (it == user_values.end())
|
||||
et.set_nulary(t, nan);
|
||||
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);
|
||||
if (it == user_values.end())
|
||||
user_values.insert(Tusrvalmap::value_type(t, val));
|
||||
user_values.emplace(t, val);
|
||||
else
|
||||
(*it).second = val;
|
||||
it->second = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,5 +244,5 @@ AtomAsgnEvaluator::get_value(const char *name) const
|
|||
if (it == aa.lname2expr.end())
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
else
|
||||
return operator[]((*it).second);
|
||||
return operator[](it->second);
|
||||
}
|
||||
|
|
|
@ -51,8 +51,7 @@ namespace ogp
|
|||
/** Make a copy with provided reference to (posibly different)
|
||||
* static atoms. */
|
||||
AtomAssignings(const AtomAssignings &aa, StaticAtoms &a);
|
||||
virtual ~AtomAssignings()
|
||||
= default;
|
||||
virtual ~AtomAssignings() = default;
|
||||
/** Parse the assignments from the given string. */
|
||||
void parse(int length, const char *stream);
|
||||
/** Process a syntax error from bison. */
|
||||
|
@ -97,8 +96,7 @@ namespace ogp
|
|||
std::vector<double>(a.expr.nformulas()), aa(a)
|
||||
{
|
||||
}
|
||||
~AtomAsgnEvaluator()
|
||||
override = default;
|
||||
~AtomAsgnEvaluator() override = default;
|
||||
/** This sets all initial values to NaNs, all constants and
|
||||
* all values set by user by call set_value. This is called by
|
||||
* FormulaEvaluator::eval() method, which is called by eval()
|
||||
|
|
|
@ -15,16 +15,16 @@ AtomSubstitutions::AtomSubstitutions(const AtomSubstitutions &as, const FineAtom
|
|||
|
||||
// fill new2old
|
||||
for (const auto & it : as.new2old)
|
||||
new2old.insert(Tshiftmap::value_type(ns.query(it.first),
|
||||
Tshiftname(ns.query(it.second.first),
|
||||
it.second.second)));
|
||||
new2old.emplace(ns.query(it.first),
|
||||
Tshiftname(ns.query(it.second.first),
|
||||
it.second.second));
|
||||
// fill old2new
|
||||
for (const auto & it : as.old2new)
|
||||
{
|
||||
Tshiftnameset sset;
|
||||
for (const auto & itt : it.second)
|
||||
sset.insert(Tshiftname(ns.query(itt.first), itt.second));
|
||||
old2new.insert(Toldnamemap::value_type(ns.query(it.first), sset));
|
||||
sset.emplace(ns.query(itt.first), itt.second);
|
||||
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
|
||||
newname = new_atoms.get_name_storage().query(newname);
|
||||
oldname = new_atoms.get_name_storage().query(oldname);
|
||||
if (newname == nullptr || oldname == nullptr)
|
||||
if (!newname || !oldname)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Bad newname or oldname in AtomSubstitutions::add_substitution");
|
||||
|
||||
// insert to new2old map
|
||||
new2old.insert(Tshiftmap::value_type(newname, Tshiftname(oldname, tshift)));
|
||||
new2old.emplace(newname, Tshiftname(oldname, tshift));
|
||||
// insert to old2new map
|
||||
auto it = old2new.find(oldname);
|
||||
if (it != old2new.end())
|
||||
(*it).second.insert(Tshiftname(newname, -tshift));
|
||||
it->second.emplace(newname, -tshift);
|
||||
else
|
||||
{
|
||||
Tshiftnameset snset;
|
||||
snset.insert(Tshiftname(newname, -tshift));
|
||||
old2new.insert(Toldnamemap::value_type(oldname, snset));
|
||||
snset.emplace(newname, -tshift);
|
||||
old2new.emplace(oldname, snset);
|
||||
}
|
||||
|
||||
// put to info
|
||||
|
@ -68,7 +68,7 @@ AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot)
|
|||
// add all new names derived from the old name
|
||||
Toldnamemap::const_iterator it = old2new.find(oname);
|
||||
if (it != old2new.end())
|
||||
for (const auto & itt : (*it).second)
|
||||
for (const auto & itt : it->second)
|
||||
na_ext.push_back(itt.first);
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ AtomSubstitutions::get_new4old(const char *oldname, int tshift) const
|
|||
auto it = old2new.find(oldname);
|
||||
if (it != old2new.end())
|
||||
{
|
||||
const Tshiftnameset &sset = (*it).second;
|
||||
const Tshiftnameset &sset = it->second;
|
||||
for (const auto & itt : sset)
|
||||
if (itt.second == -tshift)
|
||||
return itt.first;
|
||||
|
@ -93,15 +93,14 @@ AtomSubstitutions::get_new4old(const char *oldname, int tshift) const
|
|||
void
|
||||
AtomSubstitutions::print() const
|
||||
{
|
||||
printf("Atom Substitutions:\nOld ==> New:\n");
|
||||
std::cout << u8"Atom Substitutions:\nOld ⇒ New:\n";
|
||||
for (const auto & it : old2new)
|
||||
for (auto itt = it.second.begin();
|
||||
itt != it.second.end(); ++itt)
|
||||
printf(" %s ==> [%s, %d]\n", it.first, (*itt).first, (*itt).second);
|
||||
for (const auto &itt : it.second)
|
||||
std::cout << " " << it.first << u8" ⇒ [" << itt.first << ", " << itt.second << "]\n";
|
||||
|
||||
printf("Old <== New:\n");
|
||||
std::cout << u8"Old ⇐ New:\n";
|
||||
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
|
||||
|
@ -113,19 +112,19 @@ SAtoms::substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as)
|
|||
endovarspan(mlead, mlag);
|
||||
|
||||
// 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);
|
||||
// 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);
|
||||
|
||||
exovarspan(mlead, mlag);
|
||||
|
||||
// substitute all lagged exo
|
||||
while (nullptr != (name = findExoWithLeadInInterval(mlag, -1)))
|
||||
while (name = findExoWithLeadInInterval(mlag, -1))
|
||||
makeAuxVariables(name, -1, -1, mlag, fp, as);
|
||||
// substitute all leaded exo
|
||||
while (nullptr != (name = findExoWithLeadInInterval(1, mlead)))
|
||||
while (name = findExoWithLeadInInterval(1, mlead))
|
||||
makeAuxVariables(name, 1, 1, mlead, fp, as);
|
||||
|
||||
// notify that substitution have been finished
|
||||
|
@ -141,16 +140,16 @@ SAtoms::substituteAllLagsAndExo1Leads(FormulaParser &fp, AtomSubstitutions &as)
|
|||
endovarspan(mlead, mlag);
|
||||
|
||||
// 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);
|
||||
|
||||
exovarspan(mlead, mlag);
|
||||
|
||||
// substitute all lagged exo
|
||||
while (nullptr != (name = findExoWithLeadInInterval(mlag, -1)))
|
||||
while (name = findExoWithLeadInInterval(mlag, -1))
|
||||
makeAuxVariables(name, -1, -1, mlag, fp, as);
|
||||
// substitute all leaded exo by 1
|
||||
while (nullptr != (name = findExoWithLeadInInterval(1, 1)))
|
||||
while (name = findExoWithLeadInInterval(1, 1))
|
||||
makeAuxVariables(name, 1, 1, 1, fp, as);
|
||||
|
||||
// notify that substitution have been finished
|
||||
|
@ -181,8 +180,7 @@ void
|
|||
SAtoms::attemptAuxName(const char *str, int ll, string &out) const
|
||||
{
|
||||
char c = (ll >= 0) ? ((ll == 0) ? 'e' : 'p') : 'm';
|
||||
char absll[100];
|
||||
sprintf(absll, "%d", std::abs(ll));
|
||||
string absll = std::to_string(std::abs(ll));
|
||||
int iter = 1;
|
||||
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;
|
||||
|
||||
char tmp[500];
|
||||
|
||||
// recover tree index of a previous atom, i.e. set tprev to a tree
|
||||
// index of atom "a(-2)"
|
||||
int tprev = index(name, start-step);
|
||||
if (tprev == -1)
|
||||
{
|
||||
sprintf(tmp, "%s(%d)", name, start-step);
|
||||
tprev = fp.add_nulary(tmp);
|
||||
string tmp = string{name} + '(' + std::to_string(start-step) + ')';
|
||||
tprev = fp.add_nulary(tmp.c_str());
|
||||
}
|
||||
|
||||
int ll = start;
|
||||
|
@ -241,19 +237,19 @@ SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead,
|
|||
const char *newname;
|
||||
string newname_str;
|
||||
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);
|
||||
newname = newname_str.c_str();
|
||||
register_uniq_endo(newname);
|
||||
newname = varnames.query(newname);
|
||||
sprintf(tmp, "%s(0)", newname);
|
||||
taux = fp.add_nulary(tmp);
|
||||
string tmp = string{newname} + "(0)";
|
||||
taux = fp.add_nulary(tmp.c_str());
|
||||
// add to substitutions
|
||||
as.add_substitution(newname, name, ll-step);
|
||||
|
||||
// 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
|
||||
{
|
||||
|
@ -273,8 +269,8 @@ SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead,
|
|||
if (t == -1)
|
||||
{
|
||||
// no "a(-3)", make t <-> a_m2(-1)
|
||||
sprintf(tmp, "%s(%d)", newname, step);
|
||||
t = fp.add_nulary(tmp);
|
||||
string tmp = string{newname} + '(' + std::to_string(step) + ')';
|
||||
t = fp.add_nulary(tmp.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -22,8 +22,7 @@ namespace ogp
|
|||
struct SubstInfo
|
||||
{
|
||||
int num_substs{0};
|
||||
SubstInfo()
|
||||
= default;
|
||||
SubstInfo() = default;
|
||||
};
|
||||
|
||||
/** 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
|
||||
* semantically same as the atoms from as. */
|
||||
AtomSubstitutions(const AtomSubstitutions &as, const FineAtoms &oa, FineAtoms &na);
|
||||
virtual ~AtomSubstitutions()
|
||||
= default;
|
||||
virtual ~AtomSubstitutions() = default;
|
||||
/** This is called during the substitution job from the
|
||||
* substitution method of the new atoms. This says that the
|
||||
* new name, say "a_m3" is a substitution of old name "a"
|
||||
|
@ -128,11 +126,8 @@ namespace ogp
|
|||
: FineAtoms()
|
||||
{
|
||||
}
|
||||
SAtoms(const SAtoms &sa)
|
||||
|
||||
= default;
|
||||
~SAtoms()
|
||||
override = default;
|
||||
SAtoms(const SAtoms &sa) = default;
|
||||
~SAtoms() override = default;
|
||||
/** This substitutes all lags and leads for all exogenous and
|
||||
* all lags and leads greater than 1 for all endogenous
|
||||
* variables. This is useful for perfect foresight problems
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
#include "parser_exception.hh"
|
||||
#include "location.hh"
|
||||
#include "csv_tab.hh"
|
||||
#include <cstring>
|
||||
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
|
@ -28,17 +30,16 @@ void
|
|||
CSVParser::csv_parse(int length, const char *str)
|
||||
{
|
||||
// allocate temporary buffer and parse
|
||||
auto *buffer = new char[length+2];
|
||||
strncpy(buffer, str, length);
|
||||
auto buffer = std::make_unique<char[]>(length+2);
|
||||
std::copy_n(str, length, buffer.get());
|
||||
buffer[length] = '\0';
|
||||
buffer[length+1] = '\0';
|
||||
csv_lloc.off = 0;
|
||||
csv_lloc.ll = 0;
|
||||
parsed_string = buffer;
|
||||
void *p = csv__scan_buffer(buffer, (unsigned int) length+2);
|
||||
parsed_string = buffer.get();
|
||||
void *p = csv__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
|
||||
csv_parser = this;
|
||||
::csv_parse();
|
||||
delete [] buffer;
|
||||
csv__destroy_buffer(p);
|
||||
parsed_string = nullptr;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ void
|
|||
NameStorage::print() const
|
||||
{
|
||||
for (auto i : name_store)
|
||||
printf("%s\n", i);
|
||||
std::cout << i << '\n';
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -69,7 +69,7 @@ Constants::import_constants(const Constants &c, OperationTree &otree, Tintintmap
|
|||
{
|
||||
int told = it.first;
|
||||
int tnew = otree.add_nulary();
|
||||
tmap.insert(Tintintmap::value_type(told, tnew));
|
||||
tmap.emplace(told, tnew);
|
||||
add_constant(tnew, it.second);
|
||||
}
|
||||
}
|
||||
|
@ -77,16 +77,15 @@ Constants::import_constants(const Constants &c, OperationTree &otree, Tintintmap
|
|||
void
|
||||
Constants::setValues(EvalTree &et) const
|
||||
{
|
||||
Tconstantmap::const_iterator it;
|
||||
for (it = cmap.begin(); it != cmap.end(); ++it)
|
||||
et.set_nulary((*it).first, (*it).second);
|
||||
for (const auto & it : cmap)
|
||||
et.set_nulary(it.first, it.second);
|
||||
}
|
||||
|
||||
void
|
||||
Constants::add_constant(int t, double val)
|
||||
{
|
||||
cmap.insert(Tconstantmap::value_type(t, val));
|
||||
cinvmap.insert(Tconstantinvmap::value_type(val, t));
|
||||
cmap.emplace(t, val);
|
||||
cinvmap.emplace(val, t);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -103,7 +102,7 @@ Constants::get_constant_value(int t) const
|
|||
{
|
||||
auto it = cmap.find(t);
|
||||
if (it != cmap.end())
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
|
@ -119,7 +118,7 @@ Constants::check(const char *str) const
|
|||
sscanf(str, "%lf", &d);
|
||||
auto it = cinvmap.find(d);
|
||||
if (it != cinvmap.end())
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
@ -127,13 +126,11 @@ Constants::check(const char *str) const
|
|||
void
|
||||
Constants::print() const
|
||||
{
|
||||
Tconstantmap::const_iterator it;
|
||||
for (it = cmap.begin(); it != cmap.end(); ++it)
|
||||
printf("$%d: %8.4g\n", (*it).first, (*it).second);
|
||||
for (const auto &it : cmap)
|
||||
printf("$%d: %8.4g\n", it.first, it.second);
|
||||
}
|
||||
|
||||
DynamicAtoms::DynamicAtoms()
|
||||
= default;
|
||||
DynamicAtoms::DynamicAtoms() = default;
|
||||
|
||||
DynamicAtoms::DynamicAtoms(const DynamicAtoms &da)
|
||||
: Constants(da),
|
||||
|
@ -142,12 +139,10 @@ DynamicAtoms::DynamicAtoms(const DynamicAtoms &da)
|
|||
{
|
||||
// copy vars
|
||||
for (const auto & var : da.vars)
|
||||
vars.insert(Tvarmap::value_type(varnames.query(var.first),
|
||||
var.second));
|
||||
vars.emplace(varnames.query(var.first), var.second);
|
||||
// copy indices
|
||||
for (auto indice : da.indices)
|
||||
indices.insert(Tindexmap::value_type(indice.first,
|
||||
varnames.query(indice.second)));
|
||||
indices.emplace(indice.first, varnames.query(indice.second));
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -169,10 +164,10 @@ DynamicAtoms::check_variable(const char *name) const
|
|||
|
||||
if (it != vars.end())
|
||||
{
|
||||
const Tlagmap &lmap = (*it).second;
|
||||
const Tlagmap &lmap = it->second;
|
||||
auto itt = lmap.find(ll);
|
||||
if (itt != lmap.end())
|
||||
return (*itt).second;
|
||||
return itt->second;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -218,19 +213,19 @@ DynamicAtoms::assign_variable(const char *varname, int ll, int t)
|
|||
auto it = vars.find(varname);
|
||||
if (it != vars.end())
|
||||
{
|
||||
Tlagmap &lmap = (*it).second;
|
||||
Tlagmap &lmap = it->second;
|
||||
if (lmap.end() != lmap.find(ll))
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Attempt to assign already allocated variable");
|
||||
lmap.insert(Tlagmap::value_type(ll, t));
|
||||
lmap.emplace(ll, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
Tlagmap lmap;
|
||||
lmap.insert(Tlagmap::value_type(ll, t));
|
||||
vars.insert(Tvarmap::value_type(varname, lmap));
|
||||
lmap.emplace(ll, t);
|
||||
vars.emplace(varname, lmap);
|
||||
}
|
||||
indices.insert(Tindexmap::value_type(t, varname));
|
||||
indices.emplace(t, varname);
|
||||
|
||||
nv++;
|
||||
if (ll < minlag)
|
||||
|
@ -245,11 +240,11 @@ DynamicAtoms::unassign_variable(const char *varname, int ll, int t)
|
|||
auto it = vars.find(varname);
|
||||
if (it != vars.end())
|
||||
{
|
||||
Tlagmap &lmap = (*it).second;
|
||||
Tlagmap &lmap = it->second;
|
||||
auto itt = lmap.find(ll);
|
||||
if (itt != lmap.end())
|
||||
{
|
||||
if ((*itt).second == t)
|
||||
if (itt->second == t)
|
||||
{
|
||||
// erase it from the lagmap; if it becomes empty,
|
||||
// erase the lagmap from varmap
|
||||
|
@ -281,18 +276,16 @@ DynamicAtoms::unassign_variable(const char *varname, int ll, int t)
|
|||
void
|
||||
DynamicAtoms::update_minmaxll()
|
||||
{
|
||||
minlag = INT_MAX;
|
||||
maxlead = INT_MIN;
|
||||
for (Tvarmap::const_iterator it = vars.begin(); it != vars.end(); ++it)
|
||||
minlag = std::numeric_limits<int>::max();
|
||||
maxlead = std::numeric_limits<int>::min();
|
||||
for (const auto &it : vars)
|
||||
{
|
||||
const Tlagmap &lmap = (*it).second;
|
||||
const Tlagmap &lmap = it.second;
|
||||
for (auto itt : lmap)
|
||||
{
|
||||
int ll = itt.first;
|
||||
if (ll < minlag)
|
||||
minlag = ll;
|
||||
if (ll > maxlead)
|
||||
maxlead = ll;
|
||||
minlag = std::min(ll, minlag);
|
||||
maxlead = std::max(ll, maxlead);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -316,11 +309,11 @@ DynamicAtoms::varspan(int t, int &mlead, int &mlag) const
|
|||
auto it = indices.find(t);
|
||||
if (indices.end() == it)
|
||||
{
|
||||
mlead = INT_MIN;
|
||||
mlag = INT_MAX;
|
||||
mlead = std::numeric_limits<int>::min();
|
||||
mlag = std::numeric_limits<int>::max();
|
||||
return;
|
||||
}
|
||||
varspan((*it).second, mlead, mlag);
|
||||
varspan(it->second, mlead, mlag);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -329,30 +322,28 @@ DynamicAtoms::varspan(const char *name, int &mlead, int &mlag) const
|
|||
auto it = vars.find(name);
|
||||
if (vars.end() == it)
|
||||
{
|
||||
mlead = INT_MIN;
|
||||
mlag = INT_MAX;
|
||||
mlead = std::numeric_limits<int>::min();
|
||||
mlag = std::numeric_limits<int>::max();
|
||||
return;
|
||||
}
|
||||
const Tlagmap &lmap = (*it).second;
|
||||
const Tlagmap &lmap = it->second;
|
||||
auto beg = lmap.begin();
|
||||
auto end = lmap.rbegin();
|
||||
mlag = (*beg).first;
|
||||
mlead = (*end).first;
|
||||
mlag = beg->first;
|
||||
mlead = end->first;
|
||||
}
|
||||
|
||||
void
|
||||
DynamicAtoms::varspan(const vector<const char *> &names, int &mlead, int &mlag) const
|
||||
{
|
||||
mlead = INT_MIN;
|
||||
mlag = INT_MAX;
|
||||
mlead = std::numeric_limits<int>::min();
|
||||
mlag = std::numeric_limits<int>::max();
|
||||
for (auto name : names)
|
||||
{
|
||||
int lag, lead;
|
||||
varspan(name, lead, lag);
|
||||
if (lead > mlead)
|
||||
mlead = lead;
|
||||
if (lag < mlag)
|
||||
mlag = lag;
|
||||
mlead = std::max(lead, mlead);
|
||||
mlag = std::min(lag, mlag);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,10 +359,10 @@ DynamicAtoms::index(const char *name, int ll) const
|
|||
auto it = vars.find(name);
|
||||
if (vars.end() != it)
|
||||
{
|
||||
const Tlagmap &lmap = (*it).second;
|
||||
const Tlagmap &lmap = it->second;
|
||||
auto itt = lmap.find(ll);
|
||||
if (lmap.end() != itt)
|
||||
return (*itt).second;
|
||||
return itt->second;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -391,7 +382,7 @@ DynamicAtoms::lagmap(const char *name) const
|
|||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
std::string("Couldn't find the name ")
|
||||
+ name + " in DynamicAtoms::lagmap");
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const char *
|
||||
|
@ -401,7 +392,7 @@ DynamicAtoms::name(int t) const
|
|||
if (indices.end() == it)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Couldn't find tree index in DynamicAtoms::name");
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -410,12 +401,12 @@ DynamicAtoms::lead(int t) const
|
|||
const char *nam = name(t);
|
||||
const Tlagmap &lmap = lagmap(nam);
|
||||
auto it = lmap.begin();
|
||||
while (it != lmap.end() && (*it).second != t)
|
||||
while (it != lmap.end() && it->second != t)
|
||||
++it;
|
||||
if (lmap.end() == it)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Couldn't find the three index in DynamicAtoms::lead");
|
||||
return (*it).first;
|
||||
return it->first;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -434,7 +425,7 @@ DynamicAtoms::print() const
|
|||
}
|
||||
printf("indices:\n");
|
||||
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
|
||||
|
@ -467,7 +458,7 @@ VarOrdering::get_pos_of(int t) const
|
|||
auto it = positions.find(t);
|
||||
if (it != positions.end())
|
||||
{
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -570,7 +561,7 @@ VarOrdering::do_general(ord_type ordering)
|
|||
if ((*ord)[j] != -1)
|
||||
{
|
||||
der_atoms.push_back((*ord)[j]);
|
||||
positions.insert(std::pair<int, int>((*ord)[j], off));
|
||||
positions.emplace((*ord)[j], off);
|
||||
}
|
||||
|
||||
// set integer constants
|
||||
|
@ -599,7 +590,7 @@ VarOrdering::do_increasing_time()
|
|||
// setup the matrix of tree indices, if there is no occurrence,
|
||||
// the index is set to -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++)
|
||||
{
|
||||
try
|
||||
|
@ -627,7 +618,7 @@ VarOrdering::do_increasing_time()
|
|||
{
|
||||
der_atoms.push_back(t);
|
||||
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;
|
||||
atoms.varspan(varname, mmlead, mmlag);
|
||||
if (mmlead == 0 && mmlag == 0)
|
||||
{
|
||||
n_stat++;
|
||||
}
|
||||
n_stat++;
|
||||
else if (mmlead <= 0 && mmlag < 0)
|
||||
{
|
||||
n_pred++;
|
||||
}
|
||||
n_pred++;
|
||||
else if (mmlead > 0 && mmlag >= 0)
|
||||
{
|
||||
n_forw++;
|
||||
}
|
||||
n_forw++;
|
||||
else if (mmlead > 0 && mmlag < 0)
|
||||
{
|
||||
n_both++;
|
||||
}
|
||||
n_both++;
|
||||
else if (mmlead < mmlag)
|
||||
{
|
||||
// variable does not occur in the tree, cound as static
|
||||
n_stat++;
|
||||
}
|
||||
// variable does not occur in the tree, cound as static
|
||||
n_stat++;
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"A wrong lag/lead of a variable in VarOrdering::do_increasing_time");
|
||||
}
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"A wrong lag/lead of a variable in VarOrdering::do_increasing_time");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -681,7 +660,7 @@ VarOrdering::print() const
|
|||
printf(" %d", der_atom);
|
||||
printf("\nmap:\n");
|
||||
for (auto position : positions)
|
||||
printf(" [%d->%d]", position.first, position.second);
|
||||
printf(u8" [%d→%d]", position.first, position.second);
|
||||
printf("\ny2outer:\n");
|
||||
for (int i : y2outer)
|
||||
printf(" %d", i);
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
#include <set>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <climits>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
namespace ogp
|
||||
{
|
||||
|
@ -45,11 +46,9 @@ namespace ogp
|
|||
* allocated or not. */
|
||||
set<const char *, ltstr> name_set;
|
||||
public:
|
||||
NameStorage()
|
||||
= default;
|
||||
NameStorage() = default;
|
||||
NameStorage(const NameStorage &stor);
|
||||
virtual
|
||||
~NameStorage();
|
||||
virtual ~NameStorage();
|
||||
/** Query for the name. If the name has been stored, it
|
||||
* returns its address, otherwise 0. */
|
||||
const char *query(const char *name) const;
|
||||
|
@ -59,7 +58,7 @@ namespace ogp
|
|||
int
|
||||
num() const
|
||||
{
|
||||
return (int) name_store.size();
|
||||
return static_cast<int>(name_store.size());
|
||||
}
|
||||
const char *
|
||||
get_name(int i) const
|
||||
|
@ -80,8 +79,7 @@ namespace ogp
|
|||
/** Map mapping a tree index of a constant to its double value. */
|
||||
Tconstantmap cmap;
|
||||
public:
|
||||
Constants()
|
||||
= default;
|
||||
Constants() = default;
|
||||
/** Copy constructor. */
|
||||
Constants(const Constants &c)
|
||||
: cmap(c.cmap), cinvmap(c.cinvmap)
|
||||
|
@ -162,15 +160,14 @@ namespace ogp
|
|||
/** Number of variables. */
|
||||
int nv{0};
|
||||
/** 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. */
|
||||
int maxlead{INT_MIN};
|
||||
int maxlead{std::numeric_limits<int>::min()};
|
||||
public:
|
||||
/** Construct empty DynamicAtoms. */
|
||||
DynamicAtoms();
|
||||
DynamicAtoms(const DynamicAtoms &da);
|
||||
~DynamicAtoms()
|
||||
override = default;
|
||||
~DynamicAtoms() override = default;
|
||||
/** Check the nulary term identified by its string
|
||||
* representation. The nulary term can be either a constant or
|
||||
* a variable. If constant, -1 is returned so that it could be
|
||||
|
@ -326,7 +323,7 @@ namespace ogp
|
|||
* follows: y(t-1), x(t-1), z(t-1), [y(t)], [x(t)], z(t),
|
||||
* x(t+1), where a bracketed expresion means non-existent by
|
||||
* occupying a space. The map thus will look as follows:
|
||||
* {5->0, 6->1, 3->2, 2->5, 3->6}. Note that nothing is mapped
|
||||
* {5→0, 6→1, 3→2, 2→5, 3→6}. Note that nothing is mapped
|
||||
* to positions 3 and 4. */
|
||||
map<int, int> positions;
|
||||
/** This maps an ordering of the list of variables in
|
||||
|
@ -358,11 +355,10 @@ namespace ogp
|
|||
VarOrdering(const VarOrdering &vo, const vector<const char *> &vnames,
|
||||
const DynamicAtoms &a);
|
||||
VarOrdering(const VarOrdering &vo) = delete;
|
||||
virtual VarOrdering *clone(const vector<const char *> &vnames,
|
||||
const DynamicAtoms &a) const = 0;
|
||||
virtual std::unique_ptr<VarOrdering> clone(const vector<const char *> &vnames,
|
||||
const DynamicAtoms &a) const = 0;
|
||||
/** Destructor does nothing here. */
|
||||
virtual ~VarOrdering()
|
||||
= default;
|
||||
virtual ~VarOrdering() = default;
|
||||
/** This is the method setting the ordering and the map. A
|
||||
* subclass must reimplement it, possibly using a
|
||||
* preimplemented ordering. This method must be called by the
|
||||
|
|
|
@ -31,12 +31,12 @@ AllvarOuterOrdering::AllvarOuterOrdering(const vector<const char *> &allvar_oute
|
|||
{
|
||||
auto it = atoms.endo_outer_map.find(allvar[i]);
|
||||
if (it != atoms.endo_outer_map.end())
|
||||
endo2all[(*it).second] = i;
|
||||
endo2all[it->second] = i;
|
||||
else
|
||||
{
|
||||
it = atoms.exo_outer_map.find(allvar[i]);
|
||||
if (it != atoms.exo_outer_map.end())
|
||||
exo2all[(*it).second] = i;
|
||||
exo2all[it->second] = i;
|
||||
else
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
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__,
|
||||
string("Parameter ") + param + " does not exist in FineAtoms copy cosntructor");
|
||||
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
|
||||
for (auto endovar : fa.endovars)
|
||||
|
@ -99,7 +99,7 @@ FineAtoms::FineAtoms(const FineAtoms &fa)
|
|||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
string("Endo variable ") + endovar + " does not exist in FineAtoms copy constructor");
|
||||
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
|
||||
for (auto exovar : fa.exovars)
|
||||
|
@ -109,7 +109,7 @@ FineAtoms::FineAtoms(const FineAtoms &fa)
|
|||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
string("Exo variable ") + exovar + " does not exist in FineAtoms copy cosntructor");
|
||||
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)
|
||||
|
@ -119,7 +119,7 @@ FineAtoms::FineAtoms(const FineAtoms &fa)
|
|||
exo_order = fa.exo_order->clone(exovars, *this);
|
||||
|
||||
if (fa.allvar_order)
|
||||
allvar_order = new AllvarOuterOrdering(*(fa.allvar_order), *this);
|
||||
allvar_order = std::make_unique<AllvarOuterOrdering>(*(fa.allvar_order), *this);
|
||||
}
|
||||
|
||||
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(), exovars.begin(), exovars.end());
|
||||
|
||||
if (allvar_order)
|
||||
delete allvar_order;
|
||||
allvar_order = new AllvarOuterOrdering(allvar_tmp, *this);
|
||||
allvar_order = std::make_unique<AllvarOuterOrdering>(allvar_tmp, *this);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -166,9 +164,7 @@ FineAtoms::parsing_finished(VarOrdering::ord_type ot,
|
|||
const vector<const char *> allvar)
|
||||
{
|
||||
make_internal_orderings(ot);
|
||||
if (allvar_order)
|
||||
delete allvar_order;
|
||||
allvar_order = new AllvarOuterOrdering(allvar, *this);
|
||||
allvar_order = std::make_unique<AllvarOuterOrdering>(allvar, *this);
|
||||
}
|
||||
|
||||
const vector<const char *> &
|
||||
|
@ -205,14 +201,12 @@ vector<int>
|
|||
FineAtoms::variables() const
|
||||
{
|
||||
if (endo_order)
|
||||
{
|
||||
return der_atoms;
|
||||
}
|
||||
return der_atoms;
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::variables called before parsing_finished");
|
||||
return vector<int>();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,9 +214,7 @@ int
|
|||
FineAtoms::nstat() const
|
||||
{
|
||||
if (endo_order)
|
||||
{
|
||||
return endo_order->nstat();
|
||||
}
|
||||
return endo_order->nstat();
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
|
@ -235,9 +227,7 @@ int
|
|||
FineAtoms::npred() const
|
||||
{
|
||||
if (endo_order)
|
||||
{
|
||||
return endo_order->npred();
|
||||
}
|
||||
return endo_order->npred();
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
|
@ -250,9 +240,7 @@ int
|
|||
FineAtoms::nboth() const
|
||||
{
|
||||
if (endo_order)
|
||||
{
|
||||
return endo_order->nboth();
|
||||
}
|
||||
return endo_order->nboth();
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
|
@ -265,9 +253,7 @@ int
|
|||
FineAtoms::nforw() const
|
||||
{
|
||||
if (endo_order)
|
||||
{
|
||||
return endo_order->nforw();
|
||||
}
|
||||
return endo_order->nforw();
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
|
@ -280,9 +266,7 @@ int
|
|||
FineAtoms::get_pos_of_endo(int t) const
|
||||
{
|
||||
if (endo_order)
|
||||
{
|
||||
return endo_order->get_pos_of(t);
|
||||
}
|
||||
return endo_order->get_pos_of(t);
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
|
@ -295,9 +279,7 @@ int
|
|||
FineAtoms::get_pos_of_exo(int t) const
|
||||
{
|
||||
if (exo_order)
|
||||
{
|
||||
return exo_order->get_pos_of(t);
|
||||
}
|
||||
return exo_order->get_pos_of(t);
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
|
@ -391,7 +373,7 @@ FineAtoms::name2outer_param(const char *name) const
|
|||
if (it == param_outer_map.end())
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Name is not a parameter in FineAtoms::name2outer_param");
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -401,7 +383,7 @@ FineAtoms::name2outer_endo(const char *name) const
|
|||
if (it == endo_outer_map.end())
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Name is not an endogenous variable in FineAtoms::name2outer_endo");
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -411,7 +393,7 @@ FineAtoms::name2outer_exo(const char *name) const
|
|||
if (it == exo_outer_map.end())
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Name is not an exogenous variable in FineAtoms::name2outer_exo");
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -423,12 +405,12 @@ FineAtoms::name2outer_allvar(const char *name) const
|
|||
|
||||
auto it = endo_outer_map.find(name);
|
||||
if (it != endo_outer_map.end())
|
||||
return allvar_order->get_endo2all()[(*it).second];
|
||||
return allvar_order->get_endo2all()[it->second];
|
||||
else
|
||||
{
|
||||
it = exo_outer_map.find(name);
|
||||
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__,
|
||||
|
@ -443,7 +425,7 @@ FineAtoms::register_uniq_endo(const char *name)
|
|||
throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.", 0);
|
||||
const char *ss = varnames.insert(name);
|
||||
endovars.push_back(ss);
|
||||
endo_outer_map.insert(Tvarintmap::value_type(ss, endovars.size()-1));
|
||||
endo_outer_map.emplace(ss, endovars.size()-1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -453,7 +435,7 @@ FineAtoms::register_uniq_exo(const char *name)
|
|||
throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.", 0);
|
||||
const char *ss = varnames.insert(name);
|
||||
exovars.push_back(ss);
|
||||
exo_outer_map.insert(Tvarintmap::value_type(ss, exovars.size()-1));
|
||||
exo_outer_map.emplace(ss, exovars.size()-1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -463,7 +445,7 @@ FineAtoms::register_uniq_param(const char *name)
|
|||
throw ogp::ParserException(string("Parameter <")+name+"> is not unique.", 0);
|
||||
const char *ss = varnames.insert(name);
|
||||
params.push_back(ss);
|
||||
param_outer_map.insert(Tvarintmap::value_type(ss, params.size()-1));
|
||||
param_outer_map.emplace(ss, params.size()-1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -479,12 +461,10 @@ FineAtoms::make_internal_orderings(VarOrdering::ord_type ot)
|
|||
if (mlag >= -1 && mlead <= 1)
|
||||
{
|
||||
// make endo ordering
|
||||
if (endo_order)
|
||||
delete endo_order;
|
||||
if (ot == VarOrdering::pbspbfbf)
|
||||
endo_order = new EndoVarOrdering1(endovars, *this);
|
||||
endo_order = std::make_unique<EndoVarOrdering1>(endovars, *this);
|
||||
else
|
||||
endo_order = new EndoVarOrdering2(endovars, *this);
|
||||
endo_order = std::make_unique<EndoVarOrdering2>(endovars, *this);
|
||||
endo_order->do_ordering();
|
||||
endo_ordering_done = true;
|
||||
}
|
||||
|
@ -493,9 +473,7 @@ FineAtoms::make_internal_orderings(VarOrdering::ord_type ot)
|
|||
if (mlag == 0 && mlead == 0)
|
||||
{
|
||||
// make exo ordering
|
||||
if (exo_order)
|
||||
delete exo_order;
|
||||
exo_order = new ExoVarOrdering(exovars, *this);
|
||||
exo_order = std::make_unique<ExoVarOrdering>(exovars, *this);
|
||||
exo_order->do_ordering();
|
||||
exo_ordering_done = true;
|
||||
}
|
||||
|
@ -534,22 +512,20 @@ FineAtoms::print() const
|
|||
endo_order->print();
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Endo ordering not created.\n");
|
||||
}
|
||||
printf("Endo ordering not created.\n");
|
||||
|
||||
if (exo_order)
|
||||
{
|
||||
printf("Exo ordering:\n");
|
||||
exo_order->print();
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Exo ordering not created.\n");
|
||||
}
|
||||
printf("Exo ordering not created.\n");
|
||||
|
||||
printf("endo atoms map:\n");
|
||||
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");
|
||||
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]);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace ogp
|
||||
{
|
||||
|
@ -32,10 +33,10 @@ namespace ogp
|
|||
: VarOrdering(vo, vnames, a)
|
||||
{
|
||||
}
|
||||
VarOrdering *
|
||||
std::unique_ptr<VarOrdering>
|
||||
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
|
||||
do_ordering() override
|
||||
|
@ -60,10 +61,10 @@ namespace ogp
|
|||
: VarOrdering(vo, vnames, a)
|
||||
{
|
||||
}
|
||||
VarOrdering *
|
||||
std::unique_ptr<VarOrdering>
|
||||
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
|
||||
do_ordering() override
|
||||
|
@ -87,10 +88,10 @@ namespace ogp
|
|||
: VarOrdering(vo, vnames, a)
|
||||
{
|
||||
}
|
||||
VarOrdering *
|
||||
std::unique_ptr<VarOrdering>
|
||||
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
|
||||
do_ordering() override
|
||||
|
@ -201,14 +202,14 @@ namespace ogp
|
|||
* to endogenous variables. It is constructed by
|
||||
* parsing_finished() method, which should be called after all
|
||||
* parsing jobs have been finished. */
|
||||
VarOrdering *endo_order{nullptr};
|
||||
std::unique_ptr<VarOrdering> endo_order;
|
||||
/** This is the internal ordering of all atoms corresponding
|
||||
* to exogenous variables. It has the same handling as
|
||||
* endo_order. */
|
||||
VarOrdering *exo_order{nullptr};
|
||||
std::unique_ptr<VarOrdering> exo_order;
|
||||
/** This is the all variables outer ordering. It is
|
||||
* 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
|
||||
* for differentiation. The order of the atoms in this vector
|
||||
* defines ordering of the derivative tensors. The ordering is
|
||||
|
@ -228,20 +229,10 @@ namespace ogp
|
|||
* atoms of exogenous variables. */
|
||||
vector<int> exo_atoms_map;
|
||||
public:
|
||||
FineAtoms()
|
||||
|
||||
= default;
|
||||
FineAtoms() = default;
|
||||
FineAtoms(const FineAtoms &fa);
|
||||
/** Deletes endo_order and exo_order. */
|
||||
~FineAtoms() override
|
||||
{
|
||||
if (endo_order)
|
||||
delete endo_order;
|
||||
if (exo_order)
|
||||
delete exo_order;
|
||||
if (allvar_order)
|
||||
delete allvar_order;
|
||||
}
|
||||
~FineAtoms() override = default;
|
||||
/** Overrides DynamicAtoms::check_variable so that the error
|
||||
* would be raised if the variable name is not declared. A
|
||||
* variable is declared by inserting it to
|
||||
|
@ -387,13 +378,13 @@ namespace ogp
|
|||
int
|
||||
nexo() const
|
||||
{
|
||||
return (int) exovars.size();
|
||||
return static_cast<int>(exovars.size());
|
||||
}
|
||||
/** Return the number of parameters. */
|
||||
int
|
||||
np() const
|
||||
{
|
||||
return (int) (params.size());
|
||||
return static_cast<int>(params.size());
|
||||
}
|
||||
/** Register unique endogenous variable name. The order of
|
||||
* calls defines the endo outer ordering. The method is
|
||||
|
|
|
@ -47,27 +47,27 @@ extern ogp::FormulaParser* fparser;
|
|||
equation_list : equation_list equation | equation ;
|
||||
|
||||
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 ';'
|
||||
{fparser->add_formula($1);}
|
||||
;
|
||||
|
||||
expression : '(' expression ')' { $$ = $2;}
|
||||
| expression YPLUS expression {$$=fparser->add_binary(ogp::PLUS,$1,$3);}
|
||||
| expression YMINUS expression {$$=fparser->add_binary(ogp::MINUS,$1,$3);}
|
||||
| expression YTIMES expression {$$=fparser->add_binary(ogp::TIMES,$1,$3);}
|
||||
| expression YDIVIDE expression {$$=fparser->add_binary(ogp::DIVIDE,$1,$3);}
|
||||
| expression YPOWER expression {$$=fparser->add_binary(ogp::POWER,$1,$3);}
|
||||
| YMINUS expression %prec YUMINUS {$$=fparser->add_unary(ogp::UMINUS,$2);}
|
||||
| expression YPLUS expression {$$=fparser->add_binary(ogp::code_t::PLUS,$1,$3);}
|
||||
| expression YMINUS expression {$$=fparser->add_binary(ogp::code_t::MINUS,$1,$3);}
|
||||
| expression YTIMES expression {$$=fparser->add_binary(ogp::code_t::TIMES,$1,$3);}
|
||||
| expression YDIVIDE expression {$$=fparser->add_binary(ogp::code_t::DIVIDE,$1,$3);}
|
||||
| expression YPOWER expression {$$=fparser->add_binary(ogp::code_t::POWER,$1,$3);}
|
||||
| YMINUS expression %prec YUMINUS {$$=fparser->add_unary(ogp::code_t::UMINUS,$2);}
|
||||
| YPLUS expression %prec YUPLUS {$$ = $2;}
|
||||
| YSIN '(' expression ')' {$$=fparser->add_unary(ogp::SIN,$3);}
|
||||
| YCOS '(' expression ')' {$$=fparser->add_unary(ogp::COS,$3);}
|
||||
| YTAN '(' expression ')' {$$=fparser->add_unary(ogp::TAN,$3);}
|
||||
| YEXP '(' expression ')' {$$=fparser->add_unary(ogp::EXP,$3);}
|
||||
| YLOG '(' expression ')' {$$=fparser->add_unary(ogp::LOG,$3);}
|
||||
| YSQRT '(' expression ')' {$$=fparser->add_unary(ogp::SQRT,$3);}
|
||||
| YERF '(' expression ')' {$$=fparser->add_unary(ogp::ERF,$3);}
|
||||
| YERFC '(' expression ')' {$$=fparser->add_unary(ogp::ERFC,$3);}
|
||||
| YSIN '(' expression ')' {$$=fparser->add_unary(ogp::code_t::SIN,$3);}
|
||||
| YCOS '(' expression ')' {$$=fparser->add_unary(ogp::code_t::COS,$3);}
|
||||
| YTAN '(' expression ')' {$$=fparser->add_unary(ogp::code_t::TAN,$3);}
|
||||
| YEXP '(' expression ')' {$$=fparser->add_unary(ogp::code_t::EXP,$3);}
|
||||
| YLOG '(' expression ')' {$$=fparser->add_unary(ogp::code_t::LOG,$3);}
|
||||
| YSQRT '(' expression ')' {$$=fparser->add_unary(ogp::code_t::SQRT,$3);}
|
||||
| YERF '(' expression ')' {$$=fparser->add_unary(ogp::code_t::ERF,$3);}
|
||||
| YERFC '(' expression ')' {$$=fparser->add_unary(ogp::code_t::ERFC,$3);}
|
||||
| YDIFF '(' expression ',' NAME ')' {$$=fparser->add_derivative($3, fparser->add_nulary($5));}
|
||||
| NAME {$$=fparser->add_nulary($1);}
|
||||
| DNUMBER {$$=fparser->add_nulary($1);}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "formula_tab.hh"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
|
@ -21,29 +21,24 @@ FormulaParser::FormulaParser(const FormulaParser &fp, Atoms &a)
|
|||
: otree(fp.otree), atoms(a), formulas(fp.formulas), ders()
|
||||
{
|
||||
// create derivatives
|
||||
for (auto der : fp.ders)
|
||||
ders.push_back(new FormulaDerivatives(*der));
|
||||
}
|
||||
|
||||
FormulaParser::~FormulaParser()
|
||||
{
|
||||
destroy_derivatives();
|
||||
for (const auto &der : fp.ders)
|
||||
ders.push_back(std::make_unique<FormulaDerivatives>(*der));
|
||||
}
|
||||
|
||||
void
|
||||
FormulaParser::differentiate(int max_order)
|
||||
{
|
||||
destroy_derivatives();
|
||||
ders.clear();
|
||||
vector<int> vars;
|
||||
vars = atoms.variables();
|
||||
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 &
|
||||
FormulaParser::derivatives(int i) const
|
||||
{
|
||||
if (i < (int) ders.size())
|
||||
if (i < static_cast<int>(ders.size()))
|
||||
return *(ders[i]);
|
||||
else
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
|
@ -108,11 +103,10 @@ FormulaParser::substitute_formulas(const map<int, int> &smap)
|
|||
int f = add_substitution(formulas[i], smap);
|
||||
formulas[i] = f;
|
||||
// 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();
|
||||
delete ders[i];
|
||||
ders[i] = new FormulaDerivatives(otree, atoms.variables(), formulas[i], order);
|
||||
ders[i] = std::make_unique<FormulaDerivatives>(otree, atoms.variables(), formulas[i], order);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,16 +128,15 @@ extern location_type fmla_lloc;
|
|||
void
|
||||
FormulaParser::parse(int length, const char *stream)
|
||||
{
|
||||
auto *buffer = new char[length+2];
|
||||
strncpy(buffer, stream, length);
|
||||
auto buffer = std::make_unique<char[]>(length+2);
|
||||
std::copy_n(stream, length, buffer.get());
|
||||
buffer[length] = '\0';
|
||||
buffer[length+1] = '\0';
|
||||
fmla_lloc.off = 0;
|
||||
fmla_lloc.ll = 0;
|
||||
void *p = fmla__scan_buffer(buffer, (unsigned int) length+2);
|
||||
void *p = fmla__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
|
||||
fparser = this;
|
||||
fmla_parse();
|
||||
delete [] buffer;
|
||||
fmla__destroy_buffer(p);
|
||||
}
|
||||
|
||||
|
@ -158,8 +151,7 @@ FormulaParser::last_formula() const
|
|||
{
|
||||
int res = -1;
|
||||
for (int formula : formulas)
|
||||
if (res < formula)
|
||||
res = formula;
|
||||
res = std::max(res, formula);
|
||||
return std::max(res, otree.get_last_nulary());
|
||||
}
|
||||
|
||||
|
@ -170,10 +162,7 @@ FormulaParser::pop_last_formula()
|
|||
return -1;
|
||||
int t = formulas.back();
|
||||
if (formulas.size() == ders.size())
|
||||
{
|
||||
delete ders.back();
|
||||
ders.pop_back();
|
||||
}
|
||||
ders.pop_back();
|
||||
formulas.pop_back();
|
||||
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
|
||||
* corresponding to derivatives of the given formula. The formula is
|
||||
* supposed to belong to the provided tree, the created derivatives
|
||||
|
@ -254,13 +233,11 @@ FormulaDerivatives::FormulaDerivatives(OperationTree &otree,
|
|||
|
||||
// build ind2der map
|
||||
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)
|
||||
|
||||
= default;
|
||||
FormulaDerivatives::FormulaDerivatives(const FormulaDerivatives &fd) = default;
|
||||
|
||||
int
|
||||
FormulaDerivatives::derivative(const FoldMultiIndex &mi) const
|
||||
|
@ -276,7 +253,7 @@ FormulaDerivatives::derivative(const FoldMultiIndex &mi) const
|
|||
if (it == ind2der.end())
|
||||
return OperationTree::zero;
|
||||
else
|
||||
return tder[(*it).second];
|
||||
return tder[it->second];
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -299,17 +276,17 @@ FormulaCustomEvaluator::eval(const AtomValues &av, FormulaEvalLoader &loader)
|
|||
for (unsigned int i = 0; i < terms.size(); i++)
|
||||
{
|
||||
double res = etree.eval(terms[i]);
|
||||
loader.load((int) i, res);
|
||||
loader.load(static_cast<int>(i), res);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
: 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++)
|
||||
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
|
||||
* monotone sequence. */
|
||||
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++)
|
||||
{
|
||||
|
@ -335,36 +312,31 @@ FoldMultiIndex::FoldMultiIndex(int nv, const FoldMultiIndex &mi, const vector<in
|
|||
FoldMultiIndex::FoldMultiIndex(const FoldMultiIndex &fmi, int new_orders)
|
||||
: nvar(fmi.nvar),
|
||||
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;
|
||||
for (int i = fmi.ord; i < ord; i++)
|
||||
{
|
||||
data[i] = new_item;
|
||||
}
|
||||
data[i] = new_item;
|
||||
}
|
||||
|
||||
FoldMultiIndex::FoldMultiIndex(const FoldMultiIndex &fmi)
|
||||
: nvar(fmi.nvar),
|
||||
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 &
|
||||
FoldMultiIndex::operator=(const FoldMultiIndex &fmi)
|
||||
{
|
||||
if (ord != fmi.ord)
|
||||
{
|
||||
delete [] data;
|
||||
data = new int[fmi.ord];
|
||||
}
|
||||
data = std::make_unique<int[]>(fmi.ord);
|
||||
|
||||
ord = fmi.ord;
|
||||
nvar = fmi.nvar;
|
||||
memcpy(data, fmi.data, ord*sizeof(int));
|
||||
std::copy_n(fmi.data.get(), ord, data.get());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -427,13 +399,10 @@ int
|
|||
FoldMultiIndex::offset() const
|
||||
{
|
||||
// make copy for the recursions
|
||||
auto *tmp = new int[ord];
|
||||
for (int i = 0; i < ord; i++)
|
||||
tmp[i] = data[i];
|
||||
auto tmp = std::make_unique<int[]>(ord);
|
||||
std::copy_n(data.get(), ord, tmp.get());
|
||||
// call the recursive algorithm
|
||||
int res = offset_recurse(tmp, ord, nvar);
|
||||
|
||||
delete [] tmp;
|
||||
int res = offset_recurse(tmp.get(), ord, nvar);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -478,8 +447,8 @@ ltfmi::operator()(const FoldMultiIndex &i1, const FoldMultiIndex &i2) const
|
|||
FormulaDerEvaluator::FormulaDerEvaluator(const FormulaParser &fp)
|
||||
: etree(fp.otree, -1)
|
||||
{
|
||||
for (auto der : fp.ders)
|
||||
ders.push_back((const FormulaDerivatives *) der);
|
||||
for (const auto &der : fp.ders)
|
||||
ders.push_back(der.get());
|
||||
|
||||
der_atoms = fp.atoms.variables();
|
||||
}
|
||||
|
@ -498,28 +467,25 @@ FormulaDerEvaluator::eval(const AtomValues &av, FormulaDerEvalLoader &loader, in
|
|||
etree.reset_all();
|
||||
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 (auto it = ders[i]->ind2der.begin();
|
||||
it != ders[i]->ind2der.end(); ++it)
|
||||
for (const auto &it : ders[i]->ind2der)
|
||||
{
|
||||
const FoldMultiIndex &mi = (*it).first;
|
||||
const FoldMultiIndex &mi = it.first;
|
||||
if (mi.order() == order)
|
||||
{
|
||||
// set vars from multiindex mi and variables
|
||||
for (int k = 0; k < order; k++)
|
||||
vars[k] = der_atoms[mi[k]];
|
||||
// evaluate
|
||||
double res = etree.eval(ders[i]->tder[(*it).second]);
|
||||
double res = etree.eval(ders[i]->tder[it.second]);
|
||||
// load
|
||||
loader.load(i, order, vars, res);
|
||||
loader.load(i, order, vars.get(), res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete [] vars;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -531,7 +497,7 @@ FormulaDerEvaluator::eval(const vector<int> &mp, const AtomValues &av,
|
|||
|
||||
int nvar_glob = der_atoms.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++)
|
||||
{
|
||||
|
@ -549,12 +515,10 @@ FormulaDerEvaluator::eval(const vector<int> &mp, const AtomValues &av,
|
|||
// evaluate derivative
|
||||
double res = etree.eval(der);
|
||||
// load
|
||||
loader.load(i, order, vars, res);
|
||||
loader.load(i, order, vars.get(), res);
|
||||
}
|
||||
mi.increment();
|
||||
}
|
||||
while (!mi.past_the_end());
|
||||
}
|
||||
|
||||
delete [] vars;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#define OGP_FORMULA_PARSER_H
|
||||
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "tree.hh"
|
||||
|
||||
|
@ -16,10 +18,8 @@ namespace ogp
|
|||
class Atoms
|
||||
{
|
||||
public:
|
||||
Atoms()
|
||||
= default;
|
||||
virtual ~Atoms()
|
||||
= default;
|
||||
Atoms() = default;
|
||||
virtual ~Atoms() = default;
|
||||
/** This returns previously assigned internal index to the
|
||||
* given atom, or returns -1 if the atom has not been assigned
|
||||
* yet. The method can raise an exception, if the Atoms
|
||||
|
@ -48,8 +48,7 @@ namespace ogp
|
|||
class AtomValues
|
||||
{
|
||||
public:
|
||||
virtual ~AtomValues()
|
||||
= default;
|
||||
virtual ~AtomValues() = default;
|
||||
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);
|
||||
/** Copy constructor. */
|
||||
FormulaDerivatives(const FormulaDerivatives &fd);
|
||||
virtual ~FormulaDerivatives()
|
||||
= default;
|
||||
virtual ~FormulaDerivatives() = default;
|
||||
/** Random access to the derivatives via multiindex. */
|
||||
int derivative(const FoldMultiIndex &mi) const;
|
||||
/** Return the order. */
|
||||
|
@ -151,7 +149,7 @@ namespace ogp
|
|||
vector<int> formulas;
|
||||
/** The vector to derivatives, each vector corresponds to a
|
||||
* formula in the vector formulas. */
|
||||
vector<FormulaDerivatives *> ders;
|
||||
vector<std::unique_ptr<FormulaDerivatives>> ders;
|
||||
public:
|
||||
/** Construct an empty formula parser. */
|
||||
FormulaParser(Atoms &a)
|
||||
|
@ -161,8 +159,7 @@ namespace ogp
|
|||
FormulaParser(const FormulaParser &fp) = delete;
|
||||
/** Copy constructor using a different instance of Atoms. */
|
||||
FormulaParser(const FormulaParser &fp, Atoms &a);
|
||||
virtual
|
||||
~FormulaParser();
|
||||
virtual ~FormulaParser() = default;
|
||||
|
||||
/** Requires an addition of the formula; called from the
|
||||
* parser. */
|
||||
|
@ -267,7 +264,7 @@ namespace ogp
|
|||
int
|
||||
nformulas() const
|
||||
{
|
||||
return (int) (formulas.size());
|
||||
return static_cast<int>(formulas.size());
|
||||
}
|
||||
|
||||
/** This returns a reference to atoms. */
|
||||
|
@ -295,9 +292,6 @@ namespace ogp
|
|||
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
private:
|
||||
/** Destroy all derivatives. */
|
||||
void destroy_derivatives();
|
||||
};
|
||||
|
||||
/** This is a pure virtual class defining an interface for all
|
||||
|
@ -307,8 +301,7 @@ namespace ogp
|
|||
class FormulaEvalLoader
|
||||
{
|
||||
public:
|
||||
virtual ~FormulaEvalLoader()
|
||||
= default;
|
||||
virtual ~FormulaEvalLoader() = default;
|
||||
/** Set the value res for the given formula. The formula is
|
||||
* identified by an index corresponding to the ordering in
|
||||
* which the formulas have been parsed (starting from
|
||||
|
@ -368,8 +361,7 @@ namespace ogp
|
|||
class FormulaDerEvalLoader
|
||||
{
|
||||
public:
|
||||
virtual ~FormulaDerEvalLoader()
|
||||
= default;
|
||||
virtual ~FormulaDerEvalLoader() = default;
|
||||
/** This loads the result of the derivative of the given
|
||||
* order. The semantics of i is the same as in
|
||||
* FormulaEvalLoader::load. The indices of variables with
|
||||
|
@ -389,7 +381,7 @@ namespace ogp
|
|||
/** Dimension. */
|
||||
int ord;
|
||||
/** The multiindex. */
|
||||
int *data;
|
||||
std::unique_ptr<int[]> data;
|
||||
public:
|
||||
/** Initializes to the zero derivative. Order is 0, data is
|
||||
* empty. */
|
||||
|
@ -407,10 +399,7 @@ namespace ogp
|
|||
/** Copy constructor. */
|
||||
FoldMultiIndex(const FoldMultiIndex &fmi);
|
||||
/** Desctructor. */
|
||||
virtual ~FoldMultiIndex()
|
||||
{
|
||||
delete [] data;
|
||||
}
|
||||
virtual ~FoldMultiIndex() = default;
|
||||
/** Assignment operator. */
|
||||
const FoldMultiIndex &operator=(const FoldMultiIndex &fmi);
|
||||
/** Operator < implementing lexicographic ordering within one
|
||||
|
@ -443,7 +432,7 @@ namespace ogp
|
|||
const int *
|
||||
ind() const
|
||||
{
|
||||
return data;
|
||||
return data.get();
|
||||
}
|
||||
/** Return true if the end of the tensor is reached. The
|
||||
* result of a subsequent increment should be considered
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
#include "matrix_parser.hh"
|
||||
#include "location.hh"
|
||||
#include "matrix_tab.hh"
|
||||
#include <cstring>
|
||||
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
|
@ -29,16 +31,15 @@ MatrixParser::parse(int length, const char *stream)
|
|||
row_lengths.clear();
|
||||
nc = 0;
|
||||
// allocate temporary buffer and parse
|
||||
auto *buffer = new char[length+2];
|
||||
strncpy(buffer, stream, length);
|
||||
auto buffer = std::make_unique<char[]>(length+2);
|
||||
std::copy_n(stream, length, buffer.get());
|
||||
buffer[length] = '\0';
|
||||
buffer[length+1] = '\0';
|
||||
matrix_lloc.off = 0;
|
||||
matrix_lloc.ll = 0;
|
||||
void *p = matrix__scan_buffer(buffer, (unsigned int) length+2);
|
||||
void *p = matrix__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
|
||||
mparser = this;
|
||||
matrix_parse();
|
||||
delete [] buffer;
|
||||
matrix__destroy_buffer(p);
|
||||
}
|
||||
|
||||
|
@ -49,8 +50,7 @@ MatrixParser::add_item(double v)
|
|||
if (row_lengths.size() == 0)
|
||||
row_lengths.push_back(0);
|
||||
(row_lengths.back())++;
|
||||
if (row_lengths.back() > nc)
|
||||
nc = row_lengths.back();
|
||||
nc = std::max(nc, row_lengths.back());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -69,7 +69,7 @@ int
|
|||
MatrixParser::find_first_non_empty_row(int start) const
|
||||
{
|
||||
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++;
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#ifndef OGP_MATRIX_PARSER
|
||||
#define OGP_MATRIX_PARSER
|
||||
|
||||
#include <cstdlib> // For NULL
|
||||
#include <vector>
|
||||
|
||||
namespace ogp
|
||||
|
@ -33,19 +32,14 @@ namespace ogp
|
|||
/** Maximum number of row lengths. */
|
||||
int nc{0};
|
||||
public:
|
||||
MatrixParser()
|
||||
|
||||
= default;
|
||||
MatrixParser(const MatrixParser &mp)
|
||||
|
||||
= default;
|
||||
virtual ~MatrixParser()
|
||||
= default;
|
||||
MatrixParser() = default;
|
||||
MatrixParser(const MatrixParser &mp) = default;
|
||||
virtual ~MatrixParser() = default;
|
||||
/** Return a number of read rows. */
|
||||
int
|
||||
nrows() const
|
||||
{
|
||||
return (int) row_lengths.size();
|
||||
return static_cast<int>(row_lengths.size());
|
||||
}
|
||||
/** Return a maximum number of items in the rows. */
|
||||
int
|
||||
|
@ -91,8 +85,7 @@ namespace ogp
|
|||
int r{0};
|
||||
|
||||
public:
|
||||
MPIterator()
|
||||
= default;
|
||||
MPIterator() = default;
|
||||
/** Constructs an iterator pointing to the beginning of the
|
||||
* parsed matrix. */
|
||||
MPIterator(const MatrixParser &mp);
|
||||
|
@ -118,9 +111,7 @@ namespace ogp
|
|||
return c;
|
||||
}
|
||||
/** Assignment operator. */
|
||||
MPIterator &
|
||||
operator=(const MPIterator &it)
|
||||
= default;
|
||||
MPIterator &operator=(const MPIterator &it) = default;
|
||||
/** Return true if the iterators are the same, this is if they
|
||||
* have the same underlying object and the same item index. */
|
||||
bool
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
#include "namelist.hh"
|
||||
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
|
@ -19,13 +20,12 @@ void namelist_parse();
|
|||
void
|
||||
NameListParser::namelist_parse(int length, const char *stream)
|
||||
{
|
||||
auto *buffer = new char[length+2];
|
||||
strncpy(buffer, stream, length);
|
||||
auto buffer = std::make_unique<char[]>(length+2);
|
||||
std::copy_n(str, length, buffer.get());
|
||||
buffer[length] = '\0';
|
||||
buffer[length+1] = '\0';
|
||||
void *p = namelist__scan_buffer(buffer, (unsigned int) length+2);
|
||||
void *p = namelist__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
|
||||
name_list_parser = this;
|
||||
::namelist_parse();
|
||||
delete [] buffer;
|
||||
namelist__destroy_buffer(p);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace ogp
|
||||
{
|
||||
|
||||
/** Parent class of all parsers parsing a namelist. They must
|
||||
* implement add_name() method and error() method, which is called
|
||||
* when an parse error occurs.
|
||||
|
@ -20,8 +19,7 @@ namespace ogp
|
|||
class NameListParser
|
||||
{
|
||||
public:
|
||||
virtual ~NameListParser()
|
||||
= default;
|
||||
virtual ~NameListParser() = default;
|
||||
virtual void add_name(const char *name) = 0;
|
||||
virtual void namelist_error(const char *mes) = 0;
|
||||
void namelist_parse(int length, const char *text);
|
||||
|
|
|
@ -3,61 +3,42 @@
|
|||
// $Id: parser_exception.cpp 2269 2008-11-23 14:33:22Z michel $
|
||||
|
||||
#include "parser_exception.hh"
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
ParserException::ParserException(const char *m, int offset)
|
||||
: mes(new char[strlen(m)+1]), off(offset),
|
||||
ParserException::ParserException(string m, int offset)
|
||||
: mes(std::move(m)), off(offset),
|
||||
aux_i1(-1), aux_i2(-1), aux_i3(-1)
|
||||
{
|
||||
strcpy(mes, m);
|
||||
}
|
||||
|
||||
ParserException::ParserException(const string &m, int offset)
|
||||
: mes(new char[m.size()+1]), off(offset),
|
||||
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),
|
||||
ParserException::ParserException(string m, const char *dum, int i1)
|
||||
: mes(std::move(m)), off(0),
|
||||
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)
|
||||
: mes(new char[m.size()+1]), off(0),
|
||||
ParserException::ParserException(string m, const char *dum, int i1, int i2)
|
||||
: mes(std::move(m)), off(0),
|
||||
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)
|
||||
: mes(new char[m.size()+1]), off(0),
|
||||
ParserException::ParserException(string m, const char *dum, int i1, int i2, int i3)
|
||||
: mes(std::move(m)), off(0),
|
||||
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)
|
||||
: mes(nullptr),
|
||||
aux_i1(-1), aux_i2(-1), aux_i3(-1)
|
||||
: aux_i1(-1), aux_i2(-1), aux_i3(-1)
|
||||
{
|
||||
copy(m);
|
||||
off += plus_offset;
|
||||
}
|
||||
|
||||
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);
|
||||
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)
|
||||
: mes(nullptr),
|
||||
aux_i1(-1), aux_i2(-1), aux_i3(-1)
|
||||
: aux_i1(-1), aux_i2(-1), aux_i3(-1)
|
||||
{
|
||||
copy(m);
|
||||
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)
|
||||
: mes(nullptr),
|
||||
aux_i1(-1), aux_i2(-1), aux_i3(-1)
|
||||
: aux_i1(-1), aux_i2(-1), aux_i3(-1)
|
||||
{
|
||||
copy(m);
|
||||
aux_i3 = i3;
|
||||
|
@ -85,34 +64,12 @@ ParserException::ParserException(const ParserException &m, const char *dum, int
|
|||
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
|
||||
ParserException::copy(const ParserException &e)
|
||||
{
|
||||
if (mes)
|
||||
delete [] mes;
|
||||
mes = new char[strlen(e.mes)+1];
|
||||
strcpy(mes, e.mes);
|
||||
mes = e.mes;
|
||||
off = e.off;
|
||||
aux_i1 = e.aux_i1;
|
||||
aux_i2 = e.aux_i2;
|
||||
aux_i3 = e.aux_i3;
|
||||
}
|
||||
|
||||
void
|
||||
ParserException::print(FILE *fd) const
|
||||
{
|
||||
// todo: to be refined
|
||||
fprintf(fd, "%s: offset %d\n", mes, off);
|
||||
}
|
||||
|
|
|
@ -21,17 +21,16 @@ namespace ogp
|
|||
class ParserException
|
||||
{
|
||||
protected:
|
||||
char *mes;
|
||||
string mes;
|
||||
int off;
|
||||
int aux_i1;
|
||||
int aux_i2;
|
||||
int aux_i3;
|
||||
public:
|
||||
ParserException(const char *m, int offset);
|
||||
ParserException(const string &m, int offset);
|
||||
ParserException(const string &m, const char *dum, int i1);
|
||||
ParserException(const string &m, const char *dum, int i1, int i2);
|
||||
ParserException(const string &m, const char *dum, int i1, int i2, int i3);
|
||||
ParserException(string m, int offset);
|
||||
ParserException(string m, const char *dum, int i1);
|
||||
ParserException(string m, const char *dum, int i1, int i2);
|
||||
ParserException(string m, const char *dum, int i1, int i2, int i3);
|
||||
ParserException(const ParserException &e, int plus_offset);
|
||||
/** Makes a copy and pushes given integer to aux_i1 shuffling
|
||||
* others and forgetting the last. */
|
||||
|
@ -42,11 +41,9 @@ namespace ogp
|
|||
/** Makes a copy and pushes given three integers to aux_i1, aux_i2, aus_i3 shuffling
|
||||
* others and forgetting the last three. */
|
||||
ParserException(const ParserException &e, const char *dum, int i1, int i2, int i3);
|
||||
ParserException(const ParserException &e);
|
||||
virtual
|
||||
~ParserException();
|
||||
void print(FILE *fd) const;
|
||||
const char *
|
||||
ParserException(const ParserException &e) = default;
|
||||
virtual ~ParserException() = default;
|
||||
const string &
|
||||
message() const
|
||||
{
|
||||
return mes;
|
||||
|
|
|
@ -22,14 +22,14 @@ StaticAtoms::StaticAtoms(const StaticAtoms &a)
|
|||
for (auto var : a.vars)
|
||||
{
|
||||
const char *s = varnames.query(var.first);
|
||||
vars.insert(Tvarmap::value_type(s, var.second));
|
||||
vars.emplace(s, var.second);
|
||||
}
|
||||
|
||||
// fill indices
|
||||
for (auto indice : a.indices)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
if (DynamicAtoms::is_string_constant(name))
|
||||
{
|
||||
return Constants::check(name);
|
||||
}
|
||||
return Constants::check(name);
|
||||
else
|
||||
{
|
||||
return check_variable(name);
|
||||
}
|
||||
return check_variable(name);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -76,7 +72,7 @@ StaticAtoms::index(const char *name) const
|
|||
if (it == vars.end())
|
||||
return -1;
|
||||
else
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const char *
|
||||
|
@ -86,7 +82,7 @@ StaticAtoms::inv_index(int t) const
|
|||
if (it == indices.end())
|
||||
return nullptr;
|
||||
else
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -101,8 +97,8 @@ StaticAtoms::assign(const char *name, int t)
|
|||
else
|
||||
{
|
||||
const char *ss = varnames.insert(name);
|
||||
vars.insert(Tvarmap::value_type(ss, t));
|
||||
indices.insert(Tinvmap::value_type(t, ss));
|
||||
vars.emplace(ss, t);
|
||||
indices.emplace(t, ss);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,9 +107,7 @@ StaticAtoms::variables() const
|
|||
{
|
||||
vector<int> res;
|
||||
for (auto var : vars)
|
||||
{
|
||||
res.push_back(var.second);
|
||||
}
|
||||
res.push_back(var.second);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -133,5 +127,5 @@ StaticAtoms::print() const
|
|||
varnames.print();
|
||||
printf("map to tree indices:\n");
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
namespace ogp
|
||||
{
|
||||
|
||||
class StaticAtoms : public Atoms, public Constants
|
||||
{
|
||||
protected:
|
||||
|
@ -42,8 +41,7 @@ namespace ogp
|
|||
import_atoms(da, otree, tmap);
|
||||
}
|
||||
/* Destructor. */
|
||||
~StaticAtoms()
|
||||
override = default;
|
||||
~StaticAtoms() override = default;
|
||||
/** This imports atoms from dynamic atoms inserting the new
|
||||
* tree indices to the given tree (including constants). The
|
||||
* mapping from old atoms to new atoms is traced in tmap. */
|
||||
|
|
|
@ -22,21 +22,21 @@ StaticFineAtoms::StaticFineAtoms(const StaticFineAtoms &sfa)
|
|||
{
|
||||
const char *name = varnames.query(sfa.params[i]);
|
||||
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++)
|
||||
{
|
||||
const char *name = varnames.query(sfa.endovars[i]);
|
||||
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++)
|
||||
{
|
||||
const char *name = varnames.query(sfa.exovars[i]);
|
||||
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
|
||||
{
|
||||
const char *ss = varnames.query(name);
|
||||
if (ss == nullptr)
|
||||
if (!ss)
|
||||
throw ParserException(string("Variable <")+name+"> not declared.", 0);
|
||||
return index(name);
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ StaticFineAtoms::name2outer_param(const char *name) const
|
|||
if (it == param_outer_map.end())
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Name is not a parameter in StaticFineAtoms::name2outer_param");
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -149,7 +149,7 @@ StaticFineAtoms::name2outer_endo(const char *name) const
|
|||
if (it == endo_outer_map.end())
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Name is not an endogenous variable in StaticFineAtoms::name2outer_endo");
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -159,7 +159,7 @@ StaticFineAtoms::name2outer_exo(const char *name) const
|
|||
if (it == exo_outer_map.end())
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Name is not an exogenous variable in StaticFineAtoms::name2outer_exo");
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -195,10 +195,10 @@ StaticFineAtoms::print() const
|
|||
StaticAtoms::print();
|
||||
printf("endo atoms map:\n");
|
||||
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");
|
||||
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");
|
||||
for (unsigned int i = 0; i < der_atoms.size(); i++)
|
||||
printf("%d\t%d\n", i, der_atoms[i]);
|
||||
|
@ -208,30 +208,30 @@ void
|
|||
StaticFineAtoms::register_endo(const char *name)
|
||||
{
|
||||
const char *ss = varnames.query(name);
|
||||
if (ss == nullptr)
|
||||
if (!ss)
|
||||
throw ogp::ParserException(string("Endogenous variable <")
|
||||
+name+"> not found in storage.", 0);
|
||||
endovars.push_back(ss);
|
||||
endo_outer_map.insert(Tvarintmap::value_type(ss, endovars.size()-1));
|
||||
endo_outer_map.emplace(ss, endovars.size()-1);
|
||||
}
|
||||
|
||||
void
|
||||
StaticFineAtoms::register_exo(const char *name)
|
||||
{
|
||||
const char *ss = varnames.query(name);
|
||||
if (ss == nullptr)
|
||||
if (!ss)
|
||||
throw ogp::ParserException(string("Exogenous variable <")
|
||||
+name+"> not found in storage.", 0);
|
||||
exovars.push_back(ss);
|
||||
exo_outer_map.insert(Tvarintmap::value_type(ss, exovars.size()-1));
|
||||
exo_outer_map.emplace(ss, exovars.size()-1);
|
||||
}
|
||||
|
||||
void
|
||||
StaticFineAtoms::register_param(const char *name)
|
||||
{
|
||||
const char *ss = varnames.query(name);
|
||||
if (ss == nullptr)
|
||||
if (!ss)
|
||||
throw ogp::ParserException(string("Parameter <")+name+"> not found in storage.", 0);
|
||||
params.push_back(ss);
|
||||
param_outer_map.insert(Tvarintmap::value_type(ss, params.size()-1));
|
||||
param_outer_map.emplace(ss, params.size()-1);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
namespace ogp
|
||||
{
|
||||
|
||||
/** This class represents static atoms distinguishing between
|
||||
* parameters, endogenous and exogenous variables. The class
|
||||
* maintains also ordering of all three categories (referenced as
|
||||
|
@ -61,8 +60,7 @@ namespace ogp
|
|||
* atoms of exogenous variables. */
|
||||
vector<int> exo_atoms_map;
|
||||
public:
|
||||
StaticFineAtoms()
|
||||
= default;
|
||||
StaticFineAtoms() = default;
|
||||
/** Copy constructor making a new storage for atom names. */
|
||||
StaticFineAtoms(const StaticFineAtoms &sfa);
|
||||
/** Conversion from dynamic FineAtoms taking its outer
|
||||
|
@ -84,8 +82,7 @@ namespace ogp
|
|||
{
|
||||
StaticFineAtoms::import_atoms(fa, otree, tmap, dummy);
|
||||
}
|
||||
~StaticFineAtoms()
|
||||
override = default;
|
||||
~StaticFineAtoms() override = default;
|
||||
/** This adds atoms from dynamic atoms inserting new tree
|
||||
* indices to the given tree and tracing the mapping from old
|
||||
* atoms to new atoms in tmap. The ordering of the static
|
||||
|
@ -166,13 +163,13 @@ namespace ogp
|
|||
int
|
||||
nexo() const
|
||||
{
|
||||
return (int) exovars.size();
|
||||
return static_cast<int>(exovars.size());
|
||||
}
|
||||
/** Return the number of parameters. */
|
||||
int
|
||||
np() const
|
||||
{
|
||||
return (int) (params.size());
|
||||
return static_cast<int>(params.size());
|
||||
}
|
||||
/** Register unique endogenous variable name. The order of
|
||||
* calls defines the endo outer ordering. The method is
|
||||
|
@ -202,7 +199,6 @@ namespace ogp
|
|||
* storage. */
|
||||
void register_param(const char *name);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
#include "tree.hh"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
|
@ -25,13 +23,11 @@ int
|
|||
OperationTree::add_nulary()
|
||||
{
|
||||
int op = terms.size();
|
||||
Operation nulary;
|
||||
terms.push_back(nulary);
|
||||
terms.push_back({});
|
||||
_Tintset s;
|
||||
s.insert(op);
|
||||
nul_incidence.push_back(s);
|
||||
_Tderivmap empty;
|
||||
derivatives.push_back(empty);
|
||||
derivatives.push_back({});
|
||||
last_nulary = op;
|
||||
return op;
|
||||
}
|
||||
|
@ -40,21 +36,21 @@ int
|
|||
OperationTree::add_unary(code_t code, int op)
|
||||
{
|
||||
if (op == zero
|
||||
&& (code == UMINUS
|
||||
|| code == SIN
|
||||
|| code == TAN
|
||||
|| code == SQRT
|
||||
|| code == ERF))
|
||||
&& (code == code_t::UMINUS
|
||||
|| code == code_t::SIN
|
||||
|| code == code_t::TAN
|
||||
|| code == code_t::SQRT
|
||||
|| code == code_t::ERF))
|
||||
return zero;
|
||||
if ((op == zero && code == LOG) || op == nan)
|
||||
if ((op == zero && code == code_t::LOG) || op == nan)
|
||||
return nan;
|
||||
if (op == zero && (code == EXP
|
||||
|| code == COS
|
||||
|| code == ERFC))
|
||||
if (op == zero && (code == code_t::EXP
|
||||
|| code == code_t::COS
|
||||
|| code == code_t::ERFC))
|
||||
return one;
|
||||
|
||||
Operation unary(code, op);
|
||||
auto i = ((const _Topmap &) opmap).find(unary);
|
||||
auto i = opmap.find(unary);
|
||||
if (i == opmap.end())
|
||||
{
|
||||
int newop = terms.size();
|
||||
|
@ -63,13 +59,13 @@ OperationTree::add_unary(code_t code, int op)
|
|||
// copy incidence of the operand
|
||||
nul_incidence.push_back(nul_incidence[op]);
|
||||
// insert it to opmap
|
||||
opmap.insert(_Topval(unary, newop));
|
||||
opmap.emplace(unary, newop);
|
||||
// add empty map of derivatives
|
||||
_Tderivmap empty;
|
||||
derivatives.push_back(empty);
|
||||
return newop;
|
||||
}
|
||||
return (*i).second;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -79,7 +75,7 @@ OperationTree::add_binary(code_t code, int op1, int op2)
|
|||
if (op1 == nan || op2 == nan)
|
||||
return nan;
|
||||
// for plus
|
||||
if (code == PLUS)
|
||||
if (code == code_t::PLUS)
|
||||
{
|
||||
if (op1 == zero && op2 == zero)
|
||||
return zero;
|
||||
|
@ -89,17 +85,17 @@ OperationTree::add_binary(code_t code, int op1, int op2)
|
|||
return op1;
|
||||
}
|
||||
// for minus
|
||||
if (code == MINUS)
|
||||
if (code == code_t::MINUS)
|
||||
{
|
||||
if (op1 == zero && op2 == zero)
|
||||
return zero;
|
||||
else if (op1 == zero)
|
||||
return add_unary(UMINUS, op2);
|
||||
return add_unary(code_t::UMINUS, op2);
|
||||
else if (op2 == zero)
|
||||
return op1;
|
||||
}
|
||||
// for times
|
||||
if (code == TIMES)
|
||||
if (code == code_t::TIMES)
|
||||
{
|
||||
if (op1 == zero || op2 == zero)
|
||||
return zero;
|
||||
|
@ -109,7 +105,7 @@ OperationTree::add_binary(code_t code, int op1, int op2)
|
|||
return op1;
|
||||
}
|
||||
// for divide
|
||||
if (code == DIVIDE)
|
||||
if (code == code_t::DIVIDE)
|
||||
{
|
||||
if (op1 == op2)
|
||||
return one;
|
||||
|
@ -119,7 +115,7 @@ OperationTree::add_binary(code_t code, int op1, int op2)
|
|||
return nan;
|
||||
}
|
||||
// for power
|
||||
if (code == POWER)
|
||||
if (code == code_t::POWER)
|
||||
{
|
||||
if (op1 == zero && op2 == zero)
|
||||
return nan;
|
||||
|
@ -134,7 +130,7 @@ OperationTree::add_binary(code_t code, int op1, int op2)
|
|||
}
|
||||
|
||||
// order operands of commutative operations
|
||||
if (code == TIMES || code == PLUS)
|
||||
if (code == code_t::TIMES || code == code_t::PLUS)
|
||||
if (op1 > op2)
|
||||
{
|
||||
int tmp = op1;
|
||||
|
@ -144,7 +140,7 @@ OperationTree::add_binary(code_t code, int op1, int op2)
|
|||
|
||||
// construct operation and check/add it
|
||||
Operation binary(code, op1, op2);
|
||||
auto i = ((const _Topmap &) opmap).find(binary);
|
||||
auto i = opmap.find(binary);
|
||||
if (i == opmap.end())
|
||||
{
|
||||
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.back().insert(nul_incidence[op2].begin(), nul_incidence[op2].end());
|
||||
// add to opmap
|
||||
opmap.insert(_Topval(binary, newop));
|
||||
opmap.emplace(binary, newop);
|
||||
// add empty map of derivatives
|
||||
_Tderivmap empty;
|
||||
derivatives.push_back(empty);
|
||||
return newop;
|
||||
}
|
||||
return (*i).second;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
int
|
||||
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__,
|
||||
"Wrong value for tree index in OperationTree::add_derivative");
|
||||
|
||||
// quick returns for nulary terms or empty incidence
|
||||
if (terms[t].nary() == 0 && t != v)
|
||||
{
|
||||
return zero;
|
||||
}
|
||||
return zero;
|
||||
|
||||
if (terms[t].nary() == 0 && t == v)
|
||||
{
|
||||
return one;
|
||||
}
|
||||
return one;
|
||||
|
||||
if (nul_incidence[t].end() == nul_incidence[t].find(v))
|
||||
{
|
||||
return zero;
|
||||
}
|
||||
return zero;
|
||||
|
||||
// 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())
|
||||
return (*i).second;
|
||||
return i->second;
|
||||
|
||||
int res = -1;
|
||||
switch (terms[t].getCode())
|
||||
{
|
||||
|
||||
case UMINUS:
|
||||
case code_t::UMINUS:
|
||||
{
|
||||
int tmp = add_derivative(terms[t].getOp1(), v);
|
||||
res = add_unary(UMINUS, tmp);
|
||||
res = add_unary(code_t::UMINUS, tmp);
|
||||
break;
|
||||
}
|
||||
case LOG:
|
||||
case code_t::LOG:
|
||||
{
|
||||
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;
|
||||
}
|
||||
case EXP:
|
||||
case code_t::EXP:
|
||||
{
|
||||
int tmp = add_derivative(terms[t].getOp1(), v);
|
||||
res = add_binary(TIMES, t, tmp);
|
||||
res = add_binary(code_t::TIMES, t, tmp);
|
||||
break;
|
||||
}
|
||||
case SIN:
|
||||
case code_t::SIN:
|
||||
{
|
||||
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;
|
||||
}
|
||||
case COS:
|
||||
case code_t::COS:
|
||||
{
|
||||
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;
|
||||
}
|
||||
case TAN:
|
||||
case code_t::TAN:
|
||||
{
|
||||
int tmp = add_derivative(terms[t].getOp1(), v);
|
||||
int tmp2 = add_unary(COS, terms[t].getOp1());
|
||||
res = add_binary(DIVIDE, tmp, add_binary(TIMES, tmp2, tmp2));
|
||||
int tmp2 = add_unary(code_t::COS, terms[t].getOp1());
|
||||
res = add_binary(code_t::DIVIDE, tmp, add_binary(code_t::TIMES, tmp2, tmp2));
|
||||
break;
|
||||
}
|
||||
case SQRT:
|
||||
case code_t::SQRT:
|
||||
{
|
||||
int tmp = add_derivative(terms[t].getOp1(), v);
|
||||
res = add_binary(DIVIDE, tmp,
|
||||
add_binary(PLUS, t, t));
|
||||
res = add_binary(code_t::DIVIDE, tmp,
|
||||
add_binary(code_t::PLUS, t, t));
|
||||
break;
|
||||
}
|
||||
case ERF:
|
||||
case code_t::ERF:
|
||||
{
|
||||
int tmp = add_binary(TIMES, terms[t].getOp1(), terms[t].getOp1());
|
||||
tmp = add_unary(UMINUS, tmp);
|
||||
tmp = add_unary(EXP, tmp);
|
||||
int tmp = add_binary(code_t::TIMES, terms[t].getOp1(), terms[t].getOp1());
|
||||
tmp = add_unary(code_t::UMINUS, tmp);
|
||||
tmp = add_unary(code_t::EXP, tmp);
|
||||
int der = add_derivative(terms[t].getOp1(), v);
|
||||
tmp = add_binary(TIMES, tmp, der);
|
||||
res = add_binary(TIMES, two_over_pi, tmp);
|
||||
tmp = add_binary(code_t::TIMES, tmp, der);
|
||||
res = add_binary(code_t::TIMES, two_over_pi, tmp);
|
||||
break;
|
||||
}
|
||||
case ERFC:
|
||||
case code_t::ERFC:
|
||||
{
|
||||
int tmp = add_binary(TIMES, terms[t].getOp1(), terms[t].getOp1());
|
||||
tmp = add_unary(UMINUS, tmp);
|
||||
tmp = add_unary(EXP, tmp);
|
||||
int tmp = add_binary(code_t::TIMES, terms[t].getOp1(), terms[t].getOp1());
|
||||
tmp = add_unary(code_t::UMINUS, tmp);
|
||||
tmp = add_unary(code_t::EXP, tmp);
|
||||
int der = add_derivative(terms[t].getOp1(), v);
|
||||
tmp = add_binary(TIMES, tmp, der);
|
||||
tmp = add_binary(TIMES, two_over_pi, tmp);
|
||||
res = add_unary(UMINUS, tmp);
|
||||
tmp = add_binary(code_t::TIMES, tmp, der);
|
||||
tmp = add_binary(code_t::TIMES, two_over_pi, tmp);
|
||||
res = add_unary(code_t::UMINUS, tmp);
|
||||
break;
|
||||
}
|
||||
case PLUS:
|
||||
case code_t::PLUS:
|
||||
{
|
||||
int tmp1 = add_derivative(terms[t].getOp1(), v);
|
||||
int tmp2 = add_derivative(terms[t].getOp2(), v);
|
||||
res = add_binary(PLUS, tmp1, tmp2);
|
||||
res = add_binary(code_t::PLUS, tmp1, tmp2);
|
||||
break;
|
||||
}
|
||||
case MINUS:
|
||||
case code_t::MINUS:
|
||||
{
|
||||
int tmp1 = add_derivative(terms[t].getOp1(), v);
|
||||
int tmp2 = add_derivative(terms[t].getOp2(), v);
|
||||
res = add_binary(MINUS, tmp1, tmp2);
|
||||
res = add_binary(code_t::MINUS, tmp1, tmp2);
|
||||
break;
|
||||
}
|
||||
case TIMES:
|
||||
case code_t::TIMES:
|
||||
{
|
||||
int tmp1 = add_derivative(terms[t].getOp1(), v);
|
||||
int tmp2 = add_derivative(terms[t].getOp2(), v);
|
||||
int res1 = add_binary(TIMES, terms[t].getOp1(), tmp2);
|
||||
int res2 = add_binary(TIMES, tmp1, terms[t].getOp2());
|
||||
res = add_binary(PLUS, res1, res2);
|
||||
int res1 = add_binary(code_t::TIMES, terms[t].getOp1(), tmp2);
|
||||
int res2 = add_binary(code_t::TIMES, tmp1, terms[t].getOp2());
|
||||
res = add_binary(code_t::PLUS, res1, res2);
|
||||
break;
|
||||
}
|
||||
case DIVIDE:
|
||||
case code_t::DIVIDE:
|
||||
{
|
||||
int tmp1 = add_derivative(terms[t].getOp1(), v);
|
||||
int tmp2 = add_derivative(terms[t].getOp2(), v);
|
||||
if (tmp2 == zero)
|
||||
res = add_binary(DIVIDE, tmp1, terms[t].getOp2());
|
||||
res = add_binary(code_t::DIVIDE, tmp1, terms[t].getOp2());
|
||||
else
|
||||
{
|
||||
int nom = add_binary(MINUS,
|
||||
add_binary(TIMES, tmp1, terms[t].getOp2()),
|
||||
add_binary(TIMES, tmp2, terms[t].getOp1()));
|
||||
int den = add_binary(TIMES, terms[t].getOp2(), terms[t].getOp2());
|
||||
res = add_binary(DIVIDE, nom, den);
|
||||
int nom = add_binary(code_t::MINUS,
|
||||
add_binary(code_t::TIMES, tmp1, terms[t].getOp2()),
|
||||
add_binary(code_t::TIMES, tmp2, terms[t].getOp1()));
|
||||
int den = add_binary(code_t::TIMES, terms[t].getOp2(), terms[t].getOp2());
|
||||
res = add_binary(code_t::DIVIDE, nom, den);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case POWER:
|
||||
case code_t::POWER:
|
||||
{
|
||||
int tmp1 = add_derivative(terms[t].getOp1(), v);
|
||||
int tmp2 = add_derivative(terms[t].getOp2(), v);
|
||||
int s1 = add_binary(TIMES, tmp2,
|
||||
add_binary(TIMES, t,
|
||||
add_unary(LOG, terms[t].getOp1())));
|
||||
int s2 = add_binary(TIMES, tmp1,
|
||||
add_binary(TIMES, terms[t].getOp2(),
|
||||
add_binary(POWER, terms[t].getOp1(),
|
||||
add_binary(MINUS, terms[t].getOp2(), one))));
|
||||
res = add_binary(PLUS, s1, s2);
|
||||
int s1 = add_binary(code_t::TIMES, tmp2,
|
||||
add_binary(code_t::TIMES, t,
|
||||
add_unary(code_t::LOG, terms[t].getOp1())));
|
||||
int s2 = add_binary(code_t::TIMES, tmp1,
|
||||
add_binary(code_t::TIMES, terms[t].getOp2(),
|
||||
add_binary(code_t::POWER, terms[t].getOp1(),
|
||||
add_binary(code_t::MINUS, terms[t].getOp2(), one))));
|
||||
res = add_binary(code_t::PLUS, s1, s2);
|
||||
break;
|
||||
}
|
||||
case NONE:
|
||||
case code_t::NONE:
|
||||
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
|
||||
auto it = subst.find(t);
|
||||
if (subst.end() != it)
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
|
||||
int nary = otree.terms[t].nary();
|
||||
if (nary == 2)
|
||||
|
@ -391,7 +382,7 @@ void
|
|||
OperationTree::register_derivative(int t, int v, int tder)
|
||||
{
|
||||
// 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>
|
||||
|
@ -416,9 +407,7 @@ OperationTree::select_terms(int t, const opselector &sel, unordered_set<int> &su
|
|||
select_terms(op.getOp2(), sel, subterms);
|
||||
}
|
||||
else if (op.nary() == 1)
|
||||
{
|
||||
select_terms(op.getOp1(), sel, subterms);
|
||||
}
|
||||
select_terms(op.getOp1(), sel, subterms);
|
||||
}
|
||||
|
||||
unordered_set<int>
|
||||
|
@ -473,23 +462,23 @@ OperationTree::forget_derivative_maps()
|
|||
}
|
||||
|
||||
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
|
||||
OperationTree::print_operation(int t) const
|
||||
{
|
||||
DefaultOperationFormatter dof(*this);
|
||||
print_operation_tree(t, stdout, dof);
|
||||
print_operation_tree(t, std::cout, dof);
|
||||
}
|
||||
|
||||
void
|
||||
OperationTree::update_nul_incidence_after_nularify(int t)
|
||||
{
|
||||
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];
|
||||
if (op.nary() == 2)
|
||||
|
@ -535,12 +524,12 @@ OperationTree::update_nul_incidence_after_nularify(int t)
|
|||
|
||||
EvalTree::EvalTree(const OperationTree &ot, int last)
|
||||
: otree(ot),
|
||||
values(new double[(last == -1) ? ot.terms.size() : last+1]),
|
||||
flags(new bool[(last == -1) ? ot.terms.size() : last+1]),
|
||||
values(std::make_unique<double[]>((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)
|
||||
{
|
||||
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__,
|
||||
"Wrong last in EvalTree constructor.");
|
||||
|
||||
|
@ -594,23 +583,23 @@ EvalTree::eval(int t)
|
|||
{
|
||||
double r1 = eval(op.getOp1());
|
||||
double res;
|
||||
if (op.getCode() == UMINUS)
|
||||
if (op.getCode() == code_t::UMINUS)
|
||||
res = -r1;
|
||||
else if (op.getCode() == LOG)
|
||||
else if (op.getCode() == code_t::LOG)
|
||||
res = log(r1);
|
||||
else if (op.getCode() == EXP)
|
||||
else if (op.getCode() == code_t::EXP)
|
||||
res = exp(r1);
|
||||
else if (op.getCode() == SIN)
|
||||
else if (op.getCode() == code_t::SIN)
|
||||
res = sin(r1);
|
||||
else if (op.getCode() == COS)
|
||||
else if (op.getCode() == code_t::COS)
|
||||
res = cos(r1);
|
||||
else if (op.getCode() == TAN)
|
||||
else if (op.getCode() == code_t::TAN)
|
||||
res = tan(r1);
|
||||
else if (op.getCode() == SQRT)
|
||||
else if (op.getCode() == code_t::SQRT)
|
||||
res = sqrt(r1);
|
||||
else if (op.getCode() == ERF)
|
||||
else if (op.getCode() == code_t::ERF)
|
||||
res = erf(r1);
|
||||
else if (op.getCode() == ERFC)
|
||||
else if (op.getCode() == code_t::ERFC)
|
||||
res = erfc(r1);
|
||||
else
|
||||
{
|
||||
|
@ -624,19 +613,19 @@ EvalTree::eval(int t)
|
|||
else if (op.nary() == 2)
|
||||
{
|
||||
double res;
|
||||
if (op.getCode() == PLUS)
|
||||
if (op.getCode() == code_t::PLUS)
|
||||
{
|
||||
double r1 = eval(op.getOp1());
|
||||
double r2 = eval(op.getOp2());
|
||||
res = r1 + r2;
|
||||
}
|
||||
else if (op.getCode() == MINUS)
|
||||
else if (op.getCode() == code_t::MINUS)
|
||||
{
|
||||
double r1 = eval(op.getOp1());
|
||||
double r2 = eval(op.getOp2());
|
||||
res = r1 - r2;
|
||||
}
|
||||
else if (op.getCode() == TIMES)
|
||||
else if (op.getCode() == code_t::TIMES)
|
||||
{
|
||||
// pickup less complex formula first
|
||||
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());
|
||||
if (r1 == 0)
|
||||
|
@ -675,7 +664,7 @@ EvalTree::eval(int t)
|
|||
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
|
||||
double r2 = eval(op.getOp2());
|
||||
|
@ -729,7 +718,7 @@ EvalTree::print() const
|
|||
}
|
||||
|
||||
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
|
||||
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();
|
||||
const Operation &op2 = otree.terms[t2];
|
||||
if (op1.nary() > 0)
|
||||
format(op1, t1, fd);
|
||||
format(op1, t1, os);
|
||||
if (op2.nary() > 0)
|
||||
format(op2, t2, fd);
|
||||
format(op2, t2, os);
|
||||
}
|
||||
if (op.nary() == 1)
|
||||
{
|
||||
int t1 = op.getOp1();
|
||||
const Operation &op1 = otree.terms[t1];
|
||||
if (op1.nary() > 0)
|
||||
format(op1, t1, fd);
|
||||
format(op1, t1, os);
|
||||
}
|
||||
|
||||
// print 'term ='
|
||||
format_term(t, fd);
|
||||
fprintf(fd, " = ");
|
||||
format_term(t, os);
|
||||
os << " = ";
|
||||
if (op.nary() == 0)
|
||||
{
|
||||
format_nulary(t, fd);
|
||||
}
|
||||
format_nulary(t, os);
|
||||
else if (op.nary() == 1)
|
||||
{
|
||||
int t1 = op.getOp1();
|
||||
const Operation &op1 = otree.terms[t1];
|
||||
const char *opname = "unknown";
|
||||
std::string opname = "unknown";
|
||||
switch (op.getCode())
|
||||
{
|
||||
case UMINUS:
|
||||
case code_t::UMINUS:
|
||||
opname = "-";
|
||||
break;
|
||||
case LOG:
|
||||
case code_t::LOG:
|
||||
opname = "log";
|
||||
break;
|
||||
case EXP:
|
||||
case code_t::EXP:
|
||||
opname = "exp";
|
||||
break;
|
||||
case SIN:
|
||||
case code_t::SIN:
|
||||
opname = "sin";
|
||||
break;
|
||||
case COS:
|
||||
case code_t::COS:
|
||||
opname = "cos";
|
||||
break;
|
||||
case TAN:
|
||||
case code_t::TAN:
|
||||
opname = "tan";
|
||||
break;
|
||||
case SQRT:
|
||||
case code_t::SQRT:
|
||||
opname = "sqrt";
|
||||
break;
|
||||
case ERF:
|
||||
case code_t::ERF:
|
||||
opname = "erf";
|
||||
break;
|
||||
case ERFC:
|
||||
case code_t::ERFC:
|
||||
opname = "erfc";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fprintf(fd, "%s(", opname);
|
||||
os << opname << '(';
|
||||
if (op1.nary() == 0)
|
||||
format_nulary(t1, fd);
|
||||
format_nulary(t1, os);
|
||||
else
|
||||
format_term(t1, fd);
|
||||
fprintf(fd, ")");
|
||||
format_term(t1, os);
|
||||
os << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -814,65 +801,64 @@ DefaultOperationFormatter::format(const Operation &op, int t, FILE *fd)
|
|||
const Operation &op1 = otree.terms[t1];
|
||||
int t2 = op.getOp2();
|
||||
const Operation &op2 = otree.terms[t2];
|
||||
const char *opname = "unknown";
|
||||
std::string opname = "unknown";
|
||||
switch (op.getCode())
|
||||
{
|
||||
case PLUS:
|
||||
case code_t::PLUS:
|
||||
opname = "+";
|
||||
break;
|
||||
case MINUS:
|
||||
case code_t::MINUS:
|
||||
opname = "-";
|
||||
break;
|
||||
case TIMES:
|
||||
case code_t::TIMES:
|
||||
opname = "*";
|
||||
break;
|
||||
case DIVIDE:
|
||||
case code_t::DIVIDE:
|
||||
opname = "/";
|
||||
break;
|
||||
case POWER:
|
||||
case code_t::POWER:
|
||||
opname = "^";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (op1.nary() == 0)
|
||||
format_nulary(t1, fd);
|
||||
format_nulary(t1, os);
|
||||
else
|
||||
format_term(t1, fd);
|
||||
fprintf(fd, " %s ", opname);
|
||||
format_term(t1, os);
|
||||
os << ' ' << opname << ' ';
|
||||
if (op2.nary() == 0)
|
||||
format_nulary(t2, fd);
|
||||
format_nulary(t2, os);
|
||||
else
|
||||
format_term(t2, fd);
|
||||
format_term(t2, os);
|
||||
}
|
||||
|
||||
print_delim(fd);
|
||||
|
||||
print_delim(os);
|
||||
}
|
||||
|
||||
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
|
||||
DefaultOperationFormatter::format_nulary(int t, FILE *fd) const
|
||||
DefaultOperationFormatter::format_nulary(int t, std::ostream &os) const
|
||||
{
|
||||
if (t == OperationTree::zero)
|
||||
fprintf(fd, "0");
|
||||
os << '0';
|
||||
else if (t == OperationTree::one)
|
||||
fprintf(fd, "1");
|
||||
os << '1';
|
||||
else if (t == OperationTree::nan)
|
||||
fprintf(fd, "NaN");
|
||||
os << "NaN";
|
||||
else
|
||||
fprintf(fd, "$%d", t);
|
||||
os << '$' << t;
|
||||
}
|
||||
|
||||
void
|
||||
DefaultOperationFormatter::print_delim(FILE *fd) const
|
||||
DefaultOperationFormatter::print_delim(std::ostream &os) const
|
||||
{
|
||||
fprintf(fd, ";\n");
|
||||
os << ";\n";
|
||||
}
|
||||
|
||||
std::string
|
||||
|
@ -907,31 +893,31 @@ OperationStringConvertor::convert(const Operation &op, int t) const
|
|||
const char *opname = "unknown";
|
||||
switch (op.getCode())
|
||||
{
|
||||
case UMINUS:
|
||||
case code_t::UMINUS:
|
||||
opname = "-";
|
||||
break;
|
||||
case LOG:
|
||||
case code_t::LOG:
|
||||
opname = "log";
|
||||
break;
|
||||
case EXP:
|
||||
case code_t::EXP:
|
||||
opname = "exp";
|
||||
break;
|
||||
case SIN:
|
||||
case code_t::SIN:
|
||||
opname = "sin";
|
||||
break;
|
||||
case COS:
|
||||
case code_t::COS:
|
||||
opname = "cos";
|
||||
break;
|
||||
case TAN:
|
||||
case code_t::TAN:
|
||||
opname = "tan";
|
||||
break;
|
||||
case SQRT:
|
||||
case code_t::SQRT:
|
||||
opname = "sqrt";
|
||||
break;
|
||||
case ERF:
|
||||
case code_t::ERF:
|
||||
opname = "erf";
|
||||
break;
|
||||
case ERFC:
|
||||
case code_t::ERFC:
|
||||
opname = "erfc";
|
||||
break;
|
||||
default:
|
||||
|
@ -949,19 +935,19 @@ OperationStringConvertor::convert(const Operation &op, int t) const
|
|||
const char *opname = "unknown";
|
||||
switch (op.getCode())
|
||||
{
|
||||
case PLUS:
|
||||
case code_t::PLUS:
|
||||
opname = "+";
|
||||
break;
|
||||
case MINUS:
|
||||
case code_t::MINUS:
|
||||
opname = "-";
|
||||
break;
|
||||
case TIMES:
|
||||
case code_t::TIMES:
|
||||
opname = "*";
|
||||
break;
|
||||
case DIVIDE:
|
||||
case code_t::DIVIDE:
|
||||
opname = "/";
|
||||
break;
|
||||
case POWER:
|
||||
case code_t::POWER:
|
||||
opname = "^";
|
||||
break;
|
||||
default:
|
||||
|
@ -970,15 +956,15 @@ OperationStringConvertor::convert(const Operation &op, int t) const
|
|||
// decide about parenthesis
|
||||
bool op1_par = true;
|
||||
bool op2_par = true;
|
||||
if (op.getCode() == PLUS)
|
||||
if (op.getCode() == code_t::PLUS)
|
||||
{
|
||||
op1_par = false;
|
||||
op2_par = false;
|
||||
}
|
||||
else if (op.getCode() == MINUS)
|
||||
else if (op.getCode() == code_t::MINUS)
|
||||
{
|
||||
op1_par = false;
|
||||
if (op2.getCode() != MINUS && op2.getCode() != PLUS)
|
||||
if (op2.getCode() != code_t::MINUS && op2.getCode() != code_t::PLUS)
|
||||
op2_par = false;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <cstdio>
|
||||
#include <ostream>
|
||||
#include <memory>
|
||||
|
||||
namespace ogp
|
||||
{
|
||||
|
||||
using std::unordered_set;
|
||||
using std::unordered_map;
|
||||
using std::vector;
|
||||
|
@ -24,15 +24,15 @@ namespace ogp
|
|||
* codes, he should update the code of #OperationTree::add_unary,
|
||||
* #OperationTree::add_binary, and of course
|
||||
* #OperationTree::add_derivative. */
|
||||
enum code_t {NONE, UMINUS, LOG, EXP, SIN, COS, TAN, SQRT, ERF,
|
||||
ERFC, PLUS, MINUS, TIMES, DIVIDE, POWER};
|
||||
enum class code_t {NONE, UMINUS, LOG, EXP, SIN, COS, TAN, SQRT, ERF,
|
||||
ERFC, PLUS, MINUS, TIMES, DIVIDE, POWER};
|
||||
|
||||
/** Class representing a nulary, unary, or binary operation. */
|
||||
class Operation
|
||||
{
|
||||
protected:
|
||||
/** Code of the operation. */
|
||||
code_t code{NONE};
|
||||
code_t code{code_t::NONE};
|
||||
/** First operand. If none, then it is -1. */
|
||||
int op1{-1};
|
||||
/** Second operand. If none, then it is -1. */
|
||||
|
@ -50,18 +50,12 @@ namespace ogp
|
|||
{
|
||||
}
|
||||
/** Constructs a nulary operation. */
|
||||
Operation()
|
||||
|
||||
= default;
|
||||
Operation() = default;
|
||||
/** A copy constructor. */
|
||||
Operation(const Operation &op)
|
||||
|
||||
= default;
|
||||
Operation(const Operation &op) = default;
|
||||
|
||||
/** Operator =. */
|
||||
Operation &
|
||||
operator=(const Operation &op)
|
||||
= default;
|
||||
Operation &operator=(const Operation &op) = default;
|
||||
/** Operator ==. */
|
||||
bool
|
||||
operator==(const Operation &op) const
|
||||
|
@ -86,7 +80,7 @@ namespace ogp
|
|||
size_t
|
||||
hashval() const
|
||||
{
|
||||
return op2+1 + (op1+1)^15 + code^30;
|
||||
return op2+1 + (op1+1)^15 + static_cast<int>(code)^30;
|
||||
}
|
||||
|
||||
code_t
|
||||
|
@ -104,7 +98,6 @@ namespace ogp
|
|||
{
|
||||
return op2;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** This struct is a predicate for ordering of the operations in
|
||||
|
@ -133,8 +126,7 @@ namespace ogp
|
|||
struct opselector
|
||||
{
|
||||
virtual bool operator()(int t) const = 0;
|
||||
virtual ~opselector()
|
||||
= default;
|
||||
virtual ~opselector() = default;
|
||||
};
|
||||
|
||||
/** Forward declaration of OperationFormatter. */
|
||||
|
@ -182,7 +174,6 @@ namespace ogp
|
|||
/** This defines a type for a map mapping the unary and binary
|
||||
* operations to their indices. */
|
||||
using _Topmap = unordered_map<Operation, int, ophash>;
|
||||
using _Topval = _Topmap::value_type;
|
||||
|
||||
/** This is the map mapping the unary and binary operations to
|
||||
* the indices of the terms.*/
|
||||
|
@ -205,25 +196,18 @@ namespace ogp
|
|||
/** The tree index of the last nulary term. */
|
||||
int last_nulary;
|
||||
public:
|
||||
/** This is a number of constants set in the following
|
||||
* enum. This number reserves space in a vector of terms for
|
||||
* the constants. */
|
||||
static const int num_constants = 4;
|
||||
/** Enumeration for special terms. We need zero, one, nan and
|
||||
* 2/pi. These will be always first four terms having indices
|
||||
* zero, one and two, three. If adding anything to this
|
||||
* enumeration, make sure you have updated num_constants above.*/
|
||||
enum {zero = 0, one = 1, nan = 2, two_over_pi = 3};
|
||||
* enumeration, make sure ‘num_constants’ remains the last one.*/
|
||||
enum {zero, one, nan, two_over_pi, num_constants};
|
||||
|
||||
/** The unique constructor which initializes the object to
|
||||
* contain only zero, one and nan and two_over_pi.*/
|
||||
OperationTree();
|
||||
|
||||
/** Copy constructor. */
|
||||
OperationTree(const OperationTree &ot)
|
||||
|
||||
|
||||
= default;
|
||||
OperationTree(const OperationTree &ot) = default;
|
||||
|
||||
/** Add a nulary operation. The caller is responsible for not
|
||||
* inserting two semantically equivalent nulary operations.
|
||||
|
@ -323,7 +307,7 @@ namespace ogp
|
|||
|
||||
/** This outputs the operation to the given file descriptor
|
||||
* 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: */
|
||||
void print_operation(int t) const;
|
||||
|
@ -339,7 +323,7 @@ namespace ogp
|
|||
int
|
||||
get_num_op() const
|
||||
{
|
||||
return (int) (terms.size());
|
||||
return static_cast<int>(terms.size());
|
||||
}
|
||||
private:
|
||||
/** This registers a calculated derivative of the term in the
|
||||
|
@ -391,9 +375,9 @@ namespace ogp
|
|||
* are done. */
|
||||
const OperationTree &otree;
|
||||
/** The array of values. */
|
||||
double *const values;
|
||||
const std::unique_ptr<double[]> values;
|
||||
/** The array of evaluation flags. */
|
||||
bool *const flags;
|
||||
const std::unique_ptr<bool[]> flags;
|
||||
/** The index of last operation in the EvalTree. Length of
|
||||
* values and flags will be then last_operation+1. */
|
||||
int last_operation;
|
||||
|
@ -404,10 +388,7 @@ namespace ogp
|
|||
* (included). */
|
||||
EvalTree(const OperationTree &otree, int last = -1);
|
||||
EvalTree(const EvalTree &) = delete;
|
||||
virtual ~EvalTree()
|
||||
{
|
||||
delete [] values; delete [] flags;
|
||||
}
|
||||
virtual ~EvalTree() = default;
|
||||
/** Set evaluation flag to all terms (besides the first
|
||||
* special terms) to false. */
|
||||
void reset_all();
|
||||
|
@ -431,8 +412,7 @@ namespace ogp
|
|||
{
|
||||
public:
|
||||
/** Empty virtual destructor. */
|
||||
virtual ~OperationFormatter()
|
||||
= default;
|
||||
virtual ~OperationFormatter() = default;
|
||||
/** Print the formatted operation op with a given tree index t
|
||||
* to a given descriptor. (See class OperationTree to know
|
||||
* what is a tree index.) This prints all the tree. This
|
||||
|
@ -441,7 +421,7 @@ namespace ogp
|
|||
* term, the right hand side is a string representation of the
|
||||
* operation (which will refer to other string representation
|
||||
* of subterms). */
|
||||
virtual void format(const Operation &op, int t, FILE *fd) = 0;
|
||||
virtual void format(const Operation &op, int t, std::ostream &os) = 0;
|
||||
};
|
||||
|
||||
/** The default formatter formats the formulas with a usual syntax
|
||||
|
@ -460,23 +440,22 @@ namespace ogp
|
|||
{
|
||||
}
|
||||
/** 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
|
||||
* example 'tmp10' for term 10. In this implementation it
|
||||
* 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. */
|
||||
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
|
||||
* "\n". */
|
||||
virtual void print_delim(FILE *fd) const;
|
||||
virtual void print_delim(std::ostream &os) const;
|
||||
};
|
||||
|
||||
class NularyStringConvertor
|
||||
{
|
||||
public:
|
||||
virtual ~NularyStringConvertor()
|
||||
= default;
|
||||
virtual ~NularyStringConvertor() = default;
|
||||
/** Return the string representation of the atom with the tree
|
||||
* index t. */
|
||||
virtual std::string convert(int t) const = 0;
|
||||
|
@ -494,8 +473,7 @@ namespace ogp
|
|||
{
|
||||
}
|
||||
/** Empty virtual destructor. */
|
||||
virtual ~OperationStringConvertor()
|
||||
= default;
|
||||
virtual ~OperationStringConvertor() = default;
|
||||
/** Convert the operation to the string mathematical
|
||||
* representation. This does not write any equation, just
|
||||
* returns a string representation of the formula. */
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
#include <cmath>
|
||||
#include <climits>
|
||||
#include <ostream>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace ogdyn;
|
||||
|
||||
|
@ -117,7 +120,7 @@ DynareModel::print() const
|
|||
{
|
||||
int tf = eqs.formula(i);
|
||||
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
|
||||
DynareParser::parse_glob(int length, const char *stream)
|
||||
{
|
||||
auto *buffer = new char[length+2];
|
||||
strncpy(buffer, stream, length);
|
||||
auto buffer = std::make_unique<char[]>(length+2);
|
||||
std::copy_n(stream, length, buffer.get());
|
||||
buffer[length] = '\0';
|
||||
buffer[length+1] = '\0';
|
||||
void *p = dynglob__scan_buffer(buffer, (unsigned int) length+2);
|
||||
void *p = dynglob__scan_buffer(buffer.get(), static_cast<unsigned int>(length)+2);
|
||||
dynare_parser = this;
|
||||
dynglob_parse();
|
||||
delete [] buffer;
|
||||
dynglob__destroy_buffer(p);
|
||||
}
|
||||
|
||||
int
|
||||
DynareParser::parse_order(int len, const char *str)
|
||||
{
|
||||
auto *buf = new char[len+1];
|
||||
strncpy(buf, str, len);
|
||||
auto buf = std::make_unique<char[]>(len+1);
|
||||
std::copy_n(str, len, buf.get());
|
||||
buf[len] = '\0';
|
||||
int res;
|
||||
sscanf(buf, "%d", &res);
|
||||
delete [] buf;
|
||||
sscanf(buf.get(), "%d", &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
DynareParser::parse_pldiscount(int len, const char *str)
|
||||
{
|
||||
auto *buf = new char[len+1];
|
||||
strncpy(buf, str, len);
|
||||
auto buf = std::make_unique<char[]>(len+1);
|
||||
std::copy_n(str, len, buf.get());
|
||||
buf[len] = '\0';
|
||||
if (!atoms.is_type(buf, DynareDynamicAtoms::param))
|
||||
throw ogp::ParserException(std::string("Name ") + buf + " is not a parameter", 0);
|
||||
if (!atoms.is_type(buf.get(), DynareDynamicAtoms::param))
|
||||
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)
|
||||
t = eqs.add_nulary(buf);
|
||||
t = eqs.add_nulary(buf.get());
|
||||
|
||||
delete [] buf;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -712,14 +712,14 @@ NLSelector::operator()(int t) const
|
|||
}
|
||||
else if (nary == 1)
|
||||
{
|
||||
if (op.getCode() == ogp::UMINUS)
|
||||
if (op.getCode() == ogp::code_t::UMINUS)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
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 (model.is_constant_term(op.getOp1())
|
||||
|| model.is_constant_term(op.getOp2()))
|
||||
|
@ -727,11 +727,11 @@ NLSelector::operator()(int t) const
|
|||
else
|
||||
return true;
|
||||
// both PLUS and MINUS are linear
|
||||
if (op.getCode() == ogp::PLUS
|
||||
|| op.getCode() == ogp::MINUS)
|
||||
if (op.getCode() == ogp::code_t::PLUS
|
||||
|| op.getCode() == ogp::code_t::MINUS)
|
||||
return false;
|
||||
// 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::one
|
||||
|| op.getOp2() == ogp::OperationTree::zero
|
||||
|
@ -741,7 +741,7 @@ NLSelector::operator()(int t) const
|
|||
return true;
|
||||
// DIVIDE is linear if the denominator is constant, or if
|
||||
// the nominator is zero
|
||||
if (op.getCode() == ogp::DIVIDE
|
||||
if (op.getCode() == ogp::code_t::DIVIDE
|
||||
&& (op.getOp1() == ogp::OperationTree::zero
|
||||
|| model.is_constant_term(op.getOp2())))
|
||||
return false;
|
||||
|
@ -792,23 +792,23 @@ DynareSPModel::DynareSPModel(const char **endo, int num_endo,
|
|||
}
|
||||
|
||||
void
|
||||
ModelSSWriter::write_der0(FILE *fd)
|
||||
ModelSSWriter::write_der0(std::ostream &os)
|
||||
{
|
||||
write_der0_preamble(fd);
|
||||
write_atom_assignment(fd);
|
||||
write_der0_preamble(os);
|
||||
write_atom_assignment(os);
|
||||
|
||||
stop_set.clear();
|
||||
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
|
||||
ModelSSWriter::write_der1(FILE *fd)
|
||||
ModelSSWriter::write_der1(std::ostream &os)
|
||||
{
|
||||
write_der1_preamble(fd);
|
||||
write_atom_assignment(fd);
|
||||
write_der1_preamble(os);
|
||||
write_atom_assignment(os);
|
||||
|
||||
stop_set.clear();
|
||||
|
||||
|
@ -821,11 +821,11 @@ ModelSSWriter::write_der1(FILE *fd)
|
|||
{
|
||||
int t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, j));
|
||||
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)
|
||||
|
@ -835,115 +835,102 @@ MatlabSSWriter::MatlabSSWriter(const DynareModel &dm, const char *idd)
|
|||
}
|
||||
|
||||
void
|
||||
MatlabSSWriter::write_der0_preamble(FILE *fd) const
|
||||
MatlabSSWriter::write_der0_preamble(std::ostream &os) const
|
||||
{
|
||||
fprintf(fd,
|
||||
"%% Usage:\n"
|
||||
"%% out = %s_f(params, y)\n"
|
||||
"%% where\n"
|
||||
"%% out is a (%d,1) column vector of the residuals\n"
|
||||
"%% of the static system\n",
|
||||
id, model.getAtoms().ny());
|
||||
write_common1_preamble(fd);
|
||||
fprintf(fd,
|
||||
"function out = %s_f(params, y)\n", id);
|
||||
write_common2_preamble(fd);
|
||||
os << "% Usage:\n"
|
||||
<< "% out = " << id << "_f(params, y)\n"
|
||||
<< "% where\n"
|
||||
<< "% out is a (" << model.getAtoms().ny() << ",1) column vector of the residuals\n"
|
||||
<< "% of the static system\n";
|
||||
write_common1_preamble(os);
|
||||
os << "function out = " << id << "_f(params, y)\n";
|
||||
write_common2_preamble(os);
|
||||
}
|
||||
|
||||
void
|
||||
MatlabSSWriter::write_der1_preamble(FILE *fd) const
|
||||
MatlabSSWriter::write_der1_preamble(std::ostream &os) const
|
||||
{
|
||||
fprintf(fd,
|
||||
"%% Usage:\n"
|
||||
"%% out = %s_ff(params, y)\n"
|
||||
"%% where\n"
|
||||
"%% out is a (%d,%d) matrix of the first order\n"
|
||||
"%% derivatives of the static system residuals\n"
|
||||
"%% columns correspond to endo variables in\n"
|
||||
"%% the ordering as declared\n",
|
||||
id, model.getAtoms().ny(), model.getAtoms().ny());
|
||||
write_common1_preamble(fd);
|
||||
fprintf(fd,
|
||||
"function out = %s_ff(params, y)\n", id);
|
||||
write_common2_preamble(fd);
|
||||
os << "% Usage:\n"
|
||||
<< "% out = " << id << "_ff(params, y)\n"
|
||||
<< "% where\n"
|
||||
<< "% out is a (" << model.getAtoms().ny() << "," << model.getAtoms().ny() << ") matrix of the first order\n"
|
||||
<< "% derivatives of the static system residuals\n"
|
||||
<< "% columns correspond to endo variables in\n"
|
||||
<< "% the ordering as declared\n";
|
||||
write_common1_preamble(os);
|
||||
os << "function out = " << id << "_ff(params, y)\n";
|
||||
write_common2_preamble(os);
|
||||
}
|
||||
|
||||
void
|
||||
MatlabSSWriter::write_common1_preamble(FILE *fd) const
|
||||
MatlabSSWriter::write_common1_preamble(std::ostream &os) const
|
||||
{
|
||||
fprintf(fd,
|
||||
"%% params is a (%d,1) vector of parameter values\n"
|
||||
"%% in the ordering as declared\n"
|
||||
"%% y is a (%d,1) vector of endogenous variables\n"
|
||||
"%% in the ordering as declared\n"
|
||||
"%%\n"
|
||||
"%% Created by Dynare++ v. %s\n", model.getAtoms().np(),
|
||||
model.getAtoms().ny(), DYNVERSION);
|
||||
os << "% params is a (" << model.getAtoms().np() << ",1) vector of parameter values\n"
|
||||
<< "% in the ordering as declared\n"
|
||||
<< "% y is a (" << model.getAtoms().ny() << ",1) vector of endogenous variables\n"
|
||||
<< "% in the ordering as declared\n"
|
||||
<< "%\n"
|
||||
<< "% Created by Dynare++ v. " << DYNVERSION << "\n";
|
||||
// write ordering of parameters
|
||||
fprintf(fd, "\n%% params ordering\n%% =====================\n");
|
||||
os << "\n% params ordering\n% =====================\n";
|
||||
for (auto parname : model.getAtoms().get_params())
|
||||
{
|
||||
fprintf(fd, "%% %s\n", parname);
|
||||
}
|
||||
os << "% " << parname << "\n";
|
||||
|
||||
// write endogenous variables
|
||||
fprintf(fd, "%%\n%% y ordering\n%% =====================\n");
|
||||
os << "%\n% y ordering\n% =====================\n";
|
||||
for (auto endoname : model.getAtoms().get_endovars())
|
||||
{
|
||||
fprintf(fd, "%% %s\n", endoname);
|
||||
}
|
||||
fprintf(fd, "\n");
|
||||
os << "% " << endoname << "\n";
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
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",
|
||||
model.getAtoms().ny(), model.getAtoms().ny());
|
||||
fprintf(fd, "if size(params) ~= [%d,1]\n\terror('Wrong size of params, must be [%d,1]');\nend\n\n",
|
||||
model.getAtoms().np(), model.getAtoms().np());
|
||||
os << "if size(y) ~= [" << model.getAtoms().ny() << ",1]\n"
|
||||
<< "\terror('Wrong size of y, must be [" << model.getAtoms().ny() << ",1]');\nend\n"
|
||||
<< "if size(params) ~= [" << model.getAtoms().np() << ",1]\n"
|
||||
<< "\terror('Wrong size of params, must be [" << model.getAtoms().np() << ",1]');\nend\n\n";
|
||||
}
|
||||
|
||||
void
|
||||
MatlabSSWriter::write_atom_assignment(FILE *fd) const
|
||||
MatlabSSWriter::write_atom_assignment(std::ostream &os) const
|
||||
{
|
||||
// write OperationTree::num_constants
|
||||
fprintf(fd, "%% hardwired constants\n");
|
||||
os << "% hardwired constants\n";
|
||||
ogp::EvalTree etree(model.getParser().getTree(), ogp::OperationTree::num_constants-1);
|
||||
for (int i = 0; i < ogp::OperationTree::num_constants; i++)
|
||||
{
|
||||
format_nulary(i, fd);
|
||||
format_nulary(i, os);
|
||||
double g = etree.eval(i);
|
||||
if (std::isnan(g))
|
||||
fprintf(fd, " = NaN;\n");
|
||||
os << " = NaN;\n";
|
||||
else
|
||||
fprintf(fd, " = %12.8g;\n", etree.eval(i));
|
||||
os << " = " << std::defaultfloat << std::setprecision(8) << etree.eval(i) << ";\n";
|
||||
}
|
||||
// write numerical constants
|
||||
fprintf(fd, "%% numerical constants\n");
|
||||
os << "% numerical constants\n";
|
||||
const ogp::Constants::Tconstantmap &cmap = model.getAtoms().get_constantmap();
|
||||
for (auto it : cmap)
|
||||
{
|
||||
format_nulary(it.first, fd);
|
||||
fprintf(fd, " = %12.8g;\n", it.second);
|
||||
format_nulary(it.first, os);
|
||||
os << " = " << std::defaultfloat << std::setprecision(8) << it.second << ";\n";
|
||||
}
|
||||
// write parameters
|
||||
fprintf(fd, "%% parameter values\n");
|
||||
os << "% parameter values\n";
|
||||
for (unsigned int ip = 0; ip < model.getAtoms().get_params().size(); ip++)
|
||||
{
|
||||
const char *parname = model.getAtoms().get_params()[ip];
|
||||
int t = model.getAtoms().index(parname, 0);
|
||||
if (t == -1)
|
||||
{
|
||||
fprintf(fd, "%% %s not used in the model\n", parname);
|
||||
}
|
||||
os << "% " << parname << " not used in the model\n";
|
||||
else
|
||||
{
|
||||
format_nulary(t, fd);
|
||||
fprintf(fd, " = params(%d); %% %s\n", ip+1, parname);
|
||||
format_nulary(t, os);
|
||||
os << " = params(" << ip+1 << "); % " << parname << "\n";
|
||||
}
|
||||
}
|
||||
// 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++)
|
||||
{
|
||||
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);
|
||||
for (auto it : lmap)
|
||||
{
|
||||
format_nulary(it.second, fd);
|
||||
fprintf(fd, " = 0.0; %% %s\n", exoname);
|
||||
format_nulary(it.second, os);
|
||||
os << " = 0.0; % " << exoname << "\n";
|
||||
}
|
||||
}
|
||||
catch (const ogu::Exception &e)
|
||||
|
@ -962,43 +949,43 @@ MatlabSSWriter::write_atom_assignment(FILE *fd) const
|
|||
}
|
||||
}
|
||||
// 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++)
|
||||
{
|
||||
const char *endoname = model.getAtoms().get_endovars()[ie];
|
||||
const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(endoname);
|
||||
for (auto it : lmap)
|
||||
{
|
||||
format_nulary(it.second, fd);
|
||||
fprintf(fd, " = y(%d); %% %s\n", ie+1, endoname);
|
||||
format_nulary(it.second, os);
|
||||
os << " = y(" << ie+1 << "); % " << endoname << "\n";
|
||||
}
|
||||
}
|
||||
fprintf(fd, "\n");
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
void
|
||||
MatlabSSWriter::write_der0_assignment(FILE *fd) const
|
||||
MatlabSSWriter::write_der0_assignment(std::ostream &os) const
|
||||
{
|
||||
|
||||
// initialize out variable
|
||||
fprintf(fd, "%% setting the output variable\n");
|
||||
fprintf(fd, "out = zeros(%d, 1);\n", model.getParser().nformulas());
|
||||
os << "% setting the output variable\n"
|
||||
<< "out = zeros(" << model.getParser().nformulas() << ", 1);\n";
|
||||
|
||||
// fill out with the terms
|
||||
for (int i = 0; i < model.getParser().nformulas(); i++)
|
||||
{
|
||||
fprintf(fd, "out(%d) = ", i+1);
|
||||
format_term(model.getParser().formula(i), fd);
|
||||
fprintf(fd, ";\n");
|
||||
os << "out(" << i+1 << ") = ";
|
||||
format_term(model.getParser().formula(i), os);
|
||||
os << ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MatlabSSWriter::write_der1_assignment(FILE *fd) const
|
||||
MatlabSSWriter::write_der1_assignment(std::ostream &os) const
|
||||
{
|
||||
// initialize out variable
|
||||
fprintf(fd, "%% setting the output variable\n");
|
||||
fprintf(fd, "out = zeros(%d, %d);\n", model.getParser().nformulas(), model.getAtoms().ny());
|
||||
os << "% setting the output variable\n";
|
||||
os << "out = zeros(" << model.getParser().nformulas() << ", " << model.getAtoms().ny() << ");\n";
|
||||
|
||||
// fill out with the terms
|
||||
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));
|
||||
if (t != ogp::OperationTree::zero)
|
||||
{
|
||||
fprintf(fd, "out(%d,%d) = out(%d,%d) + ", i+1, yi+1, i+1, yi+1);
|
||||
format_term(t, fd);
|
||||
fprintf(fd, "; %% %s(%d)\n", name, model.getAtoms().lead(tvar));
|
||||
os << "out(" << i+1 << "," << yi+1 << ") = out("<< i+1 << "," << yi+1 << ") + ";
|
||||
format_term(t, os);
|
||||
os << "; % " << name << "(" << model.getAtoms().lead(tvar) << ")\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
DebugOperationFormatter::format_nulary(int t, FILE *fd) const
|
||||
DebugOperationFormatter::format_nulary(int t, std::ostream &os) const
|
||||
{
|
||||
const DynareDynamicAtoms &a = model.getAtoms();
|
||||
|
||||
if (t == ogp::OperationTree::zero)
|
||||
fprintf(fd, "0");
|
||||
os << '0';
|
||||
else if (t == ogp::OperationTree::one)
|
||||
fprintf(fd, "1");
|
||||
os << '1';
|
||||
else if (t == ogp::OperationTree::nan)
|
||||
fprintf(fd, "NaN");
|
||||
os << "NaN";
|
||||
else if (t == ogp::OperationTree::two_over_pi)
|
||||
fprintf(fd, "2/sqrt(PI)");
|
||||
os << "2/sqrt(PI)";
|
||||
else if (a.is_constant(t))
|
||||
fprintf(fd, "%g", a.get_constant_value(t));
|
||||
os << a.get_constant_value(t);
|
||||
else
|
||||
{
|
||||
int ll = a.lead(t);
|
||||
const char *name = a.name(t);
|
||||
std::string name{a.name(t)};
|
||||
if (ll == 0)
|
||||
fprintf(fd, "%s", name);
|
||||
os << name;
|
||||
else
|
||||
fprintf(fd, "%s(%d)", name, ll);
|
||||
os << name << '(' << ll << ')';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <map>
|
||||
#include <unordered_set>
|
||||
#include <ostream>
|
||||
|
||||
namespace ogdyn
|
||||
{
|
||||
|
@ -405,18 +406,18 @@ namespace ogdyn
|
|||
* virtual methods for writing a preamble, then assignment of
|
||||
* atoms, and then assignment for resulting object. These are
|
||||
* language dependent and are implemented in the subclass. */
|
||||
void write_der0(FILE *fd);
|
||||
void write_der0(std::ostream &os);
|
||||
/** This writes the evaluation of the first order derivative of
|
||||
the system. It calls pure virtual methods for writing a
|
||||
preamble, assignment, and assignemnt of the resulting
|
||||
objects. */
|
||||
void write_der1(FILE *fd);
|
||||
void write_der1(std::ostream &os);
|
||||
protected:
|
||||
virtual void write_der0_preamble(FILE *fd) const = 0;
|
||||
virtual void write_der1_preamble(FILE *fd) const = 0;
|
||||
virtual void write_atom_assignment(FILE *fd) const = 0;
|
||||
virtual void write_der0_assignment(FILE *fd) const = 0;
|
||||
virtual void write_der1_assignment(FILE *fd) const = 0;
|
||||
virtual void write_der0_preamble(std::ostream &os) const = 0;
|
||||
virtual void write_der1_preamble(std::ostream &os) const = 0;
|
||||
virtual void write_atom_assignment(std::ostream &os) const = 0;
|
||||
virtual void write_der0_assignment(std::ostream &os) const = 0;
|
||||
virtual void write_der1_assignment(std::ostream &os) const = 0;
|
||||
};
|
||||
|
||||
class MatlabSSWriter : public ModelSSWriter
|
||||
|
@ -432,24 +433,24 @@ namespace ogdyn
|
|||
}
|
||||
protected:
|
||||
// from ModelSSWriter
|
||||
void write_der0_preamble(FILE *fd) const override;
|
||||
void write_der1_preamble(FILE *fd) const override;
|
||||
void write_der0_preamble(std::ostream &os) const override;
|
||||
void write_der1_preamble(std::ostream &os) const override;
|
||||
/** This writes atom assignments. We have four kinds of atoms
|
||||
* set here: endogenous vars coming from one parameter,
|
||||
* parameter values given by the second parameter, constants,
|
||||
* and the OperationTree::num_constants hardwired constants in
|
||||
* ogp::OperationTree. */
|
||||
void write_atom_assignment(FILE *fd) const override;
|
||||
void write_der0_assignment(FILE *fd) const override;
|
||||
void write_der1_assignment(FILE *fd) const override;
|
||||
void write_atom_assignment(std::ostream &os) const override;
|
||||
void write_der0_assignment(std::ostream &os) const override;
|
||||
void write_der1_assignment(std::ostream &os) const override;
|
||||
/** 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
|
||||
* 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:
|
||||
void write_common1_preamble(FILE *fd) const;
|
||||
void write_common2_preamble(FILE *fd) const;
|
||||
void write_common1_preamble(std::ostream &os) const;
|
||||
void write_common2_preamble(std::ostream &os) const;
|
||||
};
|
||||
|
||||
/** This class implements OperationFormatter for debugging
|
||||
|
@ -465,7 +466,7 @@ namespace ogdyn
|
|||
model(m)
|
||||
{
|
||||
}
|
||||
void format_nulary(int t, FILE *fd) const override;
|
||||
void format_nulary(int t, std::ostream &os) const override;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ ForwSubstBuilder::substitute_for_term(int t, int i, int j)
|
|||
info.num_aux_variables++;
|
||||
const char *ss = model.atoms.get_name_storage().query(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));
|
||||
// now add variables and equations
|
||||
// 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);
|
||||
auxt = model.eqs.add_nulary(name);
|
||||
// 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
|
||||
// works well because in the context where
|
||||
// aux_map is used the timing doesn't matter,
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "../kord/global_check.hh"
|
||||
#include "../kord/approximation.hh"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
int
|
||||
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);
|
||||
|
||||
// write matlab files
|
||||
FILE *mfd;
|
||||
std::string mfile1(params.basename);
|
||||
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());
|
||||
exit(1);
|
||||
}
|
||||
ogdyn::MatlabSSWriter writer0(dynare.getModel(), params.basename.c_str());
|
||||
writer0.write_der0(mfd);
|
||||
fclose(mfd);
|
||||
mfd.close();
|
||||
|
||||
std::string mfile2(params.basename);
|
||||
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());
|
||||
exit(1);
|
||||
}
|
||||
ogdyn::MatlabSSWriter writer1(dynare.getModel(), params.basename.c_str());
|
||||
writer1.write_der1(mfd);
|
||||
fclose(mfd);
|
||||
mfd.close();
|
||||
|
||||
// open mat file
|
||||
std::string matfile(params.basename);
|
||||
|
@ -206,7 +209,7 @@ main(int argc, char **argv)
|
|||
}
|
||||
catch (const ogp::ParserException &e)
|
||||
{
|
||||
printf("Caught parser exception: %s\n", e.message());
|
||||
std::cout << "Caught parser exception: " << e.message() << std::endl;
|
||||
return 255;
|
||||
}
|
||||
|
||||
|
|
|
@ -188,11 +188,11 @@ PlannerBuilder::beta_multiply_b()
|
|||
{
|
||||
int beta_pow = ogp::OperationTree::one;
|
||||
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++)
|
||||
if (diff_b(yi, ll-minlag) != ogp::OperationTree::zero)
|
||||
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
|
||||
|
@ -200,21 +200,21 @@ PlannerBuilder::beta_multiply_f()
|
|||
{
|
||||
int beta_pow = ogp::OperationTree::one;
|
||||
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 fi = 0; fi < diff_f.dim2(); fi++)
|
||||
if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero)
|
||||
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;
|
||||
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 fi = 0; fi < diff_f.dim2(); fi++)
|
||||
if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero)
|
||||
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
|
||||
|
@ -271,7 +271,7 @@ PlannerBuilder::lagrange_mult_f()
|
|||
sprintf(mult_name, "MULT%d(%d)", fset[fi], -ll);
|
||||
int tm = model.eqs.add_nulary(mult_name);
|
||||
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;
|
||||
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 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);
|
||||
}
|
||||
|
||||
|
@ -295,7 +295,7 @@ PlannerBuilder::form_equations()
|
|||
it != aux_map.end(); ++it)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue