COPASI API  4.16.103
CTauLeapMethod.cpp
Go to the documentation of this file.
1 // Begin CVS Header
2 // $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/trajectory/CTauLeapMethod.cpp,v $
3 // $Revision: 1.38 $
4 // $Name: $
5 // $Author: shoops $
6 // $Date: 2012/06/04 17:37:43 $
7 // End CVS Header
8 
9 // Copyright (C) 2012 - 2010 by Pedro Mendes, Virginia Tech Intellectual
10 // Properties, Inc., University of Heidelberg, and The University
11 // of Manchester.
12 // All rights reserved.
13 
14 // Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
15 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
16 // and The University of Manchester.
17 // All rights reserved.
18 
19 // Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
20 // Properties, Inc. and EML Research, gGmbH.
21 // All rights reserved.
22 
23 /**
24  * CTauLeapMethod
25  *
26  * This class implements the tau-Leap method for the simulation of a
27  * biochemical system over time (see Gillespie (2001): Approximate
28  * accelerated stochastic simulation of chemically reacting systems.
29  * J. Chemical Physics, 115:1716-1733).
30  *
31  * File name: CTauLeapMethod.cpp
32  * Author: Juergen Pahle
33  * Email: juergen.pahle@eml-r.villa-bosch.de
34  *
35  * Last change: 20, April 2004
36  *
37  * (C) European Media Lab 2004.
38  */
39 
40 /* DEFINE ********************************************************************/
41 
42 #include "copasi.h"
43 
44 #include "CTauLeapMethod.h"
45 #include "CTrajectoryProblem.h"
46 #include "CHybridMethod.h" // CHybridBalance, todo: beautify this
47 #include "model/CModel.h"
48 #include "model/CMetab.h"
49 #include "model/CReaction.h"
50 #include "model/CState.h"
51 #include "model/CChemEq.h"
52 #include "model/CChemEqElement.h"
53 #include "model/CCompartment.h"
55 #include "utilities/CMatrix.h"
59 
61  mSpeciesMultiplier(0),
62  mMethodSpeciesIndex(0),
63  mMethodSpecies(0),
64  mModelSpecies(0),
65  mSubstrateMultiplier(0),
66  mMethodSubstrates(0),
67  mModelSubstrates(0),
68  mpParticleFlux(NULL)
69 {}
70 
72  mSpeciesMultiplier(src.mSpeciesMultiplier),
73  mMethodSpeciesIndex(src.mMethodSpeciesIndex),
74  mMethodSpecies(src.mMethodSpecies),
75  mModelSpecies(src.mModelSpecies),
76  mSubstrateMultiplier(src.mSubstrateMultiplier),
77  mMethodSubstrates(src.mMethodSubstrates),
78  mModelSubstrates(src.mModelSubstrates),
79  mpParticleFlux(src.mpParticleFlux)
80 {}
81 
83 {}
84 
86 {
87  mSpeciesMultiplier = rhs.mSpeciesMultiplier;
88  mMethodSpeciesIndex = rhs.mMethodSpeciesIndex;
89  mMethodSpecies = rhs.mMethodSpecies;
90  mModelSpecies = rhs.mModelSpecies;
91  mSubstrateMultiplier = rhs.mSubstrateMultiplier;
92  mMethodSubstrates = rhs.mMethodSubstrates;
93  mModelSubstrates = rhs.mModelSubstrates;
94  mpParticleFlux = rhs.mpParticleFlux;
95 
96  return * this;
97 }
98 
99 /* PUBLIC METHODS ************************************************************/
100 
101 /**
102  * Default constructor.
103  */
107 {
110 }
111 
113  const CCopasiContainer * pParent):
114  CTrajectoryMethod(src, pParent),
115  mReactionDependencies()
116 {
119 }
120 
121 /**
122  * Destructor.
123  */
125 {
126  cleanup();
128 }
129 
131 {
132  CCopasiParameter *pParm;
133 
135  assertParameter("Max Internal Steps", CCopasiParameter::UINT, (unsigned C_INT32) 10000);
136  assertParameter("Use Random Seed", CCopasiParameter::BOOL, false);
137  assertParameter("Random Seed", CCopasiParameter::UINT, (unsigned C_INT32) 1);
138 
139  // Check whether we have a method with the old parameter names
140  if ((pParm = getParameter("TAULEAP.Tau")) != NULL)
141  {
142  removeParameter("TAULEAP.Tau");
143 
144  if ((pParm = getParameter("TAULEAP.UseRandomSeed")) != NULL)
145  {
146  setValue("Use Random Seed", *pParm->getValue().pBOOL);
147  removeParameter("TAULEAP.UseRandomSeed");
148  }
149 
150  if ((pParm = getParameter("TAULEAP.RandomSeed")) != NULL)
151  {
152  setValue("Random Seed", *pParm->getValue().pUINT);
153  removeParameter("TAULEAP.RandomSeed");
154  }
155  }
156 }
157 
159 {
161  return true;
162 }
163 
165 {
166  // do several steps
167  C_FLOAT64 Time = mpCurrentState->getTime();
168  C_FLOAT64 EndTime = Time + deltaT;
169 
170  size_t Steps = 0;
171 
172  while (Time < EndTime)
173  {
174  mMethodState.setTime(Time);
177 
178  // We do not need to update the the method state since the only independent state
179  // values are species of type reaction which are all controlled by the method.
180 
181  Time += doSingleStep(EndTime - Time);
182 
183  if (++Steps > mMaxSteps)
184  {
186  }
187  }
188 
190  mpCurrentState->setTime(Time);
191 
192  return NORMAL;
193 }
194 
195 void CTauLeapMethod::start(const CState * initialState)
196 {
197  /* get configuration data */
198 
199  bool useRandomSeed = * getValue("Use Random Seed").pBOOL;
200  unsigned C_INT32 randomSeed = * getValue("Random Seed").pUINT;
201 
202  if (useRandomSeed) mpRandomGenerator->initialize(randomSeed);
203 
204  mEpsilon = * getValue("Epsilon").pDOUBLE;
205  mUseRandomSeed = * getValue("Use Random Seed").pBOOL;
206  mRandomSeed = * getValue("Random Seed").pUINT;
207  mMaxSteps = * getValue("Max Internal Steps").pUINT;
208 
209  *mpCurrentState = *initialState;
210 
212  assert(mpModel);
213 
215  mDoCorrection = true;
216  else
217  mDoCorrection = false;
218 
219  // Size the arrays
221 
225  mAmu = 0.0;
226 
228 
231 
232  // Create a local copy of the state where the particle number are rounded to integers
234 
235  const CStateTemplate & StateTemplate = mpModel->getStateTemplate();
236 
237  CModelEntity *const* ppEntity = StateTemplate.beginIndependent();
238  CModelEntity *const* endEntity = StateTemplate.endFixed();
240 
242  size_t Index = 1;
243 
244  for (; ppEntity != endEntity; ++ppEntity, ++pValue, ++Index)
245  {
246  if (dynamic_cast< const CMetab * >(*ppEntity) != NULL)
247  {
248  *pValue = floor(*pValue + 0.5);
249 
250  if (mFirstReactionSpeciesIndex == 0 &&
251  (*ppEntity)->getStatus() == CModelEntity::REACTIONS)
252  {
254  }
255  }
256  }
257 
258  // Update the model state so that the species are all represented by integers.
260  mpModel->updateSimulatedValues(false); //for assignments
261 
262  C_FLOAT64 * pMethodStateValue = mMethodState.beginIndependent() - 1;
263 
264  // Build the reaction dependencies
265  size_t NumReactions = 0;
266 
269  std::vector< CReactionDependencies >::iterator itDependencies = mReactionDependencies.begin();
270 
271  for (; it != end; ++it)
272  {
273  const CCopasiVector<CChemEqElement> & Balances = (*it)->getChemEq().getBalances();
274  const CCopasiVector<CChemEqElement> & Substrates = (*it)->getChemEq().getSubstrates();
275 
276  // This reactions does not change anything we ignore it
277  if (Balances.size() == 0 && Substrates.size() == 0)
278  {
279  continue;
280  }
281 
282  itDependencies->mpParticleFlux = (C_FLOAT64 *)(*it)->getParticleFluxReference()->getValuePointer();
283 
284  itDependencies->mMethodSpeciesIndex.resize(Balances.size());
285  itDependencies->mSpeciesMultiplier.resize(Balances.size());
286  itDependencies->mMethodSpecies.resize(Balances.size());
287  itDependencies->mModelSpecies.resize(Balances.size());
288 
291 
292  Index = 0;
293 
294  for (; itBalance != endBalance; ++itBalance)
295  {
296  const CMetab * pMetab = (*itBalance)->getMetabolite();
297 
298  if (pMetab->getStatus() == CModelEntity::REACTIONS)
299  {
300  itDependencies->mMethodSpeciesIndex[Index] = StateTemplate.getIndex(pMetab) - mFirstReactionSpeciesIndex;
301  itDependencies->mSpeciesMultiplier[Index] = floor((*itBalance)->getMultiplicity() + 0.5);
302  itDependencies->mMethodSpecies[Index] = pMethodStateValue + StateTemplate.getIndex(pMetab);
303  itDependencies->mModelSpecies[Index] = (C_FLOAT64 *) pMetab->getValueReference()->getValuePointer();
304 
305  Index++;
306  }
307  }
308 
309  // Correct allocation for metabolites which are not determined by reactions
310  itDependencies->mMethodSpeciesIndex.resize(Index, true);
311  itDependencies->mSpeciesMultiplier.resize(Index, true);
312  itDependencies->mMethodSpecies.resize(Index, true);
313  itDependencies->mModelSpecies.resize(Index, true);
314 
315  itDependencies->mSubstrateMultiplier.resize(Substrates.size());
316  itDependencies->mMethodSubstrates.resize(Substrates.size());
317  itDependencies->mModelSubstrates.resize(Substrates.size());
318 
319  CCopasiVector< CChemEqElement >::const_iterator itSubstrate = Substrates.begin();
320  CCopasiVector< CChemEqElement >::const_iterator endSubstrate = Substrates.end();
321 
322  Index = 0;
323 
324  for (; itSubstrate != endSubstrate; ++itSubstrate, ++Index)
325  {
326  const CMetab * pMetab = (*itSubstrate)->getMetabolite();
327 
328  itDependencies->mSubstrateMultiplier[Index] = floor((*itSubstrate)->getMultiplicity() + 0.5);
329  itDependencies->mMethodSubstrates[Index] = pMethodStateValue + StateTemplate.getIndex(pMetab);
330  itDependencies->mModelSubstrates[Index] = (C_FLOAT64 *) pMetab->getValueReference()->getValuePointer();
331  }
332 
333  ++itDependencies;
334  ++NumReactions;
335  }
336 
337  mNumReactions = NumReactions;
338 
340  mAmu.resize(mNumReactions, true);
341  mK.resize(mNumReactions, true);
342 
343  return;
344 }
345 
346 /* PROTECTED METHODS *********************************************************/
347 
348 /**
349  * Initializes the solver and sets the model to be used.
350  *
351  * @param model A reference to an instance of a CModel
352  */
353 
354 /**
355  * Cleans up memory, etc.
356  */
358 {
359  delete mpRandomGenerator;
360  mpRandomGenerator = NULL;
361  mpModel = NULL;
362  return;
363 }
364 
365 /**
366  * Simulates the system over the next interval of time. The timestep
367  * is given as argument.
368  *
369  * @param ds A C_FLOAT64 specifying the timestep
370  */
372 {
373  C_FLOAT64 Lambda, Tmp, Tau, Tau1, Tau2;
374 
376 
377  mAvgDX = 0.0;
378  mSigDX = 0.0;
379 
380  std::vector< CReactionDependencies >::const_iterator itReaction = mReactionDependencies.begin();
381  const C_FLOAT64 * pAmu = mAmu.array();
382  const C_FLOAT64 * pAmuEnd = pAmu + mNumReactions;
383 
384  for (; pAmu != pAmuEnd; ++pAmu, ++itReaction)
385  {
386  const C_FLOAT64 * pMultiplicity = itReaction->mSpeciesMultiplier.array();
387  const C_FLOAT64 * pMultiplicityEnd = pMultiplicity + itReaction->mSpeciesMultiplier.size();
388  const size_t * pIndex = itReaction->mMethodSpeciesIndex.array();
389 
390  for (; pMultiplicity != pMultiplicityEnd; ++pMultiplicity, ++pIndex)
391  {
392  mAvgDX[*pIndex] += *pMultiplicity * *pAmu;
393  mSigDX[*pIndex] += *pMultiplicity * *pMultiplicity * *pAmu;
394  }
395  }
396 
397  Tau1 = Tau2 = std::numeric_limits< C_FLOAT64 >::infinity();
398 
400  const C_FLOAT64 * pNumberEnd = pNumber + mNumReactionSpecies;
401  C_FLOAT64 * pAvgDX = mAvgDX.array();
402  C_FLOAT64 * pSigDX = mSigDX.array();
403 
404  for (; pNumber != pNumberEnd; ++pNumber, ++pAvgDX, ++pSigDX)
405  {
406  if ((Tmp = mEpsilon * fabs(*pNumber)) < 1.0)
407  Tmp = 1.0;
408 
409  *pAvgDX = Tmp / fabs(*pAvgDX);
410  *pSigDX = (Tmp * Tmp) / fabs(*pSigDX);
411 
412  if (Tau1 > *pAvgDX)
413  Tau1 = *pAvgDX;
414 
415  if (Tau2 > *pSigDX)
416  Tau2 = *pSigDX;
417  }
418 
419  Tau = std::min(Tau1, Tau2);
420 
421  if (ds < Tau)
422  Tau = ds;
423 
424  pAmu = mAmu.array();
425  C_FLOAT64 * pK = mK.array();
426  C_FLOAT64 * pKEnd = pK + mNumReactions;
427 
428  for (; pAmu != pAmuEnd; ++pAmu, ++pK)
429  {
430  Lambda = *pAmu * Tau;
431 
432  if (Lambda < 0.0)
434  else if (Lambda > 2.0e9)
436 
437  *pK = mpRandomGenerator->getRandomPoisson(Lambda);
438  }
439 
440  while (!updateSystem())
441  {
442  Tau *= 0.5;
443  pK = mK.array();
444 
445  for (; pK != pKEnd; ++pK)
446  {
447  *pK *= 0.5;
448 
449  if (*pK < floor(*pK + 0.75))
450  {
451  *pK += mpRandomGenerator->getRandomCC() < 0.5 ? - 0.5 : 0.5;
452  }
453  }
454  }
455 
456 
457  return Tau;
458 }
459 
461 {
462  //mA0Old = mA0;
463  mA0 = 0;
464 
465  for (size_t i = 0; i < mNumReactions; i++)
466  {
467  mA0 += calculateAmu(i);
468  }
469 
470  return;
471 }
472 
473 const C_FLOAT64 & CTauLeapMethod::calculateAmu(const size_t & index)
474 {
475  const CReactionDependencies & Dependencies = mReactionDependencies[index];
476  C_FLOAT64 & Amu = mAmu[index];
477 
478  Amu = *Dependencies.mpParticleFlux;
479 
480  if (Amu < 0.0)
481  {
482  // TODO CRITICAL Create a warning message
483  Amu = 0.0;
484  }
485 
486  if (!mDoCorrection)
487  {
488  return Amu;
489  }
490 
491  C_FLOAT64 SubstrateMultiplier = 1.0;
492  C_FLOAT64 SubstrateDevisor = 1.0;
493  C_FLOAT64 Multiplicity;
494  C_FLOAT64 LowerBound;
495  C_FLOAT64 Number;
496 
497  bool ApplyCorrection = false;
498 
499  const C_FLOAT64 * pMultiplicity = Dependencies.mSubstrateMultiplier.array();
500  const C_FLOAT64 * pEndMultiplicity = pMultiplicity + Dependencies.mSubstrateMultiplier.size();
501  C_FLOAT64 *const* ppLocalSubstrate = Dependencies.mMethodSubstrates.array();
502  C_FLOAT64 *const* ppModelSubstrate = Dependencies.mModelSubstrates.array();
503 
504  for (; pMultiplicity != pEndMultiplicity; ++pMultiplicity, ++ppLocalSubstrate, ++ppModelSubstrate)
505  {
506  Multiplicity = *pMultiplicity;
507 
508  // TODO We should check the error introduced through rounding.
509  **ppLocalSubstrate = floor(**ppModelSubstrate + 0.5);
510 
511  if (Multiplicity > 1.01)
512  {
513  ApplyCorrection = true;
514 
515  Number = **ppLocalSubstrate;
516 
517  LowerBound = Number - Multiplicity;
518  SubstrateDevisor *= pow(Number, Multiplicity - 1.0); //optimization
519  Number -= 1.0;
520 
521  while (Number > LowerBound)
522  {
523  SubstrateMultiplier *= Number;
524  Number -= 1.0;
525  }
526  }
527  }
528 
529  // at least one substrate particle number is zero
530  if (SubstrateMultiplier < 0.5 || SubstrateDevisor < 0.5)
531  {
532  Amu = 0.0;
533  }
534  else if (ApplyCorrection)
535  {
536  Amu *= SubstrateMultiplier / SubstrateDevisor;
537  }
538 
539  return Amu;
540 }
541 
542 /**
543  * Updates the system according to the probabilistic
544  * number of firings mK[i] of each reaction i
545  */
547 {
548  std::vector< CReactionDependencies >::const_iterator itReaction = mReactionDependencies.begin();
549 
550  CState OldState(mMethodState);
551 
552  const C_FLOAT64 * pK = mK.array();
553  const C_FLOAT64 * pKEnd = pK + mNumReactions;
554 
555  for (; pK != pKEnd; ++pK, ++itReaction)
556  {
557  const C_FLOAT64 * pMultiplicity = itReaction->mSpeciesMultiplier.array();
558  const C_FLOAT64 * pMultiplicityEnd = pMultiplicity + itReaction->mSpeciesMultiplier.size();
559  C_FLOAT64 * const * pSpecies = itReaction->mMethodSpecies.array();
560 
561  for (; pMultiplicity != pMultiplicityEnd; ++pMultiplicity, ++pSpecies)
562  {
563  **pSpecies += *pK * *pMultiplicity;
564  }
565  }
566 
568 
569  const C_FLOAT64 * pSpeciesEnd = pSpecies + mNumReactionSpecies;
570 
571  for (; pSpecies != pSpeciesEnd; ++pSpecies)
572  {
573  if (*pSpecies < -0.5)
574  {
575  // We need to undo the changes
576  mMethodState = OldState;
577  return false;
578  }
579  }
580 
581  return true;
582 }
583 
584 //virtual
586 {
587  if (!CTrajectoryMethod::isValidProblem(pProblem)) return false;
588 
589  const CTrajectoryProblem * pTP = dynamic_cast<const CTrajectoryProblem *>(pProblem);
590 
591  if (pTP->getDuration() < 0.0)
592  {
593  //back integration not possible
595  return false;
596  }
597 
598  if (pTP->getModel()->getTotSteps() < 1)
599  {
600  //at least one reaction necessary
602  return false;
603  }
604 
605  //check for ODE rules
606  size_t i, imax = pTP->getModel()->getNumModelValues();
607 
608  for (i = 0; i < imax; ++i)
609  {
610  if (pTP->getModel()->getModelValues()[i]->getStatus() == CModelEntity::ODE)
611  {
612  //ode rule found
614  return false;
615  }
616  }
617 
618  imax = pTP->getModel()->getNumMetabs();
619 
620  for (i = 0; i < imax; ++i)
621  {
622  if (pTP->getModel()->getMetabolites()[i]->getStatus() == CModelEntity::ODE)
623  {
624  //ode rule found
626  return false;
627  }
628  }
629 
630  imax = pTP->getModel()->getCompartments().size();
631 
632  for (i = 0; i < imax; ++i)
633  {
634  if (pTP->getModel()->getCompartments()[i]->getStatus() == CModelEntity::ODE)
635  {
636  //ode rule found
638  return false;
639  }
640  }
641 
642  //TODO: rewrite CModel::suitableForStochasticSimulation() to use
643  // CCopasiMessage
644  std::string message = pTP->getModel()->suitableForStochasticSimulation();
645 
646  if (message != "")
647  {
648  //model not suitable, message describes the problem
649  CCopasiMessage(CCopasiMessage::ERROR, message.c_str());
650  return false;
651  }
652 
653  //events are not supported at the moment
654  if (pTP->getModel()->getEvents().size() > 0)
655  {
657  return false;
658  }
659 
660  return true;
661 }
C_FLOAT64 mEpsilon
CCopasiVectorN< CEvent > & getEvents()
Definition: CModel.cpp:1110
const CCopasiVector< CMetab > & getMetabolites() const
Definition: CModel.cpp:1051
CVector< C_FLOAT64 > mSpeciesMultiplier
CVector< C_FLOAT64 * > mMethodSubstrates
const CCopasiVectorN< CModelValue > & getModelValues() const
Definition: CModel.cpp:1060
virtual size_t size() const
void initializeParameter()
size_t getNumMetabs() const
Definition: CModel.cpp:1118
iterator begin()
void updateSimulatedValues(const bool &updateMoieties)
Definition: CModel.cpp:1851
CVector< C_FLOAT64 > mK
Definition: CState.h:305
CTrajectoryProblem * mpProblem
void resize(size_t size, const bool &copy=false)
Definition: CVector.h:301
size_t mFirstReactionSpeciesIndex
CReactionDependencies & operator=(const CReactionDependencies &rhs)
size_t getIndex(const CModelEntity *entity) const
Definition: CState.cpp:231
CVector< C_FLOAT64 * > mMethodSpecies
C_FLOAT64 doSingleStep(C_FLOAT64 ds)
#define C_INT32
Definition: copasi.h:90
Definition: CMetab.h:178
virtual bool isValidProblem(const CCopasiProblem *pProblem)
void setTime(const C_FLOAT64 &time)
Definition: CState.cpp:326
const C_FLOAT64 & calculateAmu(const size_t &index)
size_t getTotSteps() const
Definition: CModel.cpp:1136
bool removeParameter(const std::string &name)
#define MCTrajectoryMethod
#define DESTRUCTOR_TRACE
Definition: copasi.h:206
iterator end()
std::vector< CType * >::const_iterator const_iterator
Definition: CCopasiVector.h:57
std::vector< CReactionDependencies > mReactionDependencies
static CRandom * createGenerator(CRandom::Type type=CRandom::mt19937, unsigned C_INT32 seed=0)
Definition: CRandom.cpp:49
virtual C_FLOAT64 getRandomPoisson(const C_FLOAT64 &mean)
Definition: CRandom.cpp:314
virtual C_FLOAT64 getRandomCC()
Definition: CRandom.cpp:235
size_t getNumDependentReactionMetabs() const
Definition: CModel.cpp:1133
CModelEntity ** endFixed()
Definition: CState.cpp:213
void setState(const CState &state)
Definition: CModel.cpp:1785
unsigned C_INT32 mMaxSteps
const C_FLOAT64 & getDuration() const
const Value & getValue() const
CVector< C_FLOAT64 > mAmu
bool setValue(const std::string &name, const CType &value)
unsigned C_INT32 * pUINT
virtual Status step(const double &deltaT)
CModelEntity ** beginIndependent()
Definition: CState.cpp:208
CCopasiParameter * getParameter(const std::string &name)
CTauLeapMethod(const CTauLeapMethod &src, const CCopasiContainer *pParent=NULL)
size_t getNumIndependentReactionMetabs() const
Definition: CModel.cpp:1130
CRandom * mpRandomGenerator
size_t size() const
Definition: CVector.h:100
CVector< C_FLOAT64 > mSigDX
CCopasiVectorNS< CCompartment > & getCompartments()
Definition: CModel.cpp:1145
const C_FLOAT64 & getTime() const
Definition: CState.cpp:325
CVector< C_FLOAT64 * > mModelSubstrates
#define C_FLOAT64
Definition: copasi.h:92
CType * array()
Definition: CVector.h:139
const CStateTemplate & getStateTemplate() const
Definition: CModel.cpp:1172
size_t getNumModelValues() const
Definition: CModel.cpp:1139
const ModelType & getModelType() const
Definition: CModel.cpp:2339
size_t mNumReactionSpecies
CCopasiVectorNS< CReaction > & getReactions()
Definition: CModel.cpp:1039
virtual void * getValuePointer() const
CCopasiParameter * assertParameter(const std::string &name, const CCopasiParameter::Type type, const CType &defaultValue)
CVector< C_FLOAT64 > mAvgDX
unsigned C_INT32 mRandomSeed
const CState & getState() const
Definition: CModel.cpp:1771
const CModelEntity::Status & getStatus() const
virtual bool elevateChildren()
virtual bool isValidProblem(const CCopasiProblem *pProblem)
CVector< C_FLOAT64 > mSubstrateMultiplier
std::string suitableForStochasticSimulation() const
Definition: CModel.cpp:3901
virtual void start(const CState *initialState)
CModel * getModel() const
#define min(a, b)
Definition: f2c.h:175
C_FLOAT64 * beginIndependent()
Definition: CState.cpp:328
virtual void initialize(unsigned C_INT32 seed=CRandom::getSystemSeed())
Definition: CRandom.cpp:162
CVector< C_FLOAT64 * > mModelSpecies
CCopasiObject * getValueReference() const