COPASI API  4.16.103
CEvaluationNodeChoice.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010 - 2014 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 
17 #include "CEvaluationNode.h"
18 #include "CEvaluationTree.h"
19 
20 #include "sbml/math/ASTNode.h"
21 
23  CEvaluationNode(CEvaluationNode::INVALID, ""),
24  mpIf(NULL),
25  mpTrue(NULL),
26  mpFalse(NULL)
28 
30  const Data & data):
31  CEvaluationNode((Type)(CEvaluationNode::CHOICE | subType), data),
32  mpIf(NULL),
33  mpTrue(NULL),
34  mpFalse(NULL)
35 {
36  switch (subType)
37  {
38  case IF:
39  break;
40 
41  default:
42  fatalError();
43  break;
44  }
45 
47 }
48 
50  CEvaluationNode(src),
51  mpIf(src.mpIf),
52  mpTrue(src.mpTrue),
53  mpFalse(src.mpFalse)
54 {}
55 
57 
59 {
60  if (mpIf->getValue() > 0.5)
61  {
62  mValue = mpTrue->getValue();
63  }
64  else
65  {
66  mValue = mpFalse->getValue();
67  }
68 }
69 
71 {
72  mpIf = static_cast<CEvaluationNode *>(getChild());
73 
74  if (mpIf == NULL) return false;
75 
76  mpTrue = static_cast<CEvaluationNode *>(mpIf->getSibling());
77 
78  if (mpTrue == NULL) return false;
79 
80  mpFalse = static_cast<CEvaluationNode *>(mpTrue->getSibling());
81 
82  if (mpFalse == NULL) return false;
83 
84  return (mpFalse->getSibling() == NULL); // We must have exactly three children
85 }
86 
87 // virtual
88 std::string CEvaluationNodeChoice::getInfix(const std::vector< std::string > & children) const
89 {
90  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
91  return mData + "(" + children[0] + "," + children[1] + "," + children[2] + ")";
92  else
93  return "@";
94 }
95 
96 // virtual
97 std::string CEvaluationNodeChoice::getDisplayString(const std::vector< std::string > & children) const
98 {
99  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
100  return mData + "(" + children[0] + "," + children[1] + "," + children[2] + ")";
101  else
102  return "@";
103 }
104 
105 // virtual
106 std::string CEvaluationNodeChoice::getCCodeString(const std::vector< std::string > & children) const
107 {
108  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
109  return "(" + children[0] + " ? " + children[1] + " : " + children[2] + ")";
110  else
111  return "@";
112 }
113 
114 // virtual
115 std::string CEvaluationNodeChoice::getBerkeleyMadonnaString(const std::vector< std::string > & children) const
116 {
117  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
118  return "(if " + children[0] + " then " + children[1] + " else " + children[2] + ")";
119  else
120  return "@";
121 }
122 
123 // virtual
124 std::string CEvaluationNodeChoice::getXPPString(const std::vector< std::string > & children) const
125 {
126  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
127  return "if(" + children[0] + ")then(" + children[1] + ")else(" + children[2] + ")";
128  else
129  return "@"; //TODO
130 }
131 
132 // static
133 CEvaluationNode * CEvaluationNodeChoice::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children)
134 {
135  assert(pASTNode->getNumChildren() == children.size());
136 
137  size_t i = 0, iMax = children.size();
138 
139  // a piecewise function definition can have zero or more children.
140  if (iMax == 0)
141  {
142  // create a NaN node
144  }
145 
146  if (iMax == 1)
147  {
148  // this must be the otherwise
149  // It is not clearly specified what happens if there are no pieces, but
150  // an otherwise. I would assume that in this case, the otherwise always
151  // takes effect
152 
153  return children[0];
154  }
155 
157  std::string data = "";
158 
159  switch (pASTNode->getType())
160  {
161  case AST_FUNCTION_PIECEWISE:
162  subType = IF;
163  data = "if";
164  break;
165 
166  default:
167  subType = INVALID;
168  break;
169  }
170 
171  CEvaluationNodeChoice * pNode = new CEvaluationNodeChoice(subType, data);
172  CEvaluationNode * pCurrent = pNode;
173 
174  // We have at least 2 children
175  while (i < iMax - 1)
176  {
177  // add the condition
178  pCurrent->addChild(children[i + 1]);
179  // the true value
180  pCurrent->addChild(children[i]);
181 
182  i += 2;
183 
184  switch (iMax - i)
185  {
186  case 0:
187  // We are missing the false value
189  break;
190 
191  case 1:
192  // the false value
193  pCurrent->addChild(children[i++]);
194  break;
195 
196  default:
197  // We have at least 2 more children
198  {
199  // create a new piecewise as the false value
200  CEvaluationNode * pTmp = new CEvaluationNodeChoice(subType, data);
201  pCurrent->addChild(pTmp);
202  pCurrent = pTmp;
203  }
204  break;
205  }
206  }
207 
208  return pNode;
209 }
210 
211 ASTNode* CEvaluationNodeChoice::toAST(const CCopasiDataModel* pDataModel) const
212 {
213  ASTNode* node = new ASTNode(AST_FUNCTION_PIECEWISE);
214  const CEvaluationNode* child1 = dynamic_cast<const CEvaluationNode*>(this->getChild());
215  assert(child1 != NULL);
216  const CEvaluationNode* child2 = dynamic_cast<const CEvaluationNode*>(child1->getSibling());
217  assert(child2 != NULL);
218  const CEvaluationNode* child3 = dynamic_cast<const CEvaluationNode*>(child2->getSibling());
219  assert(child3 != NULL);
220  // the condition is the second child to the AST node but the first child in
221  // the CEvaluationNode
222  node->addChild(child2->toAST(pDataModel));
223  node->addChild(child1->toAST(pDataModel));
224  node->addChild(child3->toAST(pDataModel));
225  return node;
226 }
227 
228 #include "utilities/copasimathml.h"
229 
230 // virtual
231 std::string CEvaluationNodeChoice::getMMLString(const std::vector< std::string > & children,
232  bool /* expand */,
233  const std::vector< std::vector< std::string > > & /* variables */) const
234 {
235  std::ostringstream out;
236 
237  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
238  {
239  out << "<mrow>" << std::endl;
240  out << "<mo> {</mo>" << std::endl;
241  out << "<mtable>" << std::endl;
242 
243  out << "<mtr>" << std::endl;
244 
245  out << "<mtd>" << std::endl;
246  out << children[0];
247  out << "<mo> , </mo>" << std::endl;
248  out << "</mtd>" << std::endl;
249 
250  out << "<mtd>" << std::endl;
251  out << children[1];
252 
253  out << "</mtd>" << std::endl;
254 
255  out << "</mtr>" << std::endl;
256 
257  out << "<mtr>" << std::endl;
258 
259  out << "<mtd>" << std::endl;
260  out << "<mo> else, </mo>" << std::endl;
261 
262  out << "</mtd>" << std::endl;
263  out << "<mtd>" << std::endl;
264  out << children[2];
265  out << "</mtd>" << std::endl;
266 
267  out << "</mtr>" << std::endl;
268 
269  out << "</mtable>" << std::endl;
270  out << "</mrow>" << std::endl;
271  }
272 
273  return out.str();
274 }
virtual ASTNode * toAST(const CCopasiDataModel *pDataModel) const
virtual bool compile(const CEvaluationTree *pTree)
virtual std::string getInfix(const std::vector< std::string > &children) const
CCopasiNode< Data > * getSibling()
Definition: CCopasiNode.h:353
static CEvaluationNode * fromAST(const ASTNode *pASTNode, const std::vector< CEvaluationNode * > &children)
const C_FLOAT64 & getValue() const
#define fatalError()
virtual std::string getMMLString(const std::vector< std::string > &children, bool expand, const std::vector< std::vector< std::string > > &variables) const
virtual std::string getXPPString(const std::vector< std::string > &children) const
virtual std::string getBerkeleyMadonnaString(const std::vector< std::string > &children) const
#define PRECEDENCE_FUNCTION
virtual bool addChild(CCopasiNode< Data > *pChild, CCopasiNode< Data > *pAfter=NULL)
Definition: CCopasiNode.h:156
virtual std::string getDisplayString(const std::vector< std::string > &children) const
virtual ASTNode * toAST(const CCopasiDataModel *pDataModel) const
static Type subType(const Type &type)
virtual std::string getCCodeString(const std::vector< std::string > &children) const
class CEvaluationNode::CPrecedence mPrecedence
#define PRECEDENCE_NUMBER
CCopasiNode< Data > * getChild()
Definition: CCopasiNode.h:210