Beispiel #1
0
// virtual
bool CConcentrationReference::isPrerequisiteForContext(const CObjectInterface * pObject,
    const CMath::SimulationContextFlag & /* context */,
    const CObjectInterface::ObjectSet & changedObjects) const
{
  // If the value is in the context, it does not depend on the object.
  if (changedObjects.find(this) != changedObjects.end())
    return false;

  // Densities which are not in the context have to be recalculated.
  return true;
}
Beispiel #2
0
bool CCopasiObject::isPrerequisiteForContext(const CObjectInterface * pObject,
    const CMath::SimulationContextFlag & /* context */,
    const CObjectInterface::ObjectSet & changedObjects) const
{
  // If the object is among the changed objects it does not depend on anything else.
  if (changedObjects.find(this) != changedObjects.end())
    return false;

#ifdef COPASI_DEBUG
  const CObjectInterface::ObjectSet & Prerequisites = getPrerequisites();

  // This method should only be called for objects which are prerequisites.
  // We check for this only in debug mode.
  assert(Prerequisites.find(pObject) != Prerequisites.end());
#endif // COPASI_DEBUG

  return true;
}
Beispiel #3
0
void CMathDelay::createUpdateSequences()
{
  // The requested objects are all delay values
  CObjectInterface::ObjectSet Requested;

  CMathObject **pObject = mValueObjects.array();
  CMathObject **pObjectEnd = pObject + mValueObjects.size();

  for (; pObject != pObjectEnd; ++pObject)
    if (*pObject != NULL)
      {
        Requested.insert(*pObject);
      }

  mpContainer->getTransientDependencies().getUpdateSequence(mValueSequence, CMath::DelayValues,
      mpContainer->getStateObjects(false), Requested);
  mpContainer->getTransientDependencies().getUpdateSequence(mValueSequenceReduced, CMath::UseMoieties | CMath::DelayValues,
      mpContainer->getStateObjects(true), Requested);
}
Beispiel #4
0
/**
 *   Sets up the dependency graph.
 */
void CHybridMethod::setupDependencyGraph()
{
  mDG.clear();
  size_t numReactions = mReactions.size();
  size_t i, j;

  CObjectInterface::ObjectSet PropensityObjects;

  for (i = 0; i < numReactions; i++)
    {
      PropensityObjects.insert(mReactions[i].getPropensityObject());
    }

  // Do for each reaction:
  for (i = 0; i < numReactions; i++)
    {
      CObjectInterface::ObjectSet ChangedObjects;

      CMathReaction & reaction = mReactions[i];

      CMathReaction::ObjectBalance::const_iterator itBalance = reaction.getObjectBalance().begin();
      CMathReaction::ObjectBalance::const_iterator endBalance = reaction.getObjectBalance().end();

      for (; itBalance != endBalance; ++itBalance)
        {
          ChangedObjects.insert(itBalance->first);
        }

      mpContainer->getTransientDependencies().getUpdateSequence(mUpdateSequences[i], CMath::Default, ChangedObjects, PropensityObjects);

      for (j = 0; j < numReactions; j++)
        {
          if (mpContainer->getTransientDependencies().dependsOn(mReactions[j].getPropensityObject(), CMath::Default, ChangedObjects))
            {
              mDG.addDependent(i, j);
            }
        }
    }

  return;
}
Beispiel #5
0
// virtual
bool CParticleReference::isPrerequisiteForContext(const CObjectInterface * pObject,
    const CMath::SimulationContextFlag & context ,
    const CObjectInterface::ObjectSet & changedObjects) const
{
  const CMetab * pSpecies = static_cast< const CMetab * >(getObjectParent());

  if ((context & CMath::UseMoieties) &&
      pSpecies->isDependent())
    {
      return true;
    }

  // If the value is changed it must not be recalculated, i.e., it does not depend on the object.
  if (changedObjects.find(this) != changedObjects.end())
    return false;

  // Amounts which are determine by assignment need to be recalculated.
  if (pSpecies->getStatus() == CModelEntity::ASSIGNMENT)
    return true;

  const CConcentrationReference * pConcentrationReference = NULL;

  if (getObjectName() != "ParticleNumber")
    {
      pConcentrationReference = pSpecies->getInitialConcentrationReference();
    }
  else
    {
      pConcentrationReference = pSpecies->getConcentrationReference();
    }

  // If the concentration was changed in the context we need to recalculate.
  if (changedObjects.find(pConcentrationReference) != changedObjects.end())
    return true;

  return false;
}
Beispiel #6
0
void CStochDirectMethod::start()
{
  CTrajectoryMethod::start();

  /* get configuration data */
  mMaxSteps = getValue< C_INT32 >("Max Internal Steps");

  mpRandomGenerator = &mpContainer->getRandomGenerator();

  if (getValue< bool >("Use Random Seed"))
    {
      mpRandomGenerator->initialize(getValue< unsigned C_INT32 >("Random Seed"));
    }

  //mpCurrentState is initialized. This state is not used internally in the
  //stochastic solver, but it is used for returning the result after each step.

  //========Initialize Roots Related Arguments========
  mNumRoot = mpContainer->getRoots().size();
  mRootsFound.resize(mNumRoot);
  mRootsA.resize(mNumRoot);
  mRootsB.resize(mNumRoot);
  mpRootValueNew = &mRootsA;
  mpRootValueOld = &mRootsB;
  mRootsNonZero.resize(mNumRoot);
  mRootsNonZero = 0.0;

  CMathObject * pRootObject = mpContainer->getMathObject(mpContainer->getRoots().array());
  CMathObject * pRootObjectEnd = pRootObject + mNumRoot;

  CObjectInterface::ObjectSet Requested;

  for (; pRootObject != pRootObjectEnd; ++pRootObject)
    {
      Requested.insert(pRootObject);
    }

  CObjectInterface::ObjectSet Changed;

  // Determine whether we have time dependent roots;

  CObjectInterface * pTimeObject = mpContainer->getMathObject(mpContainerStateTime);
  Changed.insert(pTimeObject);

  mpContainer->getTransientDependencies().getUpdateSequence(mUpdateTimeDependentRoots, CMath::Default, Changed, Requested);
  mHaveTimeDependentRoots = (mUpdateTimeDependentRoots.size() > 0);

  // Build the reaction dependencies
  mReactions.initialize(mpContainer->getReactions());
  mNumReactions = mReactions.size();
  mAmu.initialize(mpContainer->getPropensities());
  mPropensityObjects.initialize(mAmu.size(), mpContainer->getMathObject(mAmu.array()));
  mUpdateSequences.resize(mNumReactions);

  CMathReaction * pReaction = mReactions.array();
  CMathReaction * pReactionEnd = pReaction + mNumReactions;
  CObjectInterface::UpdateSequence * pUpdateSequence = mUpdateSequences.array();
  CMathObject * pPropensityObject = mPropensityObjects.array();
  CMathObject * pPropensityObjectEnd = pPropensityObject + mPropensityObjects.size();

  for (; pPropensityObject != pPropensityObjectEnd; ++pPropensityObject)
    {
      Requested.insert(pPropensityObject);
    }

  pPropensityObject = mPropensityObjects.array();

  for (; pReaction  != pReactionEnd; ++pReaction, ++pUpdateSequence, ++pPropensityObject)
    {
      Changed = pReaction->getChangedObjects();

      // The time is always updated
      Changed.insert(pTimeObject);

      pUpdateSequence->clear();
      mpContainer->getTransientDependencies().getUpdateSequence(*pUpdateSequence, CMath::Default, Changed, Requested);
    }

  mMaxStepsReached = false;

  mTargetTime = *mpContainerStateTime;
  mNextReactionTime = *mpContainerStateTime;
  mNextReactionIndex = C_INVALID_INDEX;

  stateChange(CMath::State);

  return;
}
// virtual
void CTrajectoryMethodDsaLsodar::start()
{
  CLsodaMethod::start();

  mReactions.initialize(mpContainer->getReactions());
  mNumReactions = mReactions.size();
  mAmu.initialize(mpContainer->getPropensities());
  mPropensityObjects.initialize(mNumReactions, mpContainer->getMathObject(mAmu.array()));
  mUpdateSequences.resize(mNumReactions);
  mFirstReactionSpeciesIndex = mpContainer->getCountFixedEventTargets() + 1 /* Time */ + mpContainer->getCountODEs();

  // Create a local copy of the state where the particle number species determined
  // by reactions are rounded to integers.
  C_FLOAT64 * pValue = mContainerState.array() + mFirstReactionSpeciesIndex;
  C_FLOAT64 * pValueEnd = pValue + mpContainer->getCountIndependentSpecies() + mpContainer->getCountDependentSpecies();

  for (; pValue != pValueEnd; ++pValue)
    {
      *pValue = floor(*pValue + 0.5);
    }

  // The container state is now up to date we just need to calculate all values needed for simulation.
  mpContainer->updateSimulatedValues(false);

  CMathObject * pTimeObject = mpContainer->getMathObject(mpContainer->getModel().getValueReference());

  // Build the reaction dependencies
  mReactions.initialize(mpContainer->getReactions());
  mNumReactions = mReactions.size();
  mAmu.initialize(mpContainer->getPropensities());
  mPropensityObjects.initialize(mAmu.size(), mpContainer->getMathObject(mAmu.array()));
  mUpdateSequences.resize(mNumReactions);

  C_FLOAT64 * pAmu = mAmu.array();
  mA0 = 0.0;

  CMathReaction * pReaction = mReactions.array();
  CMathReaction * pReactionEnd = pReaction + mNumReactions;
  CCore::CUpdateSequence * pUpdateSequence;
  CMathObject * pPropensityObject = mPropensityObjects.array();
  CMathObject * pPropensityObjectEnd = pPropensityObject + mPropensityObjects.size();

  CObjectInterface::ObjectSet Requested;

  for (; pPropensityObject != pPropensityObjectEnd; ++pPropensityObject)
    {
      Requested.insert(pPropensityObject);
    }

  pPropensityObject = mPropensityObjects.array();

  for (; pReaction  != pReactionEnd; ++pReaction, ++pUpdateSequence, ++pPropensityObject, ++pAmu)
    {
      // Update the propensity
      pPropensityObject->calculateValue();
      mA0 += *pAmu;

      CObjectInterface::ObjectSet Changed;

      // The time is always updated
      Changed.insert(pTimeObject);

      const CMathReaction::SpeciesBalance * itBalance = pReaction->getNumberBalance().array();
      const CMathReaction::SpeciesBalance * endBalance = itBalance + pReaction->getNumberBalance().size();

      for (; itBalance != endBalance; ++itBalance)
        {
          Changed.insert(mpContainer->getMathObject(itBalance->first));
        }

      pUpdateSequence->clear();
      mpContainer->getTransientDependencies().getUpdateSequence(*pUpdateSequence, CCore::SimulationContext::Default, Changed, Requested);
    }

  mPartition.intialize(mpContainer, *mpLowerLimit, *mpUpperLimit);

  return;
}
Beispiel #8
0
// virtual
bool CMathObject::isPrerequisiteForContext(const CObjectInterface * pObject,
    const CMath::SimulationContextFlag & context,
    const CObjectInterface::ObjectSet & changedObjects) const
{
  // This method should only be called for objects which are prerequisites.
  // We check for this only in debug mode.
  assert(mPrerequisites.find(pObject) != mPrerequisites.end());

  switch (mEntityType)
    {
      case CMath::Moiety:

        if ((context & CMath::UpdateMoieties) &&
            mValueType == CMath::TotalMass)
          {
            return true;
          }

        if ((context & CMath::UseMoieties) &&
            mValueType == CMath::DependentMass)
          {
            return true;
          }

        return false;
        break;

      case CMath::Species:

        // For species we need to account for the duality of the intensive and extensive value
        if (mValueType != CMath::Value)
          return true;

        if ((context & CMath::UseMoieties) &&
            mSimulationType == CMath::Dependent &&
            !mIsIntensiveProperty)
          {
            if (mpCorrespondingProperty != pObject)
              {
                return true;
              }

            return false;
          }

        // If the value is in the context, it does not depend on the object.
        if (changedObjects.find(this) != changedObjects.end())
          return false;

        if (mIsIntensiveProperty)
          {
            // Densities which are not in the context have to be recalculated.
            return true;
          }
        else
          {
            // Amount which are determine by assignment need to be recalculated.
            if (mSimulationType == CMath::Assignment)
              return true;

            // If the concentration was changed in the context we need to recalculate.
            if (changedObjects.find(mpCorrespondingProperty) != changedObjects.end())
              return true;

            // If the concentration is calculated by an assignment we need to recalculate.
            if (mpCorrespondingProperty->getSimulationType() == CMath::Assignment)
              return true;

            return false;
          }

        break;

      case CMath::Event:

        if ((context & CMath::EventHandling) &&
            mValueType == CMath::Discontinuous)
          {
            switch ((int) mpExpression->getRoot()->getType())
              {
                case (CEvaluationNode::CHOICE | CEvaluationNodeChoice::IF):
                {
                  const CMathObject * pMathObject = dynamic_cast< const CMathObject * >(pObject);

                  if (pMathObject != NULL &&
                      pMathObject->mValueType == CMath::EventTrigger)
                    {
                      return false;
                    }

                  return true;
                }
                break;

                case (CEvaluationNode::FUNCTION | CEvaluationNodeFunction::FLOOR):
                  return false;
                  break;

                case (CEvaluationNode::FUNCTION | CEvaluationNodeFunction::CEIL):
                  return false;
                  break;

                default:
                  return true;
              }
          }

        return true;
        break;

      case CMath::Delay:

        if (context & CMath::EventHandling)
          {
            return true;
          }

        return (mValueType == CMath::DelayLag);

        break;

      default:
        return true;
    }

  // This should never be reached.
  return true;
}
Beispiel #9
0
bool CExperimentSet::compile(const CMathContainer * pMathContainer)
{
  bool success = true;

  // First we need to sort the experiments so that we can make use of continued
  // file reading.
  sort();

  CObjectInterface::ObjectSet DependentObjects;

  std::ifstream in;
  std::string CurrentFileName("");
  size_t CurrentLineNumber = 1;

  std::vector< CExperiment * >::iterator it = mpExperiments->begin() + mNonExperiments;
  std::vector< CExperiment * >::iterator end = mpExperiments->end();

  for (; it != end; ++it)
    {
      if (CurrentFileName != (*it)->getFileName())
        {
          CurrentFileName = (*it)->getFileName();
          CurrentLineNumber = 1;

          if (in.is_open())
            {
              in.close();
              in.clear();
            }

          in.open(CLocaleString::fromUtf8(CurrentFileName).c_str(), std::ios::binary);

          if (in.fail())
            {
              CCopasiMessage(CCopasiMessage::ERROR, MCFitting + 8, CurrentFileName.c_str());
              return false; // File can not be opened.
            }
        }

      if (!(*it)->read(in, CurrentLineNumber))
        {
          return false;
        }

      if (!(*it)->compile(pMathContainer))
        {
          return false;
        }

      const std::map< const CObjectInterface *, size_t > & ExpDependentObjects = (*it)->getDependentObjectsMap();
      std::map< const CObjectInterface *, size_t >::const_iterator itObject  = ExpDependentObjects.begin();
      std::map< const CObjectInterface *, size_t >::const_iterator endObject = ExpDependentObjects.end();

      for (; itObject != endObject; ++itObject)
        {
          DependentObjects.insert(itObject->first);
        }
    }

  mDependentObjects.resize(DependentObjects.size());
  const CObjectInterface ** ppInsert = mDependentObjects.array();
  CObjectInterface::ObjectSet::const_iterator itObject = DependentObjects.begin();
  CObjectInterface::ObjectSet::const_iterator endObject = DependentObjects.end();

  for (; itObject != endObject; ++itObject, ++ppInsert)
    *ppInsert = *itObject;

  // Allocation and initialization of statistical information
  mDependentObjectiveValues.resize(mDependentObjects.size());
  mDependentObjectiveValues = std::numeric_limits<C_FLOAT64>::quiet_NaN();

  mDependentRMS.resize(mDependentObjects.size());
  mDependentRMS = std::numeric_limits<C_FLOAT64>::quiet_NaN();

  mDependentErrorMean.resize(mDependentObjects.size());
  mDependentErrorMean = std::numeric_limits<C_FLOAT64>::quiet_NaN();

  mDependentErrorMeanSD.resize(mDependentObjects.size());
  mDependentErrorMeanSD = std::numeric_limits<C_FLOAT64>::quiet_NaN();

  mDependentDataCount.resize(mDependentObjects.size());
  mDependentDataCount = std::numeric_limits<size_t>::quiet_NaN();

  return success;
}
bool CMathDependencyGraph::getUpdateSequence(const CMath::SimulationContextFlag & context,
    const CObjectInterface::ObjectSet & changedObjects,
    const CObjectInterface::ObjectSet & requestedObjects,
    CObjectInterface::UpdateSequence & updateSequence)
{

  bool success = true;

  iterator found;
  iterator notFound = mObjects2Nodes.end();

  updateSequence.clear();

  CObjectInterface::ObjectSet::const_iterator it = changedObjects.begin();
  CObjectInterface::ObjectSet::const_iterator end = changedObjects.end();

  const_iterator itCheck = mObjects2Nodes.begin();
  const_iterator endCheck = mObjects2Nodes.end();

  // Mark all nodes which are changed or need to be calculated
  for (; it != end && success; ++it)
    {
      found = mObjects2Nodes.find(*it);

      if (found != notFound)
        {
          success &= found->second->updateDependentState(context, changedObjects);
          continue;
        }

      success = false;
    }

  if (!success) goto finish;

  it = requestedObjects.begin();
  end = requestedObjects.end();

  // Mark all nodes which are requested and its prerequisites.
  for (; it != end && success; ++it)
    {
      found = mObjects2Nodes.find(*it);

      if (found != notFound)
        {
          found->second->setRequested(true);
          success &= found->second->updatePrerequisiteState(context, changedObjects);
          continue;
        }

      success = false;
    }

#ifdef COPASI_DEBUG_TRACE
{
  std::ofstream GetUpdateSequence("GetUpdateSequence.dot");
  exportDOTFormat(GetUpdateSequence, "GetUpdateSequence");
  GetUpdateSequence.close();
}
#endif //COPASI_DEBUG_TRACE

  if (!success) goto finish;

  it = requestedObjects.begin();
  end = requestedObjects.end();

  for (; it != end && success; ++it)
    {
      found = mObjects2Nodes.find(*it);

      if (found != notFound)
        {
          success &= found->second->buildUpdateSequence(context, updateSequence);
          continue;
        }

      success = false;
    }

  if (!success) goto finish;

  for (; itCheck != endCheck; ++itCheck)
    {
      // Reset the dependency nodes for the next call.
      itCheck->second->setChanged(false);
      itCheck->second->setRequested(false);
    }

finish:

  if (!success)
    {
      updateSequence.clear();

      CCopasiMessage(CCopasiMessage::ERROR, MCMathModel + 3, (*it)->getCN().c_str());
    }

#ifdef XXXX
  CObjectInterface::UpdateSequence::const_iterator itSeq = updateSequence.begin();
  CObjectInterface::UpdateSequence::const_iterator endSeq = updateSequence.end();

  std::cout << std::endl <<  "Start" << std::endl;

  for (; itSeq != endSeq; ++itSeq)
    {
      if (dynamic_cast< const CMathObject * >(*itSeq))
        {
          std::cout << *static_cast< const CMathObject * >(*itSeq);
        }
      else
        {
          std::cout << (*itSeq)->getCN() << std::endl;
        }
    }

  std::cout << "End" << std::endl;
#endif //

  return success;
}