コード例 #1
0
ファイル: CMathObject.cpp プロジェクト: jonasfoe/COPASI
bool CMathObject::createIntensiveValueExpression(const CMetab * pSpecies,
    CMathContainer & container)
{
  bool success = true;

  // mConc = *mpValue / mpCompartment->getValue() * mpModel->getNumber2QuantityFactor();
  CObjectInterface * pNumber = NULL;
  CObjectInterface * pCompartment = NULL;

  if (mIsInitialValue)
    {
      pNumber = pSpecies->getInitialValueReference();
      pCompartment = pSpecies->getCompartment()->getInitialValueReference();
    }
  else
    {
      pNumber = pSpecies->getValueReference();
      pCompartment = pSpecies->getCompartment()->getValueReference();
    }

  std::ostringstream Infix;
  Infix.imbue(std::locale::classic());
  Infix.precision(16);

  Infix << container.getModel().getNumber2QuantityFactor();
  Infix << "*";
  Infix << pointerToString(container.getMathObject(pNumber)->getValuePointer());
  Infix << "/";
  Infix << pointerToString(container.getMathObject(pCompartment)->getValuePointer());;

  CExpression E("IntensiveValueExpression", &container);

  success &= E.setInfix(Infix.str());

  pdelete(mpExpression);
  mpExpression = new CMathExpression(E, container, !mIsInitialValue);
  compileExpression();

  return success;
}
コード例 #2
0
CMathExpression::CMathExpression(const CExpression & src,
                                 CMathContainer & container,
                                 const bool & replaceDiscontinuousNodes):
  CEvaluationTree(src.getObjectName(), &container, CEvaluationTree::MathExpression),
  mPrerequisites()
{
  clearNodes();

  // Create a converted copy of the existing expression tree.
  mpRootNode = container.copyBranch(src.getRoot(), replaceDiscontinuousNodes);

  compile();
}
コード例 #3
0
ファイル: CMathObject.cpp プロジェクト: jonasfoe/COPASI
bool CMathObject::compileTotalMass(CMathContainer & container)
{
  bool success = true;

  // The default value is NaN
  *mpValue = InvalidValue;

  // Reset the prerequisites
  mPrerequisites.clear();

  const CMoiety * pMoiety = static_cast< const CMoiety *>(mpDataObject->getObjectParent());

  std::ostringstream Infix;
  Infix.imbue(std::locale::classic());
  Infix.precision(16);

  std::vector< std::pair< C_FLOAT64, CMetab * > >::const_iterator it = pMoiety->getEquation().begin();
  std::vector< std::pair< C_FLOAT64, CMetab * > >::const_iterator end = pMoiety->getEquation().end();
  bool First = true;

  for (; it != end; ++it)
    {
      const C_FLOAT64 & Multiplicity = it->first;

      if (First || Multiplicity < 0.0)
        {
          Infix << Multiplicity;
        }
      else
        {
          Infix << "+" << Multiplicity;
        }

      First = false;

      Infix << "*";
      Infix << pointerToString(container.getMathObject(it->second->getValueReference())->getValuePointer());
    }

  CExpression E("TotalMass", &container);

  success &= E.setInfix(Infix.str());

  pdelete(mpExpression);
  mpExpression = new CMathExpression(E, container, !mIsInitialValue);
  compileExpression();

  return success;
}
コード例 #4
0
ファイル: CMathObject.cpp プロジェクト: jonasfoe/COPASI
bool CMathObject::createIntensiveRateExpression(const CMetab * pSpecies,
    CMathContainer & container)
{
  bool success = true;

  /*
    mConcRate =
      (mRate * mpModel->getNumber2QuantityFactor() - mConc * mpCompartment->getRate())
      / mpCompartment->getValue();
   */

  std::ostringstream Infix;
  Infix.imbue(std::locale::classic());
  Infix.precision(16);

  Infix << "(";
  Infix << pointerToString(container.getMathObject(pSpecies->getRateReference())->getValuePointer());
  Infix << "*";
  Infix << container.getModel().getNumber2QuantityFactor();
  Infix << "-";
  Infix << pointerToString(container.getMathObject(pSpecies->getCompartment()->getValueReference())->getValuePointer());
  Infix << "*";
  Infix << pointerToString(container.getMathObject(pSpecies->getCompartment()->getRateReference())->getValuePointer());
  Infix << ")/";
  Infix << pointerToString(container.getMathObject(pSpecies->getCompartment()->getValueReference())->getValuePointer());

  CExpression E("IntensiveRateExpression", &container);

  success &= E.setInfix(Infix.str());

  pdelete(mpExpression);
  mpExpression = new CMathExpression(E, container, !mIsInitialValue);
  compileExpression();

  return success;
}
コード例 #5
0
ファイル: CMathObject.cpp プロジェクト: sachiinb/COPASI
bool CMathObject::createExtensiveValueExpression(const CMetab * pSpecies,
    CMathContainer & container)
{
  bool success = true;

  // mConc * mpCompartment->getValue() * mpModel->getQuantity2NumberFactor();

  CObjectInterface * pDensity = NULL;
  CObjectInterface * pCompartment = NULL;

  if (mIsInitialValue)
    {
      pDensity = pSpecies->getInitialConcentrationReference();
      pCompartment = pSpecies->getCompartment()->getInitialValueReference();
    }
  else
    {
      pDensity = pSpecies->getConcentrationReference();
      pCompartment = pSpecies->getCompartment()->getValueReference();
    }

  std::ostringstream Infix;
  Infix.imbue(std::locale::classic());
  Infix.precision(16);

  Infix << container.getModel().getQuantity2NumberFactor();
  Infix << "*<";
  Infix << pDensity->getCN();
  Infix << ">*<";
  Infix << pCompartment->getCN();
  Infix << ">";

  CExpression E("ExtensiveValueExpression", &container);

  success &= E.setInfix(Infix.str());

  mpExpression = new CMathExpression(E, container, !mIsInitialValue);
  compileExpression();

  return success;
}
コード例 #6
0
ファイル: CMathObject.cpp プロジェクト: jonasfoe/COPASI
bool CMathObject::compileFlux(CMathContainer & container)
{
  bool success = true;

  // The default value is NaN
  *mpValue = InvalidValue;

  // Reset the prerequisites
  mPrerequisites.clear();

  const CReaction * pReaction = static_cast< const CReaction * >(mpDataObject->getObjectParent());

  // We need to check whether this reaction is a single compartment reaction and scale it if true.
  //   mFlux = *mScalingFactor * mpFunction->calcValue(mMap.getPointers());
  //   mScalingFactor = compartment volume or 1

  pdelete(mpExpression);
  mpExpression = new CMathExpression(*pReaction->getFunction(),
                                     pReaction->getCallParameters(),
                                     container,
                                     !mIsInitialValue);

  if (pReaction->getScalingCompartment() != NULL &&
      pReaction->getEffectiveKineticLawUnitType() == CReaction::ConcentrationPerTime)
    {
      CExpression Tmp(mpExpression->getObjectName(), &container);

      std::string Infix = pointerToString(container.getMathObject(pReaction->getScalingCompartment()->getValueReference())->getValuePointer()) + "*(" + mpExpression->getInfix() + ")";
      success &= Tmp.setInfix(Infix);
      success &= Tmp.compile();

      pdelete(mpExpression);
      mpExpression = new CMathExpression(Tmp, container, false);
    }

  compileExpression();

  return success;
}
コード例 #7
0
ファイル: CMathObject.cpp プロジェクト: jonasfoe/COPASI
bool CMathObject::compilePropensity(CMathContainer & container)
{
  bool success = true;

  // The default value is NaN
  *mpValue = InvalidValue;

  // Reset the prerequisites
  mPrerequisites.clear();

  const CReaction * pReaction = static_cast< const CReaction * >(mpDataObject->getObjectParent());

  std::ostringstream Infix;
  Infix.imbue(std::locale::classic());
  Infix.precision(16);

  // Propensity for reversible reactions must be NaN
  if (pReaction->isReversible())
    {
      Infix << "NAN";
    }
  else
    {
      // Propensity is the same as the flux, but it must now be negative.
      Infix << "max(0," << pointerToString(container.getMathObject(pReaction->getParticleFluxReference())->getValuePointer());

      // Apply correction for deterministic models
      if (container.getModel().getModelType() == CModel::deterministic)
        {
          std::ostringstream Divisor;
          Divisor.imbue(std::locale::classic());
          Divisor.precision(16);

          const CCopasiVector<CChemEqElement> & Substrates = pReaction->getChemEq().getSubstrates();
          CCopasiVector< CChemEqElement >::const_iterator itSubstrate = Substrates.begin();
          CCopasiVector< CChemEqElement >::const_iterator endSubstrate = Substrates.end();
          bool first = true;

          for (; itSubstrate != endSubstrate; ++itSubstrate)
            {
              const std::string NumberPointer = pointerToString(container.getMathObject(itSubstrate->getMetabolite()->getValueReference())->getValuePointer());

              C_FLOAT64 Multiplicity = itSubstrate->getMultiplicity();

              Multiplicity -= 1.0; // Nothing to correct if the multiplicity is 1.

              if (Multiplicity > 2.0 - 100.0 * std::numeric_limits< C_FLOAT64 >::epsilon())
                {
                  if (!first)
                    {
                      Divisor << "*";
                    }

                  first = false;
                  Divisor << NumberPointer << "^" << Multiplicity;
                }
              else if (Multiplicity > 1.0 - 100.0 * std::numeric_limits< C_FLOAT64 >::epsilon())
                {
                  if (!first)
                    {
                      Divisor << "*";
                    }

                  first = false;
                  Divisor << NumberPointer;
                }

              while (Multiplicity > 1.0 - 100.0 * std::numeric_limits< C_FLOAT64 >::epsilon())
                {
                  Infix << "*(" << NumberPointer << "-" << Multiplicity << ")";
                  Multiplicity -= 1.0;
                }
            }

          if (Divisor.str() != "")
            {
              Infix << "/(" << Divisor.str() << ")";
            }
        }

      Infix << ")";
    }

  CExpression E("PropensityExpression", &container);

  success &= E.setInfix(Infix.str());

  pdelete(mpExpression);
  mpExpression = new CMathExpression(E, container, !mIsInitialValue);
  compileExpression();

  return success;
}
コード例 #8
0
ファイル: CMathObject.cpp プロジェクト: jonasfoe/COPASI
bool CMathObject::compileValue(CMathContainer & container)
{
  bool success = true;

  // The default value is NaN
  *mpValue = InvalidValue;

  // Reset the prerequisites
  mPrerequisites.clear();

  const CModelEntity * pEntity = NULL;
  const CMetab * pSpecies = NULL;

  if (mpDataObject != NULL)
    {
      pEntity = dynamic_cast< const CModelEntity * >(mpDataObject->getObjectParent());
    }

  // Only species have corresponding properties (extensive vs intensive).
  if (mEntityType == CMath::Species)
    {
      pSpecies = static_cast< const CMetab * >(pEntity);

      if (mIsIntensiveProperty)
        {
          mpCorrespondingProperty = container.getMathObject(pSpecies->getValueReference());
        }
      else
        {
          mpCorrespondingProperty = container.getMathObject(pSpecies->getConcentrationReference());
        }
    }

  if (mIsIntensiveProperty)
    {
      switch (mSimulationType)
        {
          case CMath::Assignment:
            success &= createConvertedExpression(pSpecies->getExpressionPtr(), container);
            break;

          case CMath::EventTarget:
          case CMath::Conversion:
            success &= createIntensiveValueExpression(pSpecies, container);
            break;

          case CMath::SimulationTypeUndefined:
          case CMath::Fixed:
          case CMath::Time:
          case CMath::ODE:
          case CMath::Independent:
          case CMath::Dependent:
            success = false;
            break;
        }
    }
  else
    {
      // Species need an additional conversion since the event targets the
      // intensive property.
      if (mEntityType == CMath::Species)
        {
          success &= createExtensiveValueExpression(pSpecies, container);
        }

      switch (mSimulationType)
        {
          case CMath::Fixed:
          case CMath::EventTarget:
          case CMath::Time:
          case CMath::ODE:
          case CMath::Independent:
          case CMath::Conversion:
            break;

          case CMath::Dependent:
          {
            // We need to add the dependent number of the moiety as a possible
            // prerequisite.
            const CMoiety * pMoiety = pSpecies->getMoiety();
            const CMathObject * pDependentNumber =
              container.getMathObject(pMoiety->getDependentNumberReference());

            mPrerequisites.insert(pDependentNumber);
          }
          break;

          case CMath::Assignment:
            if (pEntity != NULL)
              {
                success &= createConvertedExpression(pEntity->getExpressionPtr(), container);
              }
            else
              {
                compileExpression();
              }

            break;

          case CMath::SimulationTypeUndefined:
            success = false;
            break;
        }
    }

  return success;
}
コード例 #9
0
ファイル: CMathObject.cpp プロジェクト: jonasfoe/COPASI
bool CMathObject::compileInitialValue(CMathContainer & container)
{
  bool success = true;

  // The default value is NaN
  *mpValue = InvalidValue;

  // Initial values are taken from the data model
  if (mpDataObject != NULL)
    {
      *mpValue = * (C_FLOAT64 *) mpDataObject->getValuePointer();
    }

  // Reset the prerequisites
  mPrerequisites.clear();

  const CModelEntity * pEntity = dynamic_cast< const CModelEntity * >(mpDataObject->getObjectParent());
  const CMetab * pSpecies = NULL;

  // Only species have corresponding properties (extensive vs intensive).
  if (mEntityType == CMath::Species)
    {
      pSpecies = static_cast< const CMetab * >(pEntity);

      if (mIsIntensiveProperty)
        {
          mpCorrespondingProperty = container.getMathObject(pSpecies->getInitialValueReference());
        }
      else
        {
          mpCorrespondingProperty = container.getMathObject(pSpecies->getInitialConcentrationReference());
        }
    }

  if (mIsIntensiveProperty)
    {
      switch (mSimulationType)
        {
          case CMath::EventTarget:
          case CMath::Fixed:
          case CMath::ODE:
          case CMath::Independent:
          case CMath::Dependent:
          case CMath::Conversion:
            success &= createIntensiveValueExpression(pSpecies, container);
            break;

          case CMath::Assignment:
            // Extensive Property * Conversion / Compartment Size
            success &= createConvertedExpression(pSpecies->getInitialExpressionPtr(), container);

            break;

          case CMath::Time:
          case CMath::SimulationTypeUndefined:
            success = false;
            break;
        }
    }
  else
    {
      switch (mSimulationType)
        {
          case CMath::Fixed:
            break;

          case CMath::Assignment:
            if (pEntity != NULL)
              {
                success &= createConvertedExpression(pEntity->getInitialExpressionPtr(), container);
              }
            else
              {
                compileExpression();
              }

            break;

          case CMath::Conversion:
          {
            success &= createExtensiveValueExpression(pSpecies, container);
          }
          break;

          case CMath::SimulationTypeUndefined:
          case CMath::EventTarget:
          case CMath::Time:
          case CMath::ODE:
          case CMath::Independent:
          case CMath::Dependent:
            success = false;
            break;
        }
    }

  return success;
}
コード例 #10
0
ファイル: CMathObject.cpp プロジェクト: jonasfoe/COPASI
bool CMathObject::createExtensiveReactionRateExpression(const CMetab * pSpecies,
    CMathContainer & container)
{
  bool success = true;

  std::ostringstream Infix;
  Infix.imbue(std::locale::classic());
  Infix.precision(16);

  std::string Key = pSpecies->getKey();
  bool First = true;

  CCopasiVectorN< CReaction >::const_iterator it = container.getModel().getReactions().begin();
  CCopasiVectorN< CReaction >::const_iterator end = container.getModel().getReactions().end();

  for (; it != end; ++it)
    {
      const CCopasiVector< CChemEqElement > &Balances =
        it->getChemEq().getBalances();
      CCopasiVector< CChemEqElement >::const_iterator itChem = Balances.begin();
      CCopasiVector< CChemEqElement >::const_iterator endChem = Balances.end();

      for (; itChem != endChem; ++itChem)
        if (itChem->getMetaboliteKey() == Key)
          break;

      if (itChem != endChem)
        {
          const C_FLOAT64 & Multiplicity = itChem->getMultiplicity();

          if (First || Multiplicity < 0.0)
            {
              if (Multiplicity == std::numeric_limits< C_FLOAT64 >::infinity())
                {
                  Infix << "infinity";
                }
              else if (Multiplicity == -std::numeric_limits< C_FLOAT64 >::infinity())
                {
                  Infix << "-infinity";
                }
              else
                {
                  Infix << Multiplicity;
                }
            }
          else
            {
              if (Multiplicity == std::numeric_limits< C_FLOAT64 >::infinity())
                {
                  Infix << "+infinity";
                }
              else
                {
                  Infix << "+" << Multiplicity;
                }
            }

          First = false;

          Infix << "*";
          Infix << pointerToString(container.getMathObject(it->getParticleFluxReference())->getValuePointer());
        }
    }

  CExpression E("ExtensiveReactionExpression", &container);

  success &= E.setInfix(Infix.str());

  pdelete(mpExpression);
  mpExpression = new CMathExpression(E, container, !mIsInitialValue);
  compileExpression();

  return success;
}
コード例 #11
0
ファイル: CMathObject.cpp プロジェクト: jonasfoe/COPASI
bool CMathObject::compileTransitionTime(CMathContainer & container)
{
  bool success = true;

  // The default value is NaN
  *mpValue = InvalidValue;

  // Reset the prerequisites
  mPrerequisites.clear();

  const CMetab * pSpecies = static_cast< const CMetab *>(mpDataObject->getObjectParent());

  std::ostringstream Infix;
  Infix.imbue(std::locale::classic());
  Infix.precision(16);

  switch (pSpecies->getStatus())
    {
      case CModelEntity::ODE:
        // mTT = *mpValue / fabs(mRate);
        Infix << "abs(";
        Infix << pointerToString(container.getMathObject(pSpecies->getValueReference())->getValuePointer());
        Infix << "/";
        Infix << pointerToString(container.getMathObject(pSpecies->getRateReference())->getValuePointer());
        Infix << ")";
        break;

      case CModelEntity::REACTIONS:
      {
        std::ostringstream PositiveFlux;
        PositiveFlux.imbue(std::locale::classic());
        PositiveFlux.precision(16);

        std::ostringstream NegativeFlux;
        NegativeFlux.imbue(std::locale::classic());
        NegativeFlux.precision(16);

        std::string Key = pSpecies->getKey();
        bool First = true;

        CCopasiVectorN< CReaction >::const_iterator it = container.getModel().getReactions().begin();
        CCopasiVectorN< CReaction >::const_iterator end = container.getModel().getReactions().end();

        for (; it != end; ++it)
          {
            const CCopasiVector< CChemEqElement > &Balances =
              it->getChemEq().getBalances();
            CCopasiVector< CChemEqElement >::const_iterator itChem = Balances.begin();
            CCopasiVector< CChemEqElement >::const_iterator endChem = Balances.end();

            for (; itChem != endChem; ++itChem)
              if (itChem->getMetaboliteKey() == Key)
                break;

            if (itChem != endChem)
              {
                const C_FLOAT64 & Multiplicity = itChem->getMultiplicity();

                if (!First)
                  {
                    PositiveFlux << "+";
                    NegativeFlux << "+";
                  }

                PositiveFlux << "max(";
                NegativeFlux << "min(";

                if (Multiplicity == std::numeric_limits< C_FLOAT64 >::infinity())
                  {
                    PositiveFlux << "infinity";
                    NegativeFlux << "infinity";
                  }
                else if (Multiplicity == -std::numeric_limits< C_FLOAT64 >::infinity())
                  {
                    PositiveFlux << "-infinity";
                    NegativeFlux << "-infinity";
                  }
                else
                  {
                    PositiveFlux << Multiplicity;
                    NegativeFlux << Multiplicity;
                  }

                PositiveFlux << "*";
                NegativeFlux << "*";
                PositiveFlux << pointerToString(container.getMathObject(it->getParticleFluxReference())->getValuePointer());
                NegativeFlux << pointerToString(container.getMathObject(it->getParticleFluxReference())->getValuePointer());

                PositiveFlux << ",0)";
                NegativeFlux << ",0)";

                First = false;
              }
          }

        if (!First)
          {
            Infix << "abs(";
            Infix << pointerToString(container.getMathObject(pSpecies->getValueReference())->getValuePointer());
            Infix << ")/if(";
            Infix << pointerToString(container.getMathObject(pSpecies->getRateReference())->getValuePointer());
            Infix << "<0,-(" << NegativeFlux.str() << ")," << PositiveFlux.str() << ")";
          }
      }
      break;

      default:
        break;
    }

  CExpression E("TransitionTimeExpression", &container);

  success &= E.setInfix(Infix.str());

  pdelete(mpExpression);
  mpExpression = new CMathExpression(E, container, false);
  compileExpression();

  return success;
}
コード例 #12
0
CMathExpression::CMathExpression(const CFunction & src,
                                 const CCallParameters< C_FLOAT64 > & callParameters,
                                 CMathContainer & container,
                                 const bool & replaceDiscontinuousNodes):
  CEvaluationTree(src.getObjectName(), &container, CEvaluationTree::MathExpression),
  mPrerequisites()
{
  clearNodes();

  // Deal with the different function types
  switch (src.getType())
    {
      case CEvaluationTree::Function:
      case CEvaluationTree::PreDefined:
      case CEvaluationTree::UserDefined:
      {
        // Create a vector of CEvaluationNodeObject for each variable
        CMath::Variables< CEvaluationNode * > Variables;

        CCallParameters< C_FLOAT64 >::const_iterator it = callParameters.begin();
        CCallParameters< C_FLOAT64 >::const_iterator end = callParameters.end();

        for (; it != end; ++it)
          {
            Variables.push_back(createNodeFromValue(it->value));
          }

        // Create a converted copy of the existing expression tree.
        mpRootNode = container.copyBranch(src.getRoot(), Variables, replaceDiscontinuousNodes);

        // Deleted the created variables
        CMath::Variables< CEvaluationNode * >::iterator itVar = Variables.begin();
        CMath::Variables< CEvaluationNode * >::iterator endVar = Variables.end();

        for (; itVar != endVar; ++itVar)
          {
            pdelete(*itVar);
          }
      }

      break;

      case CEvaluationTree::MassAction:
      {
        // We build a mass action expression based on the call parameters.
        CCallParameters< C_FLOAT64 >::const_iterator it = callParameters.begin();

        // Handle the case we were have an invalid number of call parameters.
        if (callParameters.size() < 2)
          {
            mpRootNode = NULL;
          }
        else
          {
            // We always have reactants
            const C_FLOAT64 * pK = it->value;
            ++it;
            const CCallParameters< C_FLOAT64 > * pSpecies = it->vector;
            ++it;

            CEvaluationNode * pPart = createMassActionPart(pK, pSpecies);

            if (callParameters.size() < 4)
              {
                mpRootNode = pPart;
              }
            else
              {
                mpRootNode = new CEvaluationNodeOperator(CEvaluationNode::S_MINUS, "-");
                mpRootNode->addChild(pPart);

                pK = it->value;
                ++it;
                pSpecies = it->vector;
                ++it;

                pPart = createMassActionPart(pK, pSpecies);

                mpRootNode->addChild(pPart);
              }
          }
      }
      break;

      case CEvaluationTree::MathExpression:
      case CEvaluationTree::Expression:
        // This cannot happen and is only here to satisfy the compiler.
        break;
    }

  compile();
}