2019-04-16 11:40:38 +02:00
|
|
|
// Copyright © 2006, Ondra Kamenik
|
2019-01-08 17:12:05 +01:00
|
|
|
|
|
|
|
// $Id: dynare_atoms.cpp 1765 2008-03-31 14:32:08Z kamenik $
|
|
|
|
|
|
|
|
#include "parser/cc/parser_exception.hh"
|
|
|
|
#include "utils/cc/exception.hh"
|
|
|
|
|
|
|
|
#include "dynare_atoms.hh"
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
using namespace ogdyn;
|
|
|
|
using std::string;
|
|
|
|
|
|
|
|
void
|
|
|
|
DynareStaticAtoms::register_name(const char *name)
|
|
|
|
{
|
|
|
|
if (varnames.query(name))
|
|
|
|
throw ogp::ParserException(string("The name ")+name+" is not unique.", 0);
|
|
|
|
StaticAtoms::register_name(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
DynareStaticAtoms::check_variable(const char *name) const
|
|
|
|
{
|
2019-01-09 16:25:31 +01:00
|
|
|
if (nullptr == varnames.query(name))
|
2019-01-08 17:12:05 +01:00
|
|
|
throw ogp::ParserException(std::string("Unknown name <")+name+">", 0);
|
2019-01-09 15:51:19 +01:00
|
|
|
auto it = vars.find(name);
|
2019-01-08 17:12:05 +01:00
|
|
|
if (it == vars.end())
|
|
|
|
return -1;
|
|
|
|
else
|
|
|
|
return (*it).second;
|
|
|
|
}
|
|
|
|
|
|
|
|
DynareDynamicAtoms::DynareDynamicAtoms(const DynareDynamicAtoms &dda)
|
|
|
|
: SAtoms(dda)
|
|
|
|
{
|
|
|
|
// fill atom_type
|
2019-01-09 15:44:26 +01:00
|
|
|
for (auto it : dda.atom_type)
|
|
|
|
atom_type.insert(Tatypemap::value_type(varnames.query(it.first), it.second));
|
2019-01-08 17:12:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DynareDynamicAtoms::parse_variable(const char *in, std::string &out, int &ll) const
|
|
|
|
{
|
|
|
|
ll = 0;
|
|
|
|
std::string str = in;
|
|
|
|
int left = str.find_first_of("({");
|
|
|
|
if (left != -1)
|
|
|
|
{
|
|
|
|
out = str.substr(0, left);
|
|
|
|
left++;
|
|
|
|
int right = str.find_first_of(")}", left);
|
|
|
|
if ((int) string::npos == right)
|
|
|
|
throw ogp::ParserException(
|
|
|
|
string("Syntax error when parsing Dynare atom <")+in+">.", 0);
|
|
|
|
std::string tmp(str, left, right-left);
|
|
|
|
sscanf(tmp.c_str(), "%d", &ll);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
out = in;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DynareDynamicAtoms::register_uniq_endo(const char *name)
|
|
|
|
{
|
|
|
|
FineAtoms::register_uniq_endo(name);
|
|
|
|
atom_type.insert(Tatypemap::value_type(varnames.query(name), endovar));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DynareDynamicAtoms::register_uniq_exo(const char *name)
|
|
|
|
{
|
|
|
|
FineAtoms::register_uniq_exo(name);
|
|
|
|
atom_type.insert(Tatypemap::value_type(varnames.query(name), exovar));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DynareDynamicAtoms::register_uniq_param(const char *name)
|
|
|
|
{
|
|
|
|
FineAtoms::register_uniq_param(name);
|
|
|
|
atom_type.insert(Tatypemap::value_type(varnames.query(name), param));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
DynareDynamicAtoms::is_type(const char *name, atype tp) const
|
|
|
|
{
|
2019-01-09 15:51:19 +01:00
|
|
|
auto it = atom_type.find(name);
|
2019-01-08 17:12:05 +01:00
|
|
|
if (it != atom_type.end() && (*it).second == tp)
|
|
|
|
return true;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DynareDynamicAtoms::print() const
|
|
|
|
{
|
|
|
|
SAtoms::print();
|
|
|
|
printf("Name types:\n");
|
2019-01-09 15:44:26 +01:00
|
|
|
for (auto it : atom_type)
|
|
|
|
printf("name=%s type=%s\n", it.first,
|
|
|
|
(it.second == endovar) ? "endovar" : ((it.second == exovar) ? "exovar" : "param"));
|
2019-01-08 17:12:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string
|
|
|
|
DynareDynamicAtoms::convert(int t) const
|
|
|
|
{
|
|
|
|
if (t < ogp::OperationTree::num_constants)
|
|
|
|
{
|
|
|
|
throw ogu::Exception(__FILE__, __LINE__,
|
|
|
|
"Tree index is a built-in constant in DynareDynamicAtoms::convert");
|
|
|
|
return std::string();
|
|
|
|
}
|
|
|
|
if (is_constant(t))
|
|
|
|
{
|
|
|
|
double v = get_constant_value(t);
|
|
|
|
char buf[100];
|
|
|
|
sprintf(buf, "%20.16g", v);
|
|
|
|
const char *s = buf;
|
|
|
|
while (*s == ' ')
|
|
|
|
++s;
|
|
|
|
return std::string(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *s = name(t);
|
|
|
|
if (is_type(s, endovar))
|
|
|
|
{
|
|
|
|
int ll = lead(t);
|
|
|
|
char buf[100];
|
|
|
|
if (ll)
|
|
|
|
sprintf(buf, "%s(%d)", s, ll);
|
|
|
|
else
|
|
|
|
sprintf(buf, "%s", s);
|
|
|
|
return std::string(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::string(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DynareAtomValues::setValues(ogp::EvalTree &et) const
|
|
|
|
{
|
|
|
|
// set constants
|
|
|
|
atoms.setValues(et);
|
|
|
|
|
|
|
|
// set parameteres
|
|
|
|
for (unsigned int i = 0; i < atoms.get_params().size(); i++)
|
|
|
|
{
|
|
|
|
if (atoms.is_referenced(atoms.get_params()[i]))
|
|
|
|
{
|
|
|
|
const ogp::DynamicAtoms::Tlagmap &lmap = atoms.lagmap(atoms.get_params()[i]);
|
2019-01-09 15:44:26 +01:00
|
|
|
for (auto it : lmap)
|
2019-01-08 17:12:05 +01:00
|
|
|
{
|
2019-01-09 15:44:26 +01:00
|
|
|
int t = it.second;
|
2019-01-08 17:12:05 +01:00
|
|
|
et.set_nulary(t, paramvals[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// set endogenous
|
|
|
|
for (unsigned int outer_i = 0; outer_i < atoms.get_endovars().size(); outer_i++)
|
|
|
|
{
|
|
|
|
if (atoms.is_referenced(atoms.get_endovars()[outer_i]))
|
|
|
|
{
|
|
|
|
const ogp::DynamicAtoms::Tlagmap &lmap = atoms.lagmap(atoms.get_endovars()[outer_i]);
|
2019-01-09 15:44:26 +01:00
|
|
|
for (auto it : lmap)
|
2019-01-08 17:12:05 +01:00
|
|
|
{
|
2019-01-09 15:44:26 +01:00
|
|
|
int ll = it.first;
|
|
|
|
int t = it.second;
|
2019-01-08 17:12:05 +01:00
|
|
|
int i = atoms.outer2y_endo()[outer_i];
|
|
|
|
if (ll == -1)
|
|
|
|
{
|
|
|
|
et.set_nulary(t, yym[i-atoms.nstat()]);
|
|
|
|
}
|
|
|
|
else if (ll == 0)
|
|
|
|
et.set_nulary(t, yy[i]);
|
|
|
|
else
|
|
|
|
et.set_nulary(t, yyp[i-atoms.nstat()-atoms.npred()]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// set exogenous
|
|
|
|
for (unsigned int outer_i = 0; outer_i < atoms.get_exovars().size(); outer_i++)
|
|
|
|
{
|
|
|
|
if (atoms.is_referenced(atoms.get_exovars()[outer_i]))
|
|
|
|
{
|
|
|
|
const ogp::DynamicAtoms::Tlagmap &lmap = atoms.lagmap(atoms.get_exovars()[outer_i]);
|
2019-01-09 15:44:26 +01:00
|
|
|
for (auto it : lmap)
|
2019-01-08 17:12:05 +01:00
|
|
|
{
|
2019-01-09 15:44:26 +01:00
|
|
|
int ll = it.first;
|
2019-01-08 17:12:05 +01:00
|
|
|
if (ll == 0) // this is always true because of checks
|
|
|
|
{
|
2019-01-09 15:44:26 +01:00
|
|
|
int t = it.second;
|
2019-01-08 17:12:05 +01:00
|
|
|
int i = atoms.outer2y_exo()[outer_i];
|
|
|
|
et.set_nulary(t, xx[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DynareStaticSteadyAtomValues::setValues(ogp::EvalTree &et) const
|
|
|
|
{
|
|
|
|
// set constants
|
|
|
|
atoms_static.setValues(et);
|
|
|
|
|
|
|
|
// set parameters
|
2019-01-09 15:44:26 +01:00
|
|
|
for (auto name : atoms_static.get_params())
|
2019-01-08 17:12:05 +01:00
|
|
|
{
|
|
|
|
int t = atoms_static.index(name);
|
|
|
|
if (t != -1)
|
|
|
|
{
|
|
|
|
int idyn = atoms.name2outer_param(name);
|
|
|
|
et.set_nulary(t, paramvals[idyn]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// set endogenous
|
2019-01-09 15:44:26 +01:00
|
|
|
for (auto name : atoms_static.get_endovars())
|
2019-01-08 17:12:05 +01:00
|
|
|
{
|
|
|
|
int t = atoms_static.index(name);
|
|
|
|
if (t != -1)
|
|
|
|
{
|
|
|
|
int idyn = atoms.outer2y_endo()[atoms.name2outer_endo(name)];
|
|
|
|
et.set_nulary(t, yy[idyn]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// set exogenous
|
2019-01-09 15:44:26 +01:00
|
|
|
for (auto name : atoms_static.get_exovars())
|
2019-01-08 17:12:05 +01:00
|
|
|
{
|
|
|
|
int t = atoms_static.index(name);
|
|
|
|
if (t != -1)
|
|
|
|
et.set_nulary(t, 0.0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DynareSteadySubstitutions::DynareSteadySubstitutions(const ogp::FineAtoms &a,
|
|
|
|
const ogp::OperationTree &tree,
|
|
|
|
const Tsubstmap &subst,
|
|
|
|
const Vector &pvals, Vector &yy)
|
|
|
|
: atoms(a), y(yy)
|
|
|
|
{
|
|
|
|
// fill the vector of left and right hand sides
|
2019-01-09 15:44:26 +01:00
|
|
|
for (auto it : subst)
|
2019-01-08 17:12:05 +01:00
|
|
|
{
|
2019-01-09 15:44:26 +01:00
|
|
|
left_hand_sides.push_back(it.first);
|
|
|
|
right_hand_sides.push_back(it.second);
|
2019-01-08 17:12:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// evaluate right hand sides
|
|
|
|
DynareSteadyAtomValues dsav(atoms, pvals, y);
|
|
|
|
ogp::FormulaCustomEvaluator fe(tree, right_hand_sides);
|
|
|
|
fe.eval(dsav, *this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DynareSteadySubstitutions::load(int i, double res)
|
|
|
|
{
|
|
|
|
const char *name = left_hand_sides[i];
|
|
|
|
int iouter = atoms.name2outer_endo(name);
|
|
|
|
int iy = atoms.outer2y_endo()[iouter];
|
|
|
|
if (!std::isfinite(y[iy]))
|
|
|
|
y[iy] = res;
|
|
|
|
}
|
|
|
|
|
|
|
|
DynareStaticSteadySubstitutions::
|
|
|
|
DynareStaticSteadySubstitutions(const ogp::FineAtoms &a, const ogp::StaticFineAtoms &sa,
|
|
|
|
const ogp::OperationTree &tree,
|
|
|
|
const Tsubstmap &subst,
|
|
|
|
const Vector &pvals, Vector &yy)
|
|
|
|
: atoms(a), atoms_static(sa), y(yy)
|
|
|
|
{
|
|
|
|
// fill the vector of left and right hand sides
|
2019-01-09 15:44:26 +01:00
|
|
|
for (auto it : subst)
|
2019-01-08 17:12:05 +01:00
|
|
|
{
|
2019-01-09 15:44:26 +01:00
|
|
|
left_hand_sides.push_back(it.first);
|
|
|
|
right_hand_sides.push_back(it.second);
|
2019-01-08 17:12:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// evaluate right hand sides
|
|
|
|
DynareStaticSteadyAtomValues dsav(atoms, atoms_static, pvals, y);
|
|
|
|
ogp::FormulaCustomEvaluator fe(tree, right_hand_sides);
|
|
|
|
fe.eval(dsav, *this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DynareStaticSteadySubstitutions::load(int i, double res)
|
|
|
|
{
|
|
|
|
const char *name = left_hand_sides[i];
|
|
|
|
int iouter = atoms.name2outer_endo(name);
|
|
|
|
int iy = atoms.outer2y_endo()[iouter];
|
|
|
|
if (!std::isfinite(y[iy]))
|
|
|
|
y[iy] = res;
|
|
|
|
}
|