bool CModelExpansion::expressionContainsObject(const CExpression* exp, const SetOfModelElements & sourceSet) { if (!exp) return false; //we loop through the complete expression std::vector< CEvaluationNode * >::const_iterator it = exp->getNodeList().begin(); std::vector< CEvaluationNode * >::const_iterator end = exp->getNodeList().end(); for (; it != end; ++it) { CEvaluationNodeObject * node = dynamic_cast<CEvaluationNodeObject*>(*it); if (!node) continue; //std::cout << node->getData() << std::endl; const CCopasiObject * pObj = dynamic_cast<const CCopasiObject*>(node->getObjectInterfacePtr()); if (pObj) { pObj = pObj->getObjectParent(); } //is the object one that should be copied? if (sourceSet.contains(pObj)) return true; } return false; }
bool CModelAdd::copyInitialExpression(const CModelEntity * sourceEntity, CModelEntity * newEntity) { bool info = false; const CExpression* pExpression = sourceEntity->getInitialExpressionPtr(); if (pExpression == NULL) return info; CExpression* tmp; tmp = new CExpression(*pExpression, mmModel); const std::vector<CEvaluationNode*>& objectNodes = tmp->getNodeList(); size_t j, jmax = objectNodes.size(); for (j = 0; j < jmax; ++j) { if (CEvaluationNode::type(objectNodes[j]->getType()) == CEvaluationNode::OBJECT) { CEvaluationNodeObject* pObjectNode = dynamic_cast<CEvaluationNodeObject*>(objectNodes[j]); if (pObjectNode == NULL) return info; CCopasiObjectName cn = pObjectNode->getObjectCN(); const CCopasiObject* mObject = static_cast< const CCopasiObject * >(mmModel->getObjectDataModel()->getObject(cn)); if (mObject == NULL) return info; std::string host = ""; if (mObject->isReference()) { host = ",Reference=" + mObject->getObjectName(); mObject = mObject->getObjectParent(); } if (mObject == NULL) return info; std::string key = keyMap[(dynamic_cast<const CModelEntity * >(mObject))->getKey()]; CCopasiObject* pObject = (CCopasiRootContainer::getKeyFactory()->get(key)); cn = pObject->getCN() + host; pObjectNode->setData("<" + cn + ">"); } } tmp->updateTree(); newEntity->setInitialExpression(tmp->getInfix().c_str()); return info; }
bool CModelMerging::mergeInExpression(std::string toKey, std::string key, CExpression *pExpression) { bool info = false; if (pExpression == NULL) return info; const std::vector<CEvaluationNode*>& objectNodes = pExpression->getNodeList(); size_t j, jmax = objectNodes.size(); for (j = 0; j < jmax; ++j) { if (CEvaluationNode::type(objectNodes[j]->getType()) == CEvaluationNode::OBJECT) { CEvaluationNodeObject* pObjectNode = dynamic_cast<CEvaluationNodeObject*>(objectNodes[j]); if (pObjectNode == NULL) return info; CCopasiObjectName cn = pObjectNode->getObjectCN(); const CCopasiObject* mObject = static_cast< const CCopasiObject * >(mpModel->getObjectDataModel()->getObject(cn)); if (mObject == NULL) return info; std::string host = ""; if (mObject->isReference()) { host = ",Reference=" + mObject->getObjectName(); mObject = mObject->getObjectParent(); } if (mObject == NULL) return info; CCopasiObject* pObject; std::string ikey = (dynamic_cast<const CModelEntity * >(mObject))->getKey(); if (ikey == key) { pObject = (CCopasiRootContainer::getKeyFactory()->get(toKey)); cn = pObject->getCN() + host; pObjectNode->setData("<" + cn + ">"); } } } pExpression->updateTree(); return true; }
void CModelExpansion::replaceInExpression(CExpression* exp, const ElementsMap & emap) { if (!exp) return; //we loop through the complete expression std::vector< CEvaluationNode * >::const_iterator it = exp->getNodeList().begin(); std::vector< CEvaluationNode * >::const_iterator end = exp->getNodeList().end(); for (; it != end; ++it) { CEvaluationNodeObject * node = dynamic_cast<CEvaluationNodeObject*>(*it); if (!node) continue; //std::cout << node->getData() << std::endl; const CCopasiObject * pObj = dynamic_cast<const CCopasiObject*>(node->getObjectInterfacePtr()); std::string refname = ""; std::string reftype = ""; if (pObj) { refname = pObj->getObjectName(); reftype = pObj->getObjectType(); pObj = pObj->getObjectParent(); } const CCopasiObject* duplicate = emap.getDuplicatePtr(pObj); if (duplicate) { //get the reference object const CCopasiObject* pRef = dynamic_cast<const CCopasiObject*>(duplicate->getObject(reftype + "=" + refname)); //update the node if (pRef) node->setData("<" + pRef->getCN() + ">"); //std::cout << node->getData() << std::endl; } } }
bool CMathExpression::convertToInitialExpression() { if (getObjectName().substr(0, 7) != "Initial") { setObjectName("Initial" + getObjectName()); } if (mpNodeList == NULL) { return false; } std::vector< CEvaluationNode * >::iterator it = mpNodeList->begin(); std::vector< CEvaluationNode * >::iterator end = mpNodeList->end(); bool changed = false; for (; it != end; ++it) { if ((*it)->mainType() == CEvaluationNode::T_OBJECT && (*it)->subType() == CEvaluationNode::S_POINTER) { CEvaluationNodeObject * pNode = static_cast< CEvaluationNodeObject *>(*it); const C_FLOAT64 * pValue = pNode->getObjectValuePtr(); C_FLOAT64 * pInitialValue = pMathContainer->getInitialValuePointer(pValue); if (pValue != pInitialValue) { changed = true; pNode->setObjectValuePtr(pInitialValue); mPrerequisites.erase(pMathContainer->getMathObject(pValue)); mPrerequisites.insert(pMathContainer->getMathObject(pInitialValue)); } } } if (changed) { mInfix = mpRootNode->buildInfix(); } return true; }
void CModelExpansion::updateExpression(CExpression* exp, const std::string & index, const SetOfModelElements & sourceSet, ElementsMap & emap) { if (!exp) return; //we loop through the complete expression std::vector< CEvaluationNode * >::const_iterator it = exp->getNodeList().begin(); std::vector< CEvaluationNode * >::const_iterator end = exp->getNodeList().end(); for (; it != end; ++it) { CEvaluationNodeObject * node = dynamic_cast<CEvaluationNodeObject*>(*it); if (!node) continue; //std::cout << node->getData() << std::endl; const CCopasiObject * pObj = dynamic_cast<const CCopasiObject*>(node->getObjectInterfacePtr()); std::string refname = ""; std::string reftype = ""; //when copying between models, pObj=NULL. This is because the expression could not be compiled //if it points to an object in a different model. //We try to fix this now: if (!pObj && mpSourceModel) { CCopasiObjectName cn = node->getObjectCN(); while (cn.getPrimary().getObjectType() != "Model" && !cn.empty()) { cn = cn.getRemainder(); } pObj = dynamic_cast<const CCopasiObject*>(mpSourceModel->getObject(cn)); } if (pObj) { refname = pObj->getObjectName(); reftype = pObj->getObjectType(); pObj = pObj->getObjectParent(); } //is the object one that is/should be copied? if (sourceSet.contains(pObj)) { if (!emap.exists(pObj)) { //we have to create the duplicate std::cout << "!!!" << std::endl; if (dynamic_cast<const CCompartment*>(pObj)) duplicateCompartment(dynamic_cast<const CCompartment*>(pObj), index, sourceSet, emap); if (dynamic_cast<const CMetab*>(pObj)) duplicateMetab(dynamic_cast<const CMetab*>(pObj), index, sourceSet, emap); if (dynamic_cast<const CModelValue*>(pObj)) duplicateGlobalQuantity(dynamic_cast<const CModelValue*>(pObj), index, sourceSet, emap); if (dynamic_cast<const CReaction*>(pObj)) duplicateReaction(dynamic_cast<const CReaction*>(pObj), index, sourceSet, emap); } //find the duplicate const CCopasiObject* duplicate = emap.getDuplicatePtr(pObj); if (duplicate) { //get the reference object const CCopasiObject* pRef = dynamic_cast<const CCopasiObject*>(duplicate->getObject(reftype + "=" + refname)); //update the node if (pRef) node->setData("<" + pRef->getCN() + ">"); //std::cout << node->getData() << std::endl; } } } }
//TODO remove pModel CEvaluationNode* CDerive::deriveBranch(const CEvaluationNode* node, const CCopasiObject * pObject, std::vector<const CEvaluationNode*>& env, //std::vector<const CCopasiObject*>& objenv, const CEvaluationTree* pTree, bool simplify) { CEvaluationNode * newNode = NULL; const CEvaluationNodeOperator * pENO = dynamic_cast<const CEvaluationNodeOperator*>(node); if (pENO) { if (!pENO->getLeft() || !pENO->getRight()) return NULL; CEvaluationNode * pLeftDeriv = deriveBranch(pENO->getLeft(), pObject, env, pTree, simplify); if (!pLeftDeriv) return NULL; CEvaluationNode * pRightDeriv = deriveBranch(pENO->getRight(), pObject, env, pTree, simplify); if (!pRightDeriv) {delete pLeftDeriv; return NULL;} // we now know that derivations of the left and right branch exist switch ((CEvaluationNodeOperator::SubType) CEvaluationNode::subType(pENO->getType())) { case CEvaluationNodeOperator::MULTIPLY: { CEvaluationNode * pLeftCopy = copyBranch_var2obj(pENO->getLeft(), env); CEvaluationNode * pRightCopy = copyBranch_var2obj(pENO->getRight(), env); CEvaluationNode * tmpNode1 = multiply(pRightCopy, pLeftDeriv, simplify); CEvaluationNode * tmpNode2 = multiply(pRightDeriv, pLeftCopy, simplify); return add(tmpNode1, tmpNode2, simplify); } break; case CEvaluationNodeOperator::DIVIDE: { CEvaluationNode * pLeftCopy = copyBranch_var2obj(pENO->getLeft(), env); CEvaluationNode * pRightCopy = copyBranch_var2obj(pENO->getRight(), env); //numerator CEvaluationNode * tmpNode1 = multiply(pRightCopy, pLeftDeriv, simplify); CEvaluationNode * tmpNode2 = multiply(pRightDeriv, pLeftCopy, simplify); CEvaluationNode * minusNode = subtract(tmpNode1, tmpNode2, simplify); minusNode->compile(NULL); //denominator CEvaluationNode * powerNode = power(copyBranch_var2obj(pENO->getRight(), env), new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "2"), simplify); return divide(minusNode, powerNode, simplify); } break; case CEvaluationNodeOperator::PLUS: return add(pLeftDeriv, pRightDeriv, simplify); break; case CEvaluationNodeOperator::MINUS: return subtract(pLeftDeriv, pRightDeriv, simplify); break; case CEvaluationNodeOperator::POWER: { // b-1 CEvaluationNode * tmpNode = subtract(copyBranch_var2obj(pENO->getRight(), env), new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1"), simplify); // a^(b-1) CEvaluationNode * powerNode = power(copyBranch_var2obj(pENO->getLeft(), env), tmpNode, simplify); // b*a' tmpNode = multiply(copyBranch_var2obj(pENO->getRight(), env), pLeftDeriv, simplify); // ln a CEvaluationNodeFunction * funcNode = new CEvaluationNodeFunction(CEvaluationNodeFunction::LOG, "ln"); funcNode->addChild(copyBranch_var2obj(pENO->getLeft(), env)); // add a // a * b' * ln a CEvaluationNode * tmpNode2 = multiply(copyBranch_var2obj(pENO->getLeft(), env), multiply(pRightDeriv, funcNode, simplify), simplify); // b*a + a*b * ln a CEvaluationNode * plusNode = add(tmpNode, tmpNode2, simplify); // a^(b-1)*(b*a + a*b * ln a) return multiply(powerNode, plusNode, simplify); } break; default: break; } } const CEvaluationNodeVariable * pENV = dynamic_cast<const CEvaluationNodeVariable*>(node); if (pENV) { if (!env[pENV->getIndex()]) return NULL; //basically just expand the tree. return deriveBranch(env[pENV->getIndex()], pObject, env, pTree, simplify); } const CEvaluationNodeNumber * pENN = dynamic_cast<const CEvaluationNodeNumber*>(node); if (pENN) { newNode = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0"); return newNode; } const CEvaluationNodeObject *pENObj = dynamic_cast<const CEvaluationNodeObject*>(node); if (pENObj) { //first check whether the object is the derivation variable if (pObject->getCN() == pENObj->getObjectCN()) { //std::cout << "*"; return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1"); } //now we need to check if we know something about the object so that it needs to be expanded const CCopasiObject * tmpObj = (const CCopasiObject *)pENObj->getObjectInterfacePtr(); if (!tmpObj) return NULL; //object is a concentration? if (tmpObj->getObjectName() == "Concentration") { //std::cout << "Concentration found" << std::endl; //In this context, the concentration is expanded as "amount of substance/volume" std::string tmpstr = tmpObj->getObjectParent() ? "<" + tmpObj->getObjectParent()->getCN() + ",Reference=ParticleNumber>" : "<>"; CEvaluationNodeObject* amount = new CEvaluationNodeObject(CEvaluationNodeObject::CN, tmpstr); amount->compile(pTree); tmpstr = tmpObj->getObjectAncestor("Compartment") ? "<" + tmpObj->getObjectAncestor("Compartment")->getCN() + ",Reference=Volume>" : "<>"; CEvaluationNodeObject* volume = new CEvaluationNodeObject(CEvaluationNodeObject::CN, tmpstr); volume->compile(pTree); CEvaluationNodeObject* volume2 = new CEvaluationNodeObject(CEvaluationNodeObject::CN, tmpstr); //we need this node twice volume2->compile(pTree); CEvaluationNode* damount = deriveBranch(amount, pObject, env, pTree, simplify); CEvaluationNode* dvolume = deriveBranch(volume, pObject, env, pTree, simplify); // A / V - A*V /V^2 return subtract(divide(damount, volume, simplify), divide(multiply(amount, dvolume, simplify), power(volume2, new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "2"), simplify), simplify), simplify); } //TODO: //object is an object with an assignment //object is dependent species //object is a reaction rate // otherwise return 0. return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0"); } const CEvaluationNodeCall *pENCall = dynamic_cast<const CEvaluationNodeCall*>(node); if (pENCall) { //is it a function? const CFunction * tmpFunction = dynamic_cast<const CFunction*>(pENCall->getCalledTree()); // const std::vector<CEvaluationNode *> getListOfChildNodes() const {return mCallNodes;} //create call environment for the called function std::vector<const CEvaluationNode*> subenv; size_t i, imax = pENCall->getListOfChildNodes().size(); subenv.resize(imax); for (i = 0; i < imax; ++i) { CEvaluationNode* tmpnode = copyBranch_var2obj(pENCall->getListOfChildNodes()[i], env); compileTree(tmpnode, pTree); subenv[i] = tmpnode; } return deriveBranch(pENCall->getCalledTree()->getRoot(), pObject, subenv, pTree, simplify); } return newNode; }