2019-06-19 14:34:30 +02:00
|
|
|
|
/*
|
|
|
|
|
* Copyright © 2006 Ondra Kamenik
|
|
|
|
|
* Copyright © 2019 Dynare Team
|
|
|
|
|
*
|
|
|
|
|
* This file is part of Dynare.
|
|
|
|
|
*
|
|
|
|
|
* Dynare is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* Dynare is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2021-06-09 17:33:48 +02:00
|
|
|
|
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
2019-06-19 14:34:30 +02:00
|
|
|
|
*/
|
2009-09-08 15:55:19 +02:00
|
|
|
|
|
|
|
|
|
#ifndef OGDYN_DYNARE_ATOMS_H
|
|
|
|
|
#define OGDYN_DYNARE_ATOMS_H
|
|
|
|
|
|
2019-01-08 17:12:05 +01:00
|
|
|
|
#include "sylv/cc/Vector.hh"
|
2009-09-08 15:55:19 +02:00
|
|
|
|
|
2019-01-08 17:12:05 +01:00
|
|
|
|
#include "parser/cc/static_atoms.hh"
|
|
|
|
|
#include "parser/cc/static_fine_atoms.hh"
|
|
|
|
|
#include "parser/cc/atom_substitutions.hh"
|
|
|
|
|
#include "parser/cc/tree.hh"
|
2009-09-08 15:55:19 +02:00
|
|
|
|
|
|
|
|
|
#include <map>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
2017-05-16 16:30:27 +02:00
|
|
|
|
namespace ogdyn
|
|
|
|
|
{
|
|
|
|
|
using std::map;
|
|
|
|
|
using std::vector;
|
2019-04-24 14:52:30 +02:00
|
|
|
|
using std::string;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* A definition of a type mapping a string to an integer. Used as a
|
|
|
|
|
substitution map, saying what names are substituted for what expressions
|
|
|
|
|
represented by tree indices. */
|
2019-04-24 14:52:30 +02:00
|
|
|
|
using Tsubstmap = map<string, int>;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
|
|
|
|
|
class DynareStaticAtoms : public ogp::StaticAtoms
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
DynareStaticAtoms()
|
|
|
|
|
: StaticAtoms()
|
|
|
|
|
{
|
|
|
|
|
}
|
2019-04-23 18:57:52 +02:00
|
|
|
|
DynareStaticAtoms(const DynareStaticAtoms &a) = default;
|
|
|
|
|
~DynareStaticAtoms() override = default;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* This registers a unique varname identifier. It throws an exception if
|
|
|
|
|
the variable name is duplicate. It checks the uniqueness and then it
|
|
|
|
|
calls StaticAtoms::register_name. */
|
2019-04-24 14:52:30 +02:00
|
|
|
|
void register_name(string name) override;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
protected:
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* This returns a tree index of the given variable, and if the variable has
|
|
|
|
|
not been registered, it throws an exception. */
|
2019-04-24 14:52:30 +02:00
|
|
|
|
int check_variable(const string &name) const override;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class DynareDynamicAtoms : public ogp::SAtoms, public ogp::NularyStringConvertor
|
|
|
|
|
{
|
|
|
|
|
public:
|
2019-12-20 14:36:20 +01:00
|
|
|
|
enum class atype { endovar, exovar, param };
|
2017-05-16 16:30:27 +02:00
|
|
|
|
protected:
|
2019-04-24 14:52:30 +02:00
|
|
|
|
using Tatypemap = map<string, atype>;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* The map assigining a type to each name. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
Tatypemap atom_type;
|
|
|
|
|
public:
|
|
|
|
|
DynareDynamicAtoms()
|
|
|
|
|
: ogp::SAtoms()
|
|
|
|
|
{
|
|
|
|
|
}
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* This parses a variable of the forms: varname(+3), varname(3), varname,
|
|
|
|
|
varname(-3), varname(0), varname(+0), varname(-0). */
|
2019-04-24 14:52:30 +02:00
|
|
|
|
void parse_variable(const string &in, std::string &out, int &ll) const override;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Registers unique name of endogenous variable. */
|
2019-04-24 14:52:30 +02:00
|
|
|
|
void register_uniq_endo(string name) override;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Registers unique name of exogenous variable. */
|
2019-04-24 14:52:30 +02:00
|
|
|
|
void register_uniq_exo(string name) override;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Registers unique name of parameter. */
|
2019-04-24 14:52:30 +02:00
|
|
|
|
void register_uniq_param(string name) override;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Return true if the name is a given type. */
|
2019-04-24 14:52:30 +02:00
|
|
|
|
bool is_type(const string &name, atype tp) const;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Debug print. */
|
2019-01-09 16:26:42 +01:00
|
|
|
|
void print() const override;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Implement NularyStringConvertor::convert. */
|
2019-01-09 16:26:42 +01:00
|
|
|
|
std::string convert(int t) const override;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
};
|
|
|
|
|
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* This class represents the atom values for dynare, where exogenous
|
|
|
|
|
variables can occur only at time t, and endogenous at times t−1, t, and
|
|
|
|
|
t+1. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
class DynareAtomValues : public ogp::AtomValues
|
|
|
|
|
{
|
|
|
|
|
protected:
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Reference to the atoms (we suppose that they are only at t−1,t,t+1. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
const ogp::FineAtoms &atoms;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* De facto reference to the values of parameters. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
const ConstVector paramvals;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* De facto reference to the values of endogenous at time t−1. Only
|
|
|
|
|
predetermined and both part. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
const ConstVector yym;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* De facto reference to the values of endogenous at time t. Ordering given
|
|
|
|
|
by the atoms. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
const ConstVector yy;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* De facto reference to the values of endogenous at time t+1. Only both
|
|
|
|
|
and forward looking part. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
const ConstVector yyp;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* De facto reference to the values of exogenous at time t. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
const ConstVector xx;
|
|
|
|
|
public:
|
|
|
|
|
DynareAtomValues(const ogp::FineAtoms &a, const Vector &pvals, const Vector &ym,
|
|
|
|
|
const Vector &y, const Vector &yp, const Vector &x)
|
|
|
|
|
: atoms(a), paramvals(pvals), yym(ym), yy(y), yyp(yp), xx(x)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
DynareAtomValues(const ogp::FineAtoms &a, const Vector &pvals, const ConstVector &ym,
|
Dynare++ / sylvester equation solver: refactor Vector and ConstVector classes
- these classes now encapsulate a std::shared_ptr<{const, }double>, so that
they do not perform memory management, and several {Const,}Vector instances
can transparently share the same underlying data
- make converting constructor from ConstVector to Vector explicit, since that
entails memory allocation (but the reverse conversion is almost costless, so
keep it implicit); do the same for GeneralMatrix/ConstGeneralMatrix,
TwoDMatrix/ConstTwoDMatrix
- remove the constructors that were extracting a row/column from a matrix, and
replace them by getRow() and getCol() methods on {Const,}GeneralMatrix
- rename and change the API of the complex version Vector::add(), so that it is
explicit that it deals with complex numbers
- add constructors that take a MATLAB mxArray
2019-01-22 16:07:44 +01:00
|
|
|
|
const ConstVector &y, const ConstVector &yp, const Vector &x)
|
2017-05-16 16:30:27 +02:00
|
|
|
|
: atoms(a), paramvals(pvals), yym(ym), yy(y), yyp(yp), xx(x)
|
|
|
|
|
{
|
|
|
|
|
}
|
2019-01-09 16:26:42 +01:00
|
|
|
|
void setValues(ogp::EvalTree &et) const override;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
};
|
|
|
|
|
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* This class represents the atom values at the steady state. It makes only
|
|
|
|
|
appropriate subvector yym and yyp of the y vector, makes a vector of zero
|
|
|
|
|
exogenous variables and uses DynareAtomValues with more general
|
|
|
|
|
interface. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
class DynareSteadyAtomValues : public ogp::AtomValues
|
|
|
|
|
{
|
|
|
|
|
protected:
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Subvector of yy. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
const ConstVector yym;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Subvector of yy. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
const ConstVector yyp;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Vector of zeros for exogenous variables. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
Vector xx;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Atom values using this yym, yyp and xx. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
DynareAtomValues av;
|
|
|
|
|
public:
|
|
|
|
|
DynareSteadyAtomValues(const ogp::FineAtoms &a, const Vector &pvals, const Vector &y)
|
|
|
|
|
: yym(y, a.nstat(), a.nys()),
|
|
|
|
|
yyp(y, a.nstat()+a.npred(), a.nyss()),
|
|
|
|
|
xx(a.nexo()),
|
|
|
|
|
av(a, pvals, yym, y, yyp, xx)
|
|
|
|
|
{
|
|
|
|
|
xx.zeros();
|
|
|
|
|
}
|
|
|
|
|
void
|
2019-01-09 16:26:42 +01:00
|
|
|
|
setValues(ogp::EvalTree &et) const override
|
2017-05-16 16:30:27 +02:00
|
|
|
|
{
|
|
|
|
|
av.setValues(et);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class DynareStaticSteadyAtomValues : public ogp::AtomValues
|
|
|
|
|
{
|
|
|
|
|
protected:
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Reference to static atoms over which the tree, where the values go, is
|
|
|
|
|
defined. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
const ogp::StaticFineAtoms &atoms_static;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Reference to dynamic atoms for which the class gets input data. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
const ogp::FineAtoms &atoms;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* De facto reference to input data, this is a vector of endogenous
|
|
|
|
|
variables in internal ordering of the dynamic atoms. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
ConstVector yy;
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* De facto reference to input parameters corresponding to ordering defined
|
|
|
|
|
by the dynamic atoms. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
ConstVector paramvals;
|
|
|
|
|
public:
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Construct the object. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
DynareStaticSteadyAtomValues(const ogp::FineAtoms &a, const ogp::StaticFineAtoms &sa,
|
|
|
|
|
const Vector &pvals, const Vector &yyy)
|
|
|
|
|
: atoms_static(sa),
|
|
|
|
|
atoms(a),
|
|
|
|
|
yy(yyy),
|
|
|
|
|
paramvals(pvals)
|
|
|
|
|
{
|
|
|
|
|
}
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* Set the values to the tree defined over the static atoms. */
|
2019-01-09 16:26:42 +01:00
|
|
|
|
void setValues(ogp::EvalTree &et) const override;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
};
|
|
|
|
|
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* This class takes a vector of endogenous variables and a substitution map.
|
|
|
|
|
It supposes that variables at the right hand sides of the substitutions
|
|
|
|
|
are set in the endogenous vector. It evaluates the substitutions and if
|
|
|
|
|
the variables corresponding to left hand sides are not set in the
|
|
|
|
|
endogenous vector it sets them to calculated values. If a variable is
|
|
|
|
|
already set, it does not override its value. It has no methods, everything
|
|
|
|
|
is done in the constructor. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
class DynareSteadySubstitutions : public ogp::FormulaEvalLoader
|
|
|
|
|
{
|
|
|
|
|
protected:
|
|
|
|
|
const ogp::FineAtoms &atoms;
|
|
|
|
|
public:
|
|
|
|
|
DynareSteadySubstitutions(const ogp::FineAtoms &a, const ogp::OperationTree &tree,
|
|
|
|
|
const Tsubstmap &subst,
|
|
|
|
|
const Vector &pvals, Vector &yy);
|
2019-01-09 16:26:42 +01:00
|
|
|
|
void load(int i, double res) override;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
protected:
|
|
|
|
|
Vector &y;
|
2019-04-24 14:52:30 +02:00
|
|
|
|
vector<string> left_hand_sides;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
vector<int> right_hand_sides;
|
|
|
|
|
};
|
|
|
|
|
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* This class is a static version of DynareSteadySustitutions. It works for
|
|
|
|
|
static atoms and static tree and substitution map over the static tree. It
|
|
|
|
|
also needs dynamic version of the atoms, since it defines ordering of the
|
|
|
|
|
vectors pvals, and yy. */
|
2017-05-16 16:30:27 +02:00
|
|
|
|
class DynareStaticSteadySubstitutions : public ogp::FormulaEvalLoader
|
|
|
|
|
{
|
|
|
|
|
protected:
|
|
|
|
|
const ogp::FineAtoms &atoms;
|
|
|
|
|
const ogp::StaticFineAtoms &atoms_static;
|
|
|
|
|
public:
|
|
|
|
|
DynareStaticSteadySubstitutions(const ogp::FineAtoms &a,
|
|
|
|
|
const ogp::StaticFineAtoms &sa,
|
|
|
|
|
const ogp::OperationTree &tree,
|
|
|
|
|
const Tsubstmap &subst,
|
|
|
|
|
const Vector &pvals, Vector &yy);
|
2019-01-09 16:26:42 +01:00
|
|
|
|
void load(int i, double res) override;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
protected:
|
|
|
|
|
Vector &y;
|
2019-04-24 14:52:30 +02:00
|
|
|
|
vector<string> left_hand_sides;
|
2017-05-16 16:30:27 +02:00
|
|
|
|
vector<int> right_hand_sides;
|
|
|
|
|
};
|
2009-09-08 15:55:19 +02:00
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif
|