CEvaluationNode * CMathExpression::createNodeFromValue(const C_FLOAT64 * pDataValue) { CEvaluationNode * pNode = NULL; CMathObject * pMathObject = NULL; if (pDataValue != NULL) { pMathObject = pMathContainer->getMathObject(pDataValue); if (pMathObject != NULL) { pNode = new CEvaluationNodeObject((C_FLOAT64 *) pMathObject->getValuePointer()); } else { // We must have a constant value like the conversion factor from the model. pNode = new CEvaluationNodeNumber(*pDataValue); } } else { // We have an invalid value, i.e. NaN pNode = new CEvaluationNodeConstant(CEvaluationNode::S_NAN, "NAN"); } return pNode; }
/** * Update model state after one events happened */ void CStochDirectMethod::stateChange(const CMath::StateChange & change) { if (change & (CMath::ContinuousSimulation | CMath::State)) { // Create a local copy of the state where the particle number species determined // by reactions are rounded to integers. C_FLOAT64 * pValue = mContainerState.array() + mpContainer->getCountFixedEventTargets() + 1 /* Time */ + mpContainer->getCountODEs(); 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); //for assignments CMathObject * pPropensityObject = mPropensityObjects.array(); CMathObject * pPropensityObjectEnd = pPropensityObject + mPropensityObjects.size(); C_FLOAT64 * pAmu = mAmu.array(); mA0 = 0.0; // Update the propensity for (; pPropensityObject != pPropensityObjectEnd; ++pPropensityObject, ++pAmu) { pPropensityObject->calculateValue(); mA0 += *pAmu; } mNextReactionIndex = C_INVALID_INDEX; *mpRootValueNew = mpContainer->getRoots(); } mMaxStepsReached = false; }
void CTauLeapMethod::updatePropensities() { mA0 = 0; CMathObject * pPropensity = mPropensityObjects.array(); CMathObject * pPropensityEnd = pPropensity + mNumReactions; C_FLOAT64 * pAmu = mAmu.array(); for (; pPropensity != pPropensityEnd; ++pPropensity, ++pAmu) { pPropensity->calculateValue(); mA0 += *pAmu; } return; }
void CTrajectoryMethodDsaLsodar::calculatePropensities() { // It suffices to recalculate the propensities for stochastic reactions. CMathObject * pPropensity = mPropensityObjects.array(); CMathObject * pPropensityEnd = pPropensity + mNumReactions; const CMathReaction **ppStochastic = mPartition.mStochasticReactions.array(); for (; pPropensity != pPropensityEnd; ++pPropensity, ++ppStochastic) { if (*ppStochastic != NULL) { pPropensity->calculateValue(); } } return; }
void CMathObject::copy(const CMathObject & src, CMathContainer & container, const size_t & valueOffset, const size_t & objectOffset) { mpValue = (C_FLOAT64 *)((size_t) src.mpValue + valueOffset); mValueType = src.mValueType; mEntityType = src.mEntityType; mSimulationType = src.mSimulationType; mIsIntensiveProperty = src.mIsIntensiveProperty; mIsInitialValue = src.mIsInitialValue; mpDataObject = src.mpDataObject; if (src.mpIntensiveProperty != NULL) { mpIntensiveProperty = (CMathObject *)((size_t) src.mpIntensiveProperty + objectOffset); } else { mpIntensiveProperty = NULL; } if (src.mpExpression != NULL) { mpExpression = CMathExpression::copy(*src.mpExpression, container, valueOffset, objectOffset); } else { mpExpression = NULL; } ObjectSet::const_iterator it = src.getPrerequisites().begin(); ObjectSet::const_iterator end = src.getPrerequisites().end(); for (; it != end; ++it) { mPrerequisites.insert((CMathObject *)((size_t) *it + objectOffset)); } if (mpExpression != NULL && mPrerequisites.empty()) { calculate(); } }
void CMathReaction::initialize(const CReaction * pReaction, CMathContainer & container) { mpReaction = pReaction; // Sanity Check if (mpReaction == NULL) return; mpParticleFlux = container.getMathObject(mpReaction->getParticleFluxReference()); mpFlux = container.getMathObject(mpReaction->getFluxReference()); mpPropensity = container.getMathObject(mpReaction->getPropensityReference()); mObjectBalance.clear(); mChangedSpecies.clear(); mNumberBalance.resize(mpReaction->getChemEq().getBalances().size()); SpeciesBalance * pStepUpdate = mNumberBalance.array(); CDataVector < CChemEqElement >::const_iterator it = mpReaction->getChemEq().getBalances().begin(); CDataVector < CChemEqElement >::const_iterator end = mpReaction->getChemEq().getBalances().end(); for (; it != end; ++it) { const CMetab * pMetab = it->getMetabolite(); if (pMetab != NULL) { CMathObject * pParticleNumber = container.getMathObject(pMetab->getValueReference()); if (pParticleNumber->getSimulationType() == CMath::SimulationType::Independent || pParticleNumber->getSimulationType() == CMath::SimulationType::Dependent) { mChangedSpecies.insert(pParticleNumber); mObjectBalance.insert(std::pair < const CMathObject *, C_FLOAT64 >(pParticleNumber, it->getMultiplicity())); pStepUpdate->first = (C_FLOAT64 *) pParticleNumber->getValuePointer(); pStepUpdate->second = it->getMultiplicity(); ++pStepUpdate; } } } mNumberBalance.resize(mChangedSpecies.size(), true); }
// 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; }