COPASI API  4.16.103
CEvaluationNode.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010 - 2015 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 // Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
7 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
8 // and The University of Manchester.
9 // All rights reserved.
10 
11 // Copyright (C) 2005 - 2007 by Pedro Mendes, Virginia Tech Intellectual
12 // Properties, Inc. and EML Research, gGmbH.
13 // All rights reserved.
14 
15 #include "copasi.h"
16 #include "CEvaluationNode.h"
17 
18 #include "sbml/math/ASTNode.h"
19 #include "sbml/ConverterASTNode.h"
20 #include "sbml/util/List.h"
21 
23 
25  const size_t & right):
26  left(left),
27  right(right)
28 {}
29 
31  left(src.left),
32  right(src.right)
33 {}
34 
36 
38  const std::string & contents)
39 {
40  CEvaluationNode * pNode = NULL;
41 
42  switch (CEvaluationNode::type(type))
43  {
46  contents);
47  break;
48 
51  contents);
52  break;
53 
56  contents);
57  break;
58 
61  contents);
62  break;
63 
66  contents);
67  break;
68 
71  contents);
72  break;
73 
76  contents);
77  break;
78 
81  contents);
82  break;
83 
86  contents);
87  break;
88 
91  contents);
92  break;
93 
96  contents);
97  break;
98 
101  contents);
102  break;
103 
106  contents);
107  break;
108 
110  pNode = new CEvaluationNode();
111  break;
112 
114  break;
115  }
116 
117  return pNode;
118 }
119 
121 {return (Type)(type & 0x00FFFFFF);}
122 
124 {return (Type)(type & 0xFF000000);}
125 
126 // static
127 const char * CEvaluationNode::Keywords[] =
128 {
129  "log", "LOG",
130  "log10", "LOG10",
131  "exp", "EXP",
132  "sin", "SIN",
133  "cos", "COS",
134  "tan", "TAN",
135  "sec", "SEC",
136  "csc", "CSC",
137  "cot", "COT",
138  "sinh", "SINH",
139  "cosh", "COSH",
140  "tanh", "TANH",
141  "sech", "SECH",
142  "csch", "CSCH",
143  "coth", "COTH",
144  "asin", "ASIN",
145  "acos", "ACOS",
146  "atan", "ATAN",
147  "arcsec", "ARCSEC",
148  "arccsc", "ARCCSC",
149  "arccot", "ARCCOT",
150  "arcsinh", "ARCSINH",
151  "arccosh", "ARCCOSH",
152  "arctanh", "ARCTANH",
153  "arcsech", "ARCSECH",
154  "arccsch", "ARCCSCH",
155  "arccoth", "ARCCOTH",
156  "sqrt", "SQRT",
157  "abs", "ABS",
158  "floor", "FLOOR",
159  "ceil", "CEIL",
160  "factorial", "FACTORIAL",
161  "uniform", "UNIFORM",
162  "normal", "NORMAL",
163  "gamma", "GAMMA",
164  "poisson", "POISSON",
165  "max", "MAX",
166  "min", "MIN",
167  "delay", "DELAY",
168  "if", "IF",
169  NULL
170 };
171 
172 // static
173 bool CEvaluationNode::isKeyword(const std::string & str)
174 {
175  const char ** pKeyword = Keywords;
176 
177  for (; *pKeyword != NULL; ++pKeyword)
178  if (!strcmp(str.c_str(), *pKeyword)) return true;
179 
180  return false;
181 }
182 
184  CCopasiNode<Data>(""),
186  mValue(std::numeric_limits<C_FLOAT64>::quiet_NaN()),
187  mpValue(NULL),
189 {
190  mpValue = & mValue;
191 }
192 
194  const Data & data):
195  CCopasiNode<Data>(data),
196  mType(type),
197  mValue(std::numeric_limits<C_FLOAT64>::quiet_NaN()),
198  mpValue(NULL),
199  mPrecedence(PRECEDENCE_DEFAULT)
200 {
201  mpValue = & mValue;
202 }
203 
205  CCopasiNode<Data>(src),
206  mType(src.mType),
207  mValue(src.mValue),
208  mpValue(NULL),
209  mPrecedence(src.mPrecedence)
210 {
211  mpValue = & mValue;
212 }
213 
215 
216 bool CEvaluationNode::compile(const CEvaluationTree * /* pTree */)
217 {return true;}
218 
219 // virtual
220 std::string CEvaluationNode::getInfix(const std::vector< std::string > & /* children */) const
221 {return mData;}
222 
223 std::string CEvaluationNode::buildInfix() const
224 {
225  std::string Infix = "";
227 
228  while (it.next() != it.end())
229  {
230  if (*it != NULL)
231  {
232  if (it.parentContextPtr() != NULL)
233  {
234  it.parentContextPtr()->push_back(it->getInfix(it.context()));
235  }
236  else
237  {
238  Infix = it->getInfix(it.context());
239  }
240  }
241  }
242 
243  return Infix;
244 }
245 
246 // virtual
247 std::string CEvaluationNode::getDisplayString(const std::vector< std::string > & /* children */) const
248 {return mData;}
249 
251 {
252  std::string DisplayString = "";
254 
255  while (it.next() != it.end())
256  {
257  if (*it != NULL)
258  {
259  if (it.parentContextPtr() != NULL)
260  {
261  it.parentContextPtr()->push_back(it->getDisplayString(it.context()));
262  }
263  else
264  {
265  DisplayString = it->getDisplayString(it.context());
266  }
267  }
268  }
269 
270  return DisplayString;
271 }
272 
273 // virtual
274 std::string CEvaluationNode::getCCodeString(const std::vector< std::string > & /* children */) const
275 {return mData;}
276 
277 /**
278  * Build the C-code string.
279  */
281 {
282  std::string CCodeString = "";
284 
285  while (it.next() != it.end())
286  {
287  if (*it != NULL)
288  {
289  if (it.parentContextPtr() != NULL)
290  {
291  it.parentContextPtr()->push_back(it->getCCodeString(it.context()));
292  }
293  else
294  {
295  CCodeString = it->getCCodeString(it.context());
296  }
297  }
298  }
299 
300  return CCodeString;
301 }
302 
303 // virtual
304 std::string CEvaluationNode::getBerkeleyMadonnaString(const std::vector< std::string > & /* children */) const
305 {return mData;}
306 
308 {
309  std::string BerkeleyMadonnaString = "";
311 
312  while (it.next() != it.end())
313  {
314  if (*it != NULL)
315  {
316  if (it.parentContextPtr() != NULL)
317  {
318  it.parentContextPtr()->push_back(it->getBerkeleyMadonnaString(it.context()));
319  }
320  else
321  {
322  BerkeleyMadonnaString = it->getBerkeleyMadonnaString(it.context());
323  }
324  }
325  }
326 
327  return BerkeleyMadonnaString;
328 }
329 
330 // virtual
331 std::string CEvaluationNode::getXPPString(const std::vector< std::string > & /* children */) const
332 {return mData;}
333 
335 {
336  std::string BerkeleyMadonnaString = "";
338 
339  while (it.next() != it.end())
340  {
341  if (*it != NULL)
342  {
343  if (it.parentContextPtr() != NULL)
344  {
345  it.parentContextPtr()->push_back(it->getXPPString(it.context()));
346  }
347  else
348  {
349  BerkeleyMadonnaString = it->getXPPString(it.context());
350  }
351  }
352  }
353 
354  return BerkeleyMadonnaString;
355 }
356 
358 {return mType;}
359 
360 // virtual
362 {return false;}
363 
364 void CEvaluationNode::addChildren(const std::vector< CEvaluationNode * > & children)
365 {
366  std::vector< CEvaluationNode * >::const_iterator it = children.begin();
367  std::vector< CEvaluationNode * >::const_iterator end = children.end();
368 
369  for (; it != end; ++it)
370  {
371  addChild(*it);
372  }
373 }
374 
376 {return (mPrecedence.right < rhs.mPrecedence.left);}
377 
379 {
380  std::vector<CEvaluationNode*> children;
381 
382  if (child1 != NULL) children.push_back(child1);
383 
384  if (child2 != NULL) children.push_back(child2);
385 
386  return copyNode(children);
387 }
388 
389 CEvaluationNode* CEvaluationNode::copyNode(const std::vector<CEvaluationNode*>& children) const
390 {
391  CEvaluationNode * pNode = create(mType, getData());
392  std::vector<CEvaluationNode*>::const_iterator it = children.begin();
393  std::vector<CEvaluationNode*>::const_iterator endit = children.end();
394 
395  while (it != endit)
396  {
397  pNode->addChild(*it);
398  ++it;
399  }
400 
401  return pNode;
402 }
403 
405 {
406  CEvaluationNode * pNode = NULL;
408 
409  while (itNode.next() != itNode.end())
410  {
411  if (*itNode == NULL)
412  {
413  continue;
414  }
415 
416  if (itNode.parentContextPtr() != NULL)
417  {
418  itNode.parentContextPtr()->push_back(itNode->copyNode(itNode.context()));
419  }
420  else
421  {
422  assert(*itNode == this);
423  pNode = itNode->copyNode(itNode.context());
424  }
425  }
426 
427  return pNode;
428 }
429 
430 CEvaluationNode* CEvaluationNode::simplifyNode(const std::vector<CEvaluationNode*>& children) const
431 {
432  CEvaluationNode *newnode = copyNode(children);
433  return newnode;
434 }
435 
436 ASTNode* CEvaluationNode::toAST(const CCopasiDataModel* /*pDataModel*/) const
437 {
438  return new ASTNode();
439 }
440 
442 {return mpValue;}
443 
444 // virtual
445 std::string CEvaluationNode::getMMLString(const std::vector< std::string > & /* children */,
446  bool /* expand */,
447  const std::vector< std::vector< std::string > > & /* variables */) const
448 {
449  return "";
450 }
451 
452 std::string CEvaluationNode::buildMMLString(bool expand,
453  const std::vector< std::vector< std::string > > & variables) const
454 {
455  std::string MMLString = "";
457 
458  while (it.next() != it.end())
459  {
460  if (*it != NULL)
461  {
462  if (it.parentContextPtr() != NULL)
463  {
464  it.parentContextPtr()->push_back(it->getMMLString(it.context(), expand, variables));
465  }
466  else
467  {
468  MMLString = it->getMMLString(it.context(), expand, variables);
469  }
470  }
471  }
472 
473  return MMLString;
474 }
475 
476 // TODO Replace the recursive call (not critical since only used for debug)
477 void CEvaluationNode::printRecursively(std::ostream & os, int indent) const
478 {
479  int i;
480 
481  os << std::endl;
482 
483  for (i = 0; i < indent; ++i) os << " ";
484 
485  os << "mData: " << mData << std::endl;
486 
487  for (i = 0; i < indent; ++i) os << " ";
488 
489  os << "mType: " << type(mType) << " subType: " << subType(mType) << std::endl;
490 
491  for (i = 0; i < indent; ++i) os << " ";
492 
493  os << "mValue: " << mValue << std::endl;
494 
495  CEvaluationNode* tmp;
496 
497  tmp = (CEvaluationNode*)getChild();
498 
499  while (tmp)
500  {
501  tmp -> printRecursively(os, indent + 2);
502  tmp = (CEvaluationNode*)tmp->getSibling();
503  }
504 }
505 
507 {
508  this->printRecursively(std::cout, 0);
509 }
510 
512 {
513  if (splitnode == this)
514  {
515  const CEvaluationNode *child = dynamic_cast<const CEvaluationNode*>(this->getChild());
516 
517  if (!child) return NULL;
518 
519  if (left)
520  {
521  return child->copyBranch();
522  }
523  else
524  {
525  child = dynamic_cast<const CEvaluationNode*>(child->getSibling());
526 
527  if (!child) return NULL;
528 
529  return child->copyBranch();
530  }
531  }
532  else
533  {
534  /* const CEvaluationNode *child1 = dynamic_cast<const CEvaluationNode*>(getChild());
535  CEvaluationNode *newchild1 = NULL;
536  CEvaluationNode *newchild2 = NULL;
537  if (child1 != NULL)
538  {
539  newchild1 = child1->splitBranch(splitnode, left);
540  const CEvaluationNode *child2 = dynamic_cast<const CEvaluationNode*>(child1->getSibling());
541  if (child2 != NULL)
542  {
543  newchild2 = child2->splitBranch(splitnode, left);
544  }
545  }
546  CEvaluationNode *newnode = copyNode(newchild1, newchild2);
547  return newnode;*/
548 
549  std::vector<CEvaluationNode*> children;
550  const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(getChild());
551 
552  while (child != NULL)
553  {
554  CEvaluationNode *newchild = NULL;
555  newchild = child->splitBranch(splitnode, left);
556  children.push_back(newchild);
557  child = dynamic_cast<const CEvaluationNode*>(child->getSibling());
558  }
559 
560  children.push_back(NULL);
561  CEvaluationNode *newnode = copyNode(children);
562  return newnode;
563  }
564 }
565 
566 const CEvaluationNode * CEvaluationNode::findTopMinus(const std::vector<CFunctionAnalyzer::CValue> & callParameters) const
567 {
570  const CEvaluationNode * pMinus = NULL;
571 
572  while (itNode.next() != itNode.end())
573  {
574  if (*itNode == NULL)
575  {
576  continue;
577  }
578 
579 #ifdef COPASI_DEBUG
580  std::cout << itNode->getData() << std::endl;
581 #endif
582 
583  switch (itNode.processingMode())
584  {
586 
587  if (itNode->getType() == (OPERATOR | CEvaluationNodeOperator::MINUS))
588  {
589  // We found a minus no need to go down the tree.
590  itNode.skipChildren();
591  pMinus = *itNode;
592 
593  if (itNode.parentContextPtr() != NULL)
594  {
595  itNode.parentContextPtr()->push_back(pMinus);
596  }
597  }
598 
599  break;
600 
602 
604  {
605  // Left child
606  if (itNode.context()[0] != NULL)
607  {
608  // Both children contain a minus, this is not a valid split point.
609 
610  if (itNode.context()[1] != NULL)
611  {
612  pMinus = NULL;
613  }
614  // Check whether the right is positive
615  else if (CFunctionAnalyzer::evaluateNode(static_cast< const CEvaluationNode *>(itNode->getChild(1)),
616  callParameters, CFunctionAnalyzer::NOOBJECT).isPositive())
617  {
618  pMinus = itNode.context()[0];
619  }
620  else
621  {
622  pMinus = NULL;
623  }
624  }
625  // Right child
626  else if (itNode.context()[1] != NULL)
627  {
628  // Check whether the left is positive
629  if (CFunctionAnalyzer::evaluateNode(static_cast< const CEvaluationNode *>(itNode->getChild(0)),
630  callParameters, CFunctionAnalyzer::NOOBJECT).isPositive())
631  pMinus = itNode.context()[1];
632  else
633  pMinus = NULL;
634  }
635  else
636  {
637  pMinus = NULL;
638  }
639  }
640  else if (itNode->getType() == (OPERATOR | CEvaluationNodeOperator::DIVIDE))
641  {
642  // Left child
643  pMinus = itNode.context()[0];
644  }
645  else
646  {
647  pMinus = NULL;
648  }
649 
650  if (itNode.parentContextPtr() != NULL)
651  {
652  itNode.parentContextPtr()->push_back(pMinus);
653  }
654 
655  break;
656 
657  default:
658  // This will never happen
659  break;
660  }
661  }
662 
663  return pMinus;
664 }
665 
667 {
668  return !(*this == right);
669 }
670 
672 {
675 
676  while (itLeft.next() != itLeft.end() &&
677  itRight.next() != itRight.end())
678  {
679  if (*itLeft == NULL && *itRight == NULL)
680  {
681  continue;
682  }
683 
684  if (*itLeft == NULL || *itRight == NULL)
685  {
686  return false;
687  }
688 
689  if (itLeft->getType() != itRight->getType() ||
690  itLeft->getData() != itRight->getData())
691  {
692  return false;
693  }
694  }
695 
696  return true;
697 }
698 
700 {
701  bool result = false;
702 
703  if (this->getType() < right.getType())
704  {
705  result = true;
706  }
707  else if (this->getType() == right.getType())
708  {
709  switch (CEvaluationNode::type(this->getType()))
710  {
718  result = (this->getData() < right.getData());
719  break;
720 
729  break;
730  }
731 
732  const CEvaluationNode* pChild1 = dynamic_cast<const CEvaluationNode*>(this->getChild());
733 
734  const CEvaluationNode* pChild2 = dynamic_cast<const CEvaluationNode*>(right.getChild());
735 
736  while (result == false)
737  {
738  if (pChild1 == NULL || pChild2 == NULL)
739  {
740  if (pChild1 == NULL && pChild2 != NULL)
741  {
742  result = true;
743  }
744  }
745  else
746  {
747  result = (*pChild1 < *pChild2);
748  }
749 
750  pChild1 = dynamic_cast<const CEvaluationNode*>(pChild1->getSibling());
751  pChild2 = dynamic_cast<const CEvaluationNode*>(pChild2->getSibling());
752  }
753  }
754 
755  return result;
756 }
bool operator<(const CEvaluationNode &right) const
virtual ASTNode * toAST(const CCopasiDataModel *pDataModel) const
const CEvaluationNode * findTopMinus(const std::vector< CFunctionAnalyzer::CValue > &callParameters) const
CEvaluationNode * copyBranch() const
virtual std::string getDisplayString(const std::vector< std::string > &children) const
virtual std::string getXPPString(const std::vector< std::string > &children) const
CPrecedence(const size_t &left=0, const size_t &right=0)
CCopasiNode< Data > * getSibling()
Definition: CCopasiNode.h:353
const C_FLOAT64 * getValuePointer() const
static CValue evaluateNode(const CEvaluationNode *node, const std::vector< CValue > &callParameters, Mode mode)
CEvaluationNode * copyNode(CEvaluationNode *child1, CEvaluationNode *child2) const
virtual bool operator!=(const CEvaluationNode &right) const
const Type & getType() const
static CEvaluationNode * create(const Type &type, const Data &data)
std::string buildInfix() const
virtual ~CEvaluationNode()
std::string buildCCodeString() const
const CNodeIteratorMode::State & next()
virtual std::string getInfix(const std::vector< std::string > &children) const
virtual std::string getMMLString(const std::vector< std::string > &children, bool expand, const std::vector< std::vector< std::string > > &variables) const
static bool isKeyword(const std::string &str)
void addChildren(const std::vector< CEvaluationNode * > &children)
static Type type(const Type &type)
std::string buildXPPString() const
std::string buildDisplayString() const
virtual bool addChild(CCopasiNode< Data > *pChild, CCopasiNode< Data > *pAfter=NULL)
Definition: CCopasiNode.h:156
virtual std::string getBerkeleyMadonnaString(const std::vector< std::string > &children) const
void printRecursively() const
const CNodeIteratorMode::State & skipChildren()
Context * parentContextPtr()
std::string buildMMLString(bool expand, const std::vector< std::vector< std::string > > &variables) const
static Type subType(const Type &type)
void setProcessingModes(const CNodeIteratorMode::Flag &processingModes)
class CEvaluationNode::CPrecedence mPrecedence
#define C_FLOAT64
Definition: copasi.h:92
virtual bool isBoolean() const
#define PRECEDENCE_DEFAULT
bool operator==(const CEvaluationNode &right) const
virtual bool compile(const CEvaluationTree *pTree)
const CNodeIteratorMode::State & processingMode() const
std::string buildBerkeleyMadonnaString() const
virtual CEvaluationNode * simplifyNode(const std::vector< CEvaluationNode * > &children) const
virtual const Data & getData() const
Definition: CCopasiNode.h:118
const C_FLOAT64 * mpValue
CNodeIteratorMode::State end() const
CCopasiNode< Data > * getChild()
Definition: CCopasiNode.h:210
virtual std::string getCCodeString(const std::vector< std::string > &children) const
CEvaluationNode * splitBranch(const CEvaluationNode *splitnode, bool left) const
static const char * Keywords[]