COPASI API  4.16.103
CMathExpression.cpp
Go to the documentation of this file.
1 // Copyright (C) 2011 - 2013 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 #include "copasi.h"
7 
8 #include "CMathExpression.h"
9 #include "CMathContainer.h"
10 
11 #include "function/CExpression.h"
12 #include "function/CFunction.h"
15 
16 #include "utilities/CCopasiTree.h"
17 
18 #define mpContainer static_cast< const CMathContainer * >(getObjectParent())
19 
22  mPrerequisites()
23 {}
24 
25 CMathExpression::CMathExpression(const std::string & name,
26  CMathContainer & container):
27  CEvaluationTree(name, &container, CEvaluationTree::MathExpression),
28  mPrerequisites()
29 {}
30 
32  CMathContainer & container,
33  const bool & replaceDiscontinuousNodes):
34  CEvaluationTree(src.getObjectName(), &container, CEvaluationTree::MathExpression),
35  mPrerequisites()
36 {
37  // Create a converted copy of the existing expression tree.
38  mpRoot = container.copyBranch(src.getRoot(), replaceDiscontinuousNodes);
39 
40  compile();
41 }
42 
44  const CCallParameters< C_FLOAT64 > & callParameters,
45  CMathContainer & container,
46  const bool & replaceDiscontinuousNodes):
47  CEvaluationTree(src.getObjectName(), &container, CEvaluationTree::MathExpression),
48  mPrerequisites()
49 {
50  // Deal with the different function types
51  switch (src.getType())
52  {
56  {
57  // Create a vector of CEvaluationNodeObject for each variable
59 
62 
63  for (; it != end; ++it)
64  {
65  Variables.push_back(createNodeFromValue(it->value));
66  }
67 
68  // Create a converted copy of the existing expression tree.
69  mpRoot = container.copyBranch(src.getRoot(), Variables, replaceDiscontinuousNodes);
70  }
71 
72  break;
73 
75  {
76  // We build a mass action expression based on the call parameters.
78 
79  // We always have reactants
80  const C_FLOAT64 * pK = it->value;
81  ++it;
82  const CCallParameters< C_FLOAT64 > * pSpecies = it->vector;
83  ++it;
84 
85  CEvaluationNode * pPart = createMassActionPart(pK, pSpecies);
86 
87  if (it != callParameters.end())
88  {
90  mpRoot->addChild(pPart);
91 
92  pK = it->value;
93  ++it;
94  pSpecies = it->vector;
95  ++it;
96 
97  pPart = createMassActionPart(pK, pSpecies);
98 
99  mpRoot->addChild(pPart);
100  }
101  else
102  {
103  mpRoot = pPart;
104  }
105  }
106  break;
107 
110  // This cannot happen and is only here to satisfy the compiler.
111  break;
112  }
113 
114  compile();
115 }
116 
117 // virtual
119 {}
120 
121 // static
123  CMathContainer & container,
124  const size_t & valueOffset,
125  const size_t & objectOffset)
126 {
127  CMathExpression * pExpression = new CMathExpression(src.getObjectName(), container);
128 
129  pExpression->setRoot(src.getRoot()->copyBranch());
130 
131  // Apply the offset to all nodes
134 
135  for (; it != end; ++it)
136  {
138  {
139  C_FLOAT64 * pPointer = (C_FLOAT64 *) stringToPointer(it->getData());
140  static_cast< CEvaluationNodeObject * >(&*it)->setObjectValuePtr((C_FLOAT64 *)((size_t) pPointer + valueOffset));
141  }
142  }
143 
144  pExpression->compile();
145 
146  return pExpression;
147 }
148 
150 {
151  calculate();
152 
153  return mValue;
154 }
155 
156 // virtual
158 {
159  return mPrerequisites;
160 }
161 
162 // virtual
164 {
165  mPrerequisites.clear();
166  mUsable = true;
167 
168  if (!updateTree())
169  {
170  mUsable = false;
171  mCalculationSequence.clear();
172 
173  return mUsable;
174  }
175 
176  std::vector< CEvaluationNode * >::iterator it = mpNodeList->begin();
177  std::vector< CEvaluationNode * >::iterator end = mpNodeList->end();
178 
179  for (; it != end; ++it)
180  {
181  mUsable &= (*it)->compile(this);
182 
183  if ((*it)->getType() == (CEvaluationNode::OBJECT | CEvaluationNodeObject::POINTER))
184  {
185  void * pValue = stringToPointer((*it)->getData());
186 
187  // TODO CRITICAL It is possible that the user selects non model objects, i.e.,
188  // problem or method values within the expression. These cannot be mapped to a
189  // math objects and therefore dependencies will be broken.
190 
191  CMathObject * pMathObject = mpContainer->getMathObject((C_FLOAT64 *) pValue);
192 
193  if (pMathObject != NULL)
194  {
195  mPrerequisites.insert(pMathObject);
196  }
197  else
198  {
199  // For the moment we stop.
200  assert(false);
201  }
202  }
203  }
204 
205  if (mInfix == "@")
206  {
207  mUsable = true;
208  }
209 
211 
212  return mUsable;
213 }
214 
216 {
217  if (getObjectName().substr(0, 7) != "Initial")
218  {
219  setObjectName("Initial" + getObjectName());
220  }
221 
222  if (mpNodeList == NULL)
223  {
224  return false;
225  }
226 
227  std::vector< CEvaluationNode * >::iterator it = mpNodeList->begin();
228  std::vector< CEvaluationNode * >::iterator end = mpNodeList->end();
229  bool changed = false;
230 
231  for (; it != end; ++it)
232  {
233  if ((*it)->getType() == (CEvaluationNode::OBJECT | CEvaluationNodeObject::POINTER))
234  {
235  CEvaluationNodeObject * pNode = static_cast< CEvaluationNodeObject *>(*it);
236  const C_FLOAT64 * pValue = pNode->getObjectValuePtr();
237  C_FLOAT64 * pInitialValue = mpContainer->getInitialValuePointer(pValue);
238 
239  if (pValue != pInitialValue)
240  {
241  changed = true;
242  pNode->setObjectValuePtr(pInitialValue);
243 
244  mPrerequisites.erase(mpContainer->getMathObject(pValue));
245  mPrerequisites.insert(mpContainer->getMathObject(pInitialValue));
246  }
247  }
248  }
249 
250  if (changed)
251  {
252  mInfix = mpRoot->buildInfix();
253  }
254 
255  return true;
256 }
257 
259 {
260  return CEvaluationTree::setRoot(pRootNode);
261 }
262 
264 {
265  CEvaluationNode * pNode = NULL;
266  CMathObject * pMathObject = NULL;
267 
268  if (pDataValue != NULL)
269  {
270  pMathObject = mpContainer->getMathObject(pDataValue);
271 
272  if (pMathObject != NULL)
273  {
274  pNode = new CEvaluationNodeObject((C_FLOAT64 *) pMathObject->getValuePointer());
275  }
276  else
277  {
278  // We must have a constant value like the conversion factor from the model.
279  pNode = new CEvaluationNodeNumber(*pDataValue);
280  }
281  }
282  else
283  {
284  // We have an invalid value, i.e. NaN
286  }
287 
288  return pNode;
289 }
290 
292  const CCallParameters< C_FLOAT64 > * pSpecies)
293 {
295  pPart->addChild(createNodeFromValue(pK));
296 
297  CEvaluationNode * pNode = pPart;
298  CCallParameters< C_FLOAT64 >::const_iterator itSpecies = pSpecies->begin();
299  CCallParameters< C_FLOAT64 >::const_iterator endSpecies = pSpecies->end();
300 
301  for (; itSpecies != endSpecies - 1; ++itSpecies)
302  {
304  p->addChild(createNodeFromValue(itSpecies->value));
305  pNode->addChild(p);
306  pNode = p;
307  }
308 
309  pNode->addChild(createNodeFromValue(itSpecies->value));
310 
311  return pPart;
312 }
Header file of class CExpression.
virtual bool setRoot(CEvaluationNode *pRootNode)
const_iterator begin() const
CEvaluationNode * copyBranch() const
CEvaluationNode * createNodeFromValue(const C_FLOAT64 *pDataValue)
virtual const CObjectInterface::ObjectSet & getPrerequisites() const
std::vector< CEvaluationNode * > * mpNodeList
const std::string & getObjectName() const
void setObjectValuePtr(C_FLOAT64 *pObjectValue)
std::string buildInfix() const
const CEvaluationTree::Type & getType() const
CEvaluationNode * copyBranch(const CEvaluationNode *pSrc, const bool &replaceDiscontinuousNodes)
std::string mInfix
std::vector< CEvaluationNode * > mCalculationSequence
virtual void * getValuePointer() const
void buildCalculationSequence()
virtual bool addChild(CCopasiNode< Data > *pChild, CCopasiNode< Data > *pAfter=NULL)
Definition: CCopasiNode.h:156
#define mpContainer
const C_FLOAT64 & value()
bool convertToInitialExpression()
virtual bool compile()
std::set< const CObjectInterface * > ObjectSet
static CMathExpression * copy(const CMathExpression &src, CMathContainer &container, const size_t &valueOffset, const size_t &objectOffset)
const C_FLOAT64 * getObjectValuePtr() const
#define C_FLOAT64
Definition: copasi.h:92
void * stringToPointer(const std::string str)
Definition: utility.cpp:414
CObjectInterface::ObjectSet mPrerequisites
The class for handling a chemical kinetic function.
Definition: CFunction.h:29
const_iterator end() const
CEvaluationNode * createMassActionPart(const C_FLOAT64 *pK, const CCallParameters< C_FLOAT64 > *pSpecies)
bool setObjectName(const std::string &name)
virtual ~CMathExpression()
virtual bool setRoot(CEvaluationNode *pRootNode)
CEvaluationNode * getRoot()
CEvaluationNode * mpRoot