dynare/dynare++/parser/cc/atom_assignings.hh

137 lines
5.2 KiB
C++
Raw Normal View History

// Copyright © 2006, Ondra Kamenik
// $Id: atom_assignings.h 149 2007-04-30 02:11:46Z okamenik $
#ifndef OGP_ATOM_ASSIGNINGS_H
#define OGP_ATOM_ASSIGNINGS_H
#include "static_atoms.hh"
#include "formula_parser.hh"
#include "atom_substitutions.hh"
#include <vector>
#include <map>
2017-05-16 16:30:27 +02:00
namespace ogp
{
2017-05-16 16:30:27 +02:00
class AtomAsgnEvaluator;
2017-05-16 16:30:27 +02:00
/** This class represents atom assignments used in parameters
* settings and initval initialization. It maintains atoms of the
* all expressions on the right hand side, the parsed formulas of
* the right hand sides, and the information about the left hand
* sides. See documentation to the order member below. */
class AtomAssignings
{
friend class AtomAsgnEvaluator;
protected:
using Tvarintmap = std::map<const char *, int, ltstr>;
2017-05-16 16:30:27 +02:00
/** All atoms which should be sufficient for formulas at the
* right hand sides. The atoms should be filled with names
* (preregistered). This is a responsibility of the caller. */
StaticAtoms &atoms;
/** The formulas of right hand sides. */
FormulaParser expr;
/** Name storage of the names from left hand sides. */
NameStorage left_names;
/** Information on left hand sides. This maps a name to the
* index of its assigned expression in expr. More than one
* name may reference to the same expression. */
Tvarintmap lname2expr;
/** Information on left hand sides. If order[i] >= 0, then it
* says that i-th expression in expr is assigned to atom with
* order[i] tree index. */
std::vector<int> order;
public:
/** Construct the object using the provided static atoms. */
AtomAssignings(StaticAtoms &a) : atoms(a), expr(atoms)
{
}
/** Make a copy with provided reference to (posibly different)
* static atoms. */
AtomAssignings(const AtomAssignings &aa, StaticAtoms &a);
virtual ~AtomAssignings()
= default;
2017-05-16 16:30:27 +02:00
/** Parse the assignments from the given string. */
void parse(int length, const char *stream);
/** Process a syntax error from bison. */
void error(const char *mes);
/** Add an assignment of the given name to the given
* double. Can be called by a user, anytime. */
void add_assignment_to_double(const char *name, double val);
/** Add an assignment. Called from assign.y. */
void add_assignment(int asgn_off, const char *str, int name_len,
int right_off, int right_len);
/** This applies old2new map (possibly from atom
* substitutions) to this object. It registers new variables
* in the atoms, and adds the expressions to expr, and left
* names to lname2expr. The information about dynamical part
* of substitutions is ignored, since we are now in the static
* world. */
void apply_subst(const AtomSubstitutions::Toldnamemap &mm);
/** Debug print. */
void print() const;
};
2017-05-16 16:30:27 +02:00
/** This class basically evaluates the atom assignments
* AtomAssignings, so it inherits from ogp::FormulaEvaluator. It
* is also a storage for the results of the evaluation stored as a
* vector, so the class inherits from std::vector<double> and
* ogp::FormulaEvalLoader. As the expressions for atoms are
* evaluated, the results are values for atoms which will be
* used in subsequent evaluations. For this reason, the class
* inherits also from AtomValues. */
class AtomAsgnEvaluator : public FormulaEvalLoader,
public AtomValues,
protected FormulaEvaluator,
public std::vector<double>
{
protected:
using Tusrvalmap = std::map<int, double>;
2017-05-16 16:30:27 +02:00
Tusrvalmap user_values;
const AtomAssignings &aa;
public:
AtomAsgnEvaluator(const AtomAssignings &a)
: FormulaEvaluator(a.expr),
std::vector<double>(a.expr.nformulas()), aa(a)
{
}
~AtomAsgnEvaluator()
override = default;
2017-05-16 16:30:27 +02:00
/** 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()
* method passing this argument as AtomValues. So the
* ogp::EvalTree will be always this->etree. */
void setValues(EvalTree &et) const override;
2017-05-16 16:30:27 +02:00
/** User setting of the values. For example in initval,
* parameters are known and should be set to their values. In
* constrast endogenous variables are set initially to NaNs by
* AtomValues::setValues. */
void set_user_value(const char *name, double val);
/** This sets the result of i-th expression in aa to res, and
* also checks whether the i-th expression is an atom. If so,
* it sets the value of the atom in ogp::EvalTree
* this->etree. */
void load(int i, double res) override;
2017-05-16 16:30:27 +02:00
/** After the user values have been set, the assignments can
* be evaluated. For this purpose we have eval() method. The
* result is that this object as std::vector<double> will
* contain the values. It is ordered given by formulas in
* expr. */
void
eval()
{
FormulaEvaluator::eval(*this, *this);
}
/** This returns a value for a given name. If the name is not
* found among atoms, or there is no assignment for the atom,
* NaN is returned. */
double get_value(const char *name) const;
};
};
#endif