// 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; }
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; }
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); }
/** * 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; }
// 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; }
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; }
// 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; }
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; }