33 #include <cairo_base.h>    34 #include <classdesc.h>    52   using classdesc::shared_ptr;
    54   class SystemOfEquations;
    77   string mathrm(
const string& nm);
    89     virtual int BODMASlevel() 
const=0; 
    91     virtual ostream& 
latex(ostream&) 
const=0;
    92     std::string 
latexStr()
 const {ostringstream o; 
latex(o); 
return o.str();}
    94     virtual ostream& matlab(ostream&) 
const=0;
    95     std::string 
matlabStr()
 const {ostringstream o; matlab(o); 
return o.str();}
   101     virtual void render(ecolab::cairo::Surface& surf) 
const=0;
   111     virtual int order(
unsigned maxOrder) 
const=0;
   114     virtual bool tensorEval(std::set<const Node*>& visited) 
const=0;
   117     mutable int cachedOrder=-1;
   141     {payload=x.get(); 
return *
this;}
   143     {payload=x; 
return *
this;}
   147     operator bool()
 const {
return payload!=
nullptr;}
   159     ConstantDAG(
const string& value=
"0"): value(value.length()? value: 
"0") {}
   162     int order(
unsigned maxOrder)
 const  override {
return 0;}
   163     bool tensorEval(std::set<const Node*>&)
 const override {
return false;}
   164     ostream& 
latex(ostream& o)
 const  override {
return o<<value;}
   165     ostream& 
matlab(ostream& o)
 const  override {
return o<<value;}
   166     void render(ecolab::cairo::Surface& surf) 
const override;
   185     int order(
unsigned maxOrder)
 const override {
   187         if (cachedOrder>=0) 
return cachedOrder;
   188         if (maxOrder==0) 
throw error(
"maximum order recursion reached");
   189         return cachedOrder=rhs->
order(maxOrder-1)+1;
   194     bool tensorEval(std::set<const Node*>&) 
const override;
   199     ostream& 
latex(ostream&) 
const override;
   200     ostream& matlab(ostream&) 
const override;
   202     void render(ecolab::cairo::Surface& surf) 
const override;
   203     NodePtr derivative(SystemOfEquations&) 
const override; 
   225     virtual Type type() 
const=0;
   228     int order(
unsigned maxOrder) 
const override;
   229     bool tensorEval(std::set<const Node*>&) 
const override;
   232     void checkArg(
unsigned i, 
unsigned j) 
const;
   235   template <OperationType::Type T>
   240     {arguments.resize(OperationTypeInfo::numArguments<T>());}
   253           if (name.find_first_of(
"+-")!=string::npos)
   261     ostream& 
latex(ostream&) 
const override; 
   262     ostream& matlab(ostream& o) 
const override;
   263     void render(ecolab::cairo::Surface& surf) 
const override;
   273     int order(
unsigned maxOrder)
 const override {
return 0;} 
   282     ostream& 
latex(ostream& o)
 const override  {
return o<<
"locked";} 
   283     ostream& 
matlab(ostream& o)
 const override  {
return o<<
"";} 
   284     void render(ecolab::cairo::Surface& surf) 
const override;
   286     int order(
unsigned maxOrder)
 const override {
return rhs? rhs->
order(maxOrder-1)+1:0;}
   287     bool tensorEval(std::set<const Node*>&)
 const override {
return true;}
   289     {lock.
throw_error(
"derivative not defined for locked objects");}
   294     std::map<std::string, NodePtr > 
cache;
   299       return "op:"+std::to_string(std::size_t(x.
ports(0).lock().get()));
   305       return "switch:"+std::to_string(std::size_t(x.
ports(0).lock().get()));
   308       return "lock:"+std::to_string(std::size_t(x.
ports(0).lock().get()));
   311     std::string 
key(
const string& x)
 const {
   315     bool exists(
const T& x) {
return cache.count(key(x));}
   318       auto r=cache.find(key(x));
   326       reverseLookupCache[n.get()]=n;
   327       return cache.insert(make_pair(key(x),n)).first->second;
   330       integrationInputs.insert(make_pair(
"input:"+name,n));
   331       reverseLookupCache[n.get()]=n;
   334       auto r=integrationInputs.find(
"input:"+name);
   335       if (r!=integrationInputs.end())
   340     std::size_t 
size()
 const {
return cache.size()+integrationInputs.size();}
   343       auto it=reverseLookupCache.find(&x);
   344       if (it==reverseLookupCache.end())
   353       return reverseLookupCache.insert(make_pair(x.get(), x)).first->second;
   382     void processGodleyTable
   383     (map<string, GodleyColumnDAG>& godleyVariables, 
const GodleyIcon&);
   386     template <
class Expr> 
NodePtr chainRule(
const Expr& x, 
const Expr& deriv);
   398     ostream& 
latex(ostream&) 
const; 
   399     ostream& latexWrapped(ostream&) 
const; 
   401     ostream& matlab(ostream&) 
const; 
   402     void populateEvalOpVector
   407     (
EvalOpVector& equations, std::vector<Integral>& integrals);
   415     template <
class Expr> 
NodePtr derivative(
const Expr& expr);
   422     {
return dynamic_pointer_cast<
VariableDAG>(expressionCache[v]);}
   428     void renderEquations(ecolab::cairo::Surface&, 
double height) 
const;
   437   template <OperationType::Type T>
   439   {
return se.derivative(*
this);}
 virtual VariableValuePtr addEvalOps(EvalOpVector &, const VariableValuePtr &result={})=0
adds EvalOps to an EvalOpVector representing this node. 
bool addTensorOp(const shared_ptr< VariableValue > &result, OperationDAGBase &nodeOp, EvalOpVector &ev)
LockDAG(const Lock &lock)
Type type() const override
bool tensorEval()
returns true if the evaluation of this involves tensor processing 
LaTeXManip latex() const
used within io streaming 
void doOneEvent(bool idleTasksOnly)
checks if any GUI events are waiting, and proces an event if so 
bool tensorEval(std::set< const Node *> &) const override
returns true if the evaluation of this involves tensor processing 
ostream & matlab(ostream &o) const override
writes a matlab representation of this DAG to the stream 
ostream & latex(ostream &o) const override
writes LaTeX representation of this DAG to the stream 
int BODMASlevel() const override
algebraic heirarchy level, used for working out whether brackets are necessary. 
const Node & operator*() const
OperationDAG(const string &name="")
std::string key(const OperationBase &x) const
const NodePtr & insert(const T &x, const NodePtr &n)
std::set< std::string > processingDerivative
keep track of derivatives of variables, to trap definition loops 
VariableDAG(const string &valueId, const string &name, Type type)
string differentiateName(const string &x)
creates a new name to represent the derivative of a variable 
int order(unsigned maxOrder) const override
returns evaluation order in sequence of variable defintions 
SubexpressionCache expressionCache
std::shared_ptr< Item > ItemPtr
VariableValuePtr result
reference to where this node's value is stored 
std::string matlabStr() const
std::string uqName(const std::string &name)
extract unqualified portion of name 
vector< VariableDAG * > integrationVariables
WeakNodePtr(const std::shared_ptr< T > &x)
string valueId(const string &name)
construct a valueId from fully qualified name @ name should not be canonicalised 
int BODMASlevel() const override
algebraic heirarchy level, used for working out whether brackets are necessary. 
a shared_ptr that default constructs a default target, and is always valid 
virtual Type type() const =0
string latexInit(const string &)
convert an initialisation string into a matlab expression 
VariableDAGPtr getNodeFromIntVar(const std::string &valueId)
bool tensorEval(std::set< const Node *> &) const override
returns true if the evaluation of this involves tensor processing 
std::map< const Node *, NodePtr > reverseLookupCache
virtual int order(unsigned maxOrder) const =0
returns evaluation order in sequence of variable defintions 
std::string latexStr() const
std::shared_ptr< Node > derivative(SystemOfEquations &) const override
support for the derivative operator. 
int order(unsigned maxOrder) const override
returns evaluation order in sequence of variable defintions 
OperationDAGBase(const string &name="")
ConstantDAG(const string &value="0")
std::string key(const Lock &x) const
int order(unsigned maxOrder) const override
returns evaluation order in sequence of variable defintions 
string matlabInit(const string &)
convert an initialisation string into a matlab expression 
virtual std::string valueId() const
string used to link to the VariableValue associated with this 
VariableDAGPtr getIntegralInput(const string &name) const
MatlabManip matlab() const
int BODMASlevel() const override
algebraic heirarchy level, used for working out whether brackets are necessary. 
NodePtr derivative(const Expr &expr)
symbolically differentiate expr 
void ensureValueExists(VariableValue *vv, const std::string &name) const
ensure an associated variableValue exists 
LaTeXManip(const Node &node)
std::string str(T x)
utility function to create a string representation of a numeric type 
std::map< std::string, NodePtr > cache
void throw_error(const std::string &) const
mark item on canvas, then throw 
ostream & matlab(ostream &o) const override
writes a matlab representation of this DAG to the stream 
WeakNodePtr & operator=(const NodePtr &x)
std::string key(const SwitchIcon &x) const
weak reference into subexpression cache 
ostream & operator<<(ostream &o, LaTeXManip m)
std::shared_ptr< Node > NodePtr
NodePtr makeDAG(VariableBase &v)
int order(unsigned maxOrder) const override
returns evaluation order in sequence of variable defintions 
virtual std::string name() const
variable displayed name 
MatlabManip(const Node &node)
VariableDAGPtr getNodeFromValueId(const std::string &v)
const Node * operator->() const
NodePtr insertAnonymous(NodePtr x)
ConstantDAG(double value)
void insertIntegralInput(const string &name, const VariableDAGPtr &n)
std::string key(const VariableBase &x) const
vector< vector< WeakNodePtr > > arguments
int BODMASlevel() const override
algebraic heirarchy level, used for working out whether brackets are necessary. 
std::set< std::string > varNames
used to rename ambiguous variables in different scopes 
represents a Godley column 
virtual ostream & matlab(ostream &) const =0
writes a matlab representation of this DAG to the stream 
vector< pair< VariableDAGPtr, string > > derivInputs
std::map< std::string, std::string > userDefinedFunctions
table of user defined functions and their definitions 
vector< VariableDAG * > variables
string latex(double)
convert double to a LaTeX string representing that value 
virtual std::weak_ptr< Port > ports(std::size_t i) const
callback to be run when item deleted from group 
WeakNodePtr & operator=(Node *x)
shared_ptr< VariableDAG > VariableDAGPtr
string mathrm(const string &nm)
wraps in  if nm has more than one letter - and also takes into account LaTeX subscript/superscripts ...
NodePtr derivative(SystemOfEquations &) const override
support for the derivative operator. 
std::string key(const string &x) const
strings refer to variable names 
std::shared_ptr< VariableValue > vValue() const
variableValue associated with this. nullptr if not associated with a variableValue ...
NodePtr reverseLookup(const Node &x) const
returns NodePtr corresponding to object , if it exists in cache, nullptr otherwise ...
a manipulator to make iostream expressions easy 
NodePtr operator[](const T &x) const
set< string > processedColumns
std::map< std::string, VariableDAGPtr > integrationInputs
virtual ostream & latex(ostream &) const =0
writes LaTeX representation of this DAG to the stream 
ostream & latex(ostream &o) const override
writes LaTeX representation of this DAG to the stream