Beispiel #1
0
/**
 *  Simulates the system over the next interval of time. The timestep
 *  is given as argument.
 *
 *  @param  ds A C_FLOAT64 specifying the timestep
 */
C_FLOAT64 CTauLeapMethod::doSingleStep(C_FLOAT64 ds)
{
  C_FLOAT64 Lambda, Tmp, Tau, Tau1, Tau2;

  updatePropensities();

  mAvgDX = 0.0;
  mSigDX = 0.0;

  CMathReaction * pReaction = mReactions.array();
  const C_FLOAT64 * pAmu = mAmu.array();
  const C_FLOAT64 * pAmuEnd = pAmu + mNumReactions;
  const C_FLOAT64 * pFirstSpecies = mContainerState.array() + mFirstReactionSpeciesIndex;

  for (; pAmu != pAmuEnd; ++pAmu, ++pReaction)
    {
      const CMathReaction::Balance & Balance = pReaction->getNumberBalance();
      const CMathReaction::SpeciesBalance * it = Balance.array();
      const CMathReaction::SpeciesBalance * end = it + Balance.size();

      for (; it != end; ++it)
        {
          mAvgDX[it->first - pFirstSpecies] += it->second **pAmu;
          mSigDX[it->first - pFirstSpecies] += it->second * it->second **pAmu;
        }
    }

  Tau1 = Tau2 = std::numeric_limits< C_FLOAT64 >::infinity();

  const C_FLOAT64 * pSpecies = mContainerState.array() + mFirstReactionSpeciesIndex;
  const C_FLOAT64 * pSpeciesEnd = pSpecies + mNumReactionSpecies;
  C_FLOAT64 * pAvgDX = mAvgDX.array();
  C_FLOAT64 * pSigDX = mSigDX.array();

  for (; pSpecies != pSpeciesEnd; ++pSpecies, ++pAvgDX, ++pSigDX)
    {
      if ((Tmp = mEpsilon * fabs(*pSpecies)) < 1.0)
        Tmp = 1.0;

      *pAvgDX = Tmp / fabs(*pAvgDX);
      *pSigDX = (Tmp * Tmp) / fabs(*pSigDX);

      if (Tau1 > *pAvgDX)
        Tau1 = *pAvgDX;

      if (Tau2 > *pSigDX)
        Tau2 = *pSigDX;
    }

  Tau = std::min(Tau1, Tau2);

  if (ds < Tau)
    Tau = ds;

  pAmu = mAmu.array();
  C_FLOAT64 * pK = mK.array();
  C_FLOAT64 * pKEnd = pK + mNumReactions;

  for (; pAmu != pAmuEnd; ++pAmu, ++pK)
    {
      Lambda = *pAmu * Tau;

      if (Lambda < 0.0)
        CCopasiMessage(CCopasiMessage::EXCEPTION, MCTrajectoryMethod + 10);
      else if (Lambda > 2.0e9)
        CCopasiMessage(CCopasiMessage::EXCEPTION, MCTrajectoryMethod + 26);

      *pK = mpRandomGenerator->getRandomPoisson(Lambda);
    }

  while (!updateSystem())
    {
      Tau *= 0.5;
      pK = mK.array();

      for (; pK != pKEnd; ++pK)
        {
          *pK *= 0.5;

          if (*pK < floor(*pK + 0.75))
            {
              *pK += mpRandomGenerator->getRandomCC() < 0.5 ? - 0.5 : 0.5;
            }
        }
    }

  return Tau;
}
Beispiel #2
0
/**
 *  Simulates the system over the next interval of time. The timestep
 *  is given as argument.
 *
 *  @param  ds A C_FLOAT64 specifying the timestep
 */
C_FLOAT64 CTauLeapMethod::doSingleStep(C_FLOAT64 ds)
{
  C_FLOAT64 Lambda, Tmp, Tau, Tau1, Tau2;

  updatePropensities();

  mAvgDX = 0.0;
  mSigDX = 0.0;

  std::vector< CReactionDependencies >::const_iterator itReaction = mReactionDependencies.begin();
  const C_FLOAT64 * pAmu = mAmu.array();
  const C_FLOAT64 * pAmuEnd = pAmu + mNumReactions;

  for (; pAmu != pAmuEnd; ++pAmu, ++itReaction)
    {
      const C_FLOAT64 * pMultiplicity = itReaction->mSpeciesMultiplier.array();
      const C_FLOAT64 * pMultiplicityEnd = pMultiplicity + itReaction->mSpeciesMultiplier.size();
      const size_t * pIndex = itReaction->mMethodSpeciesIndex.array();

      for (; pMultiplicity != pMultiplicityEnd; ++pMultiplicity, ++pIndex)
        {
          mAvgDX[*pIndex] += *pMultiplicity * *pAmu;
          mSigDX[*pIndex] += *pMultiplicity * *pMultiplicity * *pAmu;
        }
    }

  Tau1 = Tau2 = std::numeric_limits< C_FLOAT64 >::infinity();

  const C_FLOAT64 * pNumber = mMethodState.beginIndependent() + mFirstReactionSpeciesIndex - 1;
  const C_FLOAT64 * pNumberEnd = pNumber + mNumReactionSpecies;
  C_FLOAT64 * pAvgDX = mAvgDX.array();
  C_FLOAT64 * pSigDX = mSigDX.array();

  for (; pNumber != pNumberEnd; ++pNumber, ++pAvgDX, ++pSigDX)
    {
      if ((Tmp = mEpsilon * fabs(*pNumber)) < 1.0)
        Tmp = 1.0;

      *pAvgDX = Tmp / fabs(*pAvgDX);
      *pSigDX = (Tmp * Tmp) / fabs(*pSigDX);

      if (Tau1 > *pAvgDX)
        Tau1 = *pAvgDX;

      if (Tau2 > *pSigDX)
        Tau2 = *pSigDX;
    }

  Tau = std::min(Tau1, Tau2);

  if (ds < Tau)
    Tau = ds;

  pAmu = mAmu.array();
  C_FLOAT64 * pK = mK.array();
  C_FLOAT64 * pKEnd = pK + mNumReactions;

  for (; pAmu != pAmuEnd; ++pAmu, ++pK)
    {
      Lambda = *pAmu * Tau;

      if (Lambda < 0.0)
        CCopasiMessage(CCopasiMessage::EXCEPTION, MCTrajectoryMethod + 10);
      else if (Lambda > 2.0e9)
        CCopasiMessage(CCopasiMessage::EXCEPTION, MCTrajectoryMethod + 26);

      *pK = mpRandomGenerator->getRandomPoisson(Lambda);
    }

  while (!updateSystem())
    {
      Tau *= 0.5;
      pK = mK.array();

      for (; pK != pKEnd; ++pK)
        {
          *pK *= 0.5;

          if (*pK < floor(*pK + 0.75))
            {
              *pK += mpRandomGenerator->getRandomCC() < 0.5 ? - 0.5 : 0.5;
            }
        }
    }


  return Tau;
}