// TODO Replace the recursive call (not critical since only used for debug) void CEvaluationNode::printRecursively(std::ostream & os, int indent) const { int i; os << std::endl; for (i = 0; i < indent; ++i) os << " "; os << "mData: " << mData << std::endl; for (i = 0; i < indent; ++i) os << " "; os << "mType: " << type(mType) << " subType: " << subType(mType) << std::endl; for (i = 0; i < indent; ++i) os << " "; os << "mValue: " << mValue << std::endl; CEvaluationNode* tmp; tmp = (CEvaluationNode*)getChild(); while (tmp) { tmp -> printRecursively(os, indent + 2); tmp = (CEvaluationNode*)tmp->getSibling(); } }
bool CEvaluationNode::operator<(const CEvaluationNode& right) const { bool result = false; if (this->getType() < right.getType()) { result = true; } else if (this->getType() == right.getType()) { switch (CEvaluationNode::type(this->getType())) { case CEvaluationNode::CONSTANT: case CEvaluationNode::NUMBER: case CEvaluationNode::OBJECT: case CEvaluationNode::CALL: case CEvaluationNode::STRUCTURE: case CEvaluationNode::VARIABLE: case CEvaluationNode::WHITESPACE: result = (this->getData() < right.getData()); break; case CEvaluationNode::OPERATOR: case CEvaluationNode::FUNCTION: case CEvaluationNode::CHOICE: case CEvaluationNode::LOGICAL: case CEvaluationNode::MV_FUNCTION: case CEvaluationNode::VECTOR: case CEvaluationNode::DELAY: case CEvaluationNode::INVALID: break; } const CEvaluationNode* pChild1 = dynamic_cast<const CEvaluationNode*>(this->getChild()); const CEvaluationNode* pChild2 = dynamic_cast<const CEvaluationNode*>(right.getChild()); while (result == false) { if (pChild1 == NULL || pChild2 == NULL) { if (pChild1 == NULL && pChild2 != NULL) { result = true; } } else { result = (*pChild1 < *pChild2); } pChild1 = dynamic_cast<const CEvaluationNode*>(pChild1->getSibling()); pChild2 = dynamic_cast<const CEvaluationNode*>(pChild2->getSibling()); } } return result; }
CEvaluationNode* CEvaluationNode::copyNode(const std::vector<CEvaluationNode*>& children) const { CEvaluationNode *newnode = create(mType, getData()); std::vector<CEvaluationNode*>::const_iterator it = children.begin(), endit = children.end(); while (it != endit) { newnode->addChild(*it); ++it; } return newnode; }
//static void CDerive::compileTree(CEvaluationNode* node, const CEvaluationTree * pTree) { if (!node) return; node->compile(pTree); CEvaluationNode* child = dynamic_cast<CEvaluationNode*>(node->getChild()); while (child != NULL) { compileTree(child, pTree); child = dynamic_cast<CEvaluationNode*>(child->getSibling()); } }
CEvaluationNode* CEvaluationNodeNormalizer::normalizePowerNode(const CEvaluationNodeOperator* pNode) { CEvaluationNode* pResult = NULL; if (pNode != NULL) { CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild())); if (pChild1 != NULL) { CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling())); if (pChild2 != NULL) { if (CEvaluationNode::type(pChild2->getType()) == CEvaluationNode::NUMBER) { if (pChild2->value() - 1.0 < ZERO) { // replace it with the first child pResult = pChild1; delete pChild2; pChild2 = NULL; } else if (pChild2->value() < ZERO) { // replace it by a number node of 1 pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1"); delete pChild1; delete pChild2; pChild1 = NULL; pChild2 = NULL; } } else { pResult = new CEvaluationNodeOperator(CEvaluationNodeOperator::POWER, "^"); pResult->addChild(pChild1); pResult->addChild(pChild2); } } } if (pResult == NULL) pResult = pNode->copyBranch(); } return pResult; }
CEvaluationNode * CMathExpression::createMassActionPart(const C_FLOAT64 * pK, const CCallParameters< C_FLOAT64 > * pSpecies) { CEvaluationNode * pPart = new CEvaluationNodeOperator(CEvaluationNode::S_MULTIPLY, "*"); pPart->addChild(createNodeFromValue(pK)); if (pSpecies->size() == 0) return pPart; CEvaluationNode * pNode = pPart; CCallParameters< C_FLOAT64 >::const_iterator itSpecies = pSpecies->begin(); CCallParameters< C_FLOAT64 >::const_iterator endSpecies = pSpecies->end(); for (; itSpecies != endSpecies - 1; ++itSpecies) { CEvaluationNode * p = new CEvaluationNodeOperator(CEvaluationNode::S_MULTIPLY, "*"); p->addChild(createNodeFromValue(itSpecies->value)); pNode->addChild(p); pNode = p; } pNode->addChild(createNodeFromValue(itSpecies->value)); return pPart; }
CEvaluationNode* CDerive::subtract(CEvaluationNode *n1, CEvaluationNode *n2, bool simplify) { if (simplify) { if (isZero(n1)) { if (isZero(n2)) { deleteBranch(n1); deleteBranch(n2); return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0"); } //else //{ // deleteBranch(n1); // return n2; //} } if (isZero(n2)) { deleteBranch(n2); return n1; } // "numerical" simplification const CEvaluationNodeNumber * tmp1 = dynamic_cast<CEvaluationNodeNumber*>(n1); const CEvaluationNodeNumber * tmp2 = dynamic_cast<CEvaluationNodeNumber*>(n2); if (tmp1 && tmp2) { CEvaluationNode* tmpNN = new CEvaluationNodeNumber(tmp1->getValue() - tmp2->getValue()); return tmpNN; } } CEvaluationNode *newNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MINUS, "-"); newNode->addChild(n1); newNode->addChild(n2); return newNode; }
// static CEvaluationNode * CEvaluationNodeDelay::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children) { assert(pASTNode->getNumChildren() == children.size()); size_t i = 0, iMax = children.size(); SubType subType = SubType::DELAY; std::string data = "delay"; CEvaluationNode * pConvertedNode = new CEvaluationNodeDelay(subType, data); for (i = 0; i < iMax; ++i) { pConvertedNode->addChild(children[i]); } pConvertedNode->compile(NULL); return pConvertedNode; }
CEvaluationNode* CDerive::add(CEvaluationNode* n1, CEvaluationNode* n2, bool simplify) { if (simplify) { if (isZero(n1)) { if (isZero(n2)) { deleteBranch(n1); deleteBranch(n2); return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0"); } else { deleteBranch(n1); return n2; } } if (isZero(n2)) { deleteBranch(n2); return n1; } // "numerical" simplification const CEvaluationNodeNumber * tmp1 = dynamic_cast<CEvaluationNodeNumber*>(n1); const CEvaluationNodeNumber * tmp2 = dynamic_cast<CEvaluationNodeNumber*>(n2); if (tmp1 && tmp2) { return new CEvaluationNodeNumber(tmp1->getValue() + tmp2->getValue()); } } CEvaluationNode *newNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::PLUS, "+"); newNode->addChild(n1); newNode->addChild(n2); return newNode; }
CEvaluationNode* CDerive::divide(CEvaluationNode* n1, CEvaluationNode* n2, bool simplify) { if (simplify) { if (isZero(n1)) { deleteBranch(n1); deleteBranch(n2); return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0"); } /*if (isOne(n1)) { if (isOne(n2)) { deleteBranch(n1); deleteBranch(n2); return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1"); } else { deleteBranch(n1); return n2; } }*/ if (isOne(n2)) { deleteBranch(n2); return n1; } } CEvaluationNode * tmpNode = NULL; tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::DIVIDE, "/"); tmpNode->addChild(n1); tmpNode->addChild(n2); //tmpNode->compile(NULL); return tmpNode; }
CEvaluationNode* CDerive::multiply(CEvaluationNode* n1, CEvaluationNode* n2, bool simplify) { if (simplify) { if (isZero(n1) || isZero(n2)) { deleteBranch(n1); deleteBranch(n2); return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0"); } if (isOne(n1)) { if (isOne(n2)) { deleteBranch(n1); deleteBranch(n2); return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1"); } else { deleteBranch(n1); return n2; } } if (isOne(n2)) { deleteBranch(n2); return n1; } } CEvaluationNode * tmpNode = NULL; tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*"); tmpNode->addChild(n1); tmpNode->addChild(n2); //tmpNode->compile(NULL); return tmpNode; }
CEvaluationNode* CDerive::power(CEvaluationNode* n1, CEvaluationNode* n2, bool simplify) { if (simplify) { if (isOne(n2)) { deleteBranch(n2); return n1; } if (isOne(n1)) { deleteBranch(n1); deleteBranch(n2); return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1"); } if (isZero(n2) && !isZero(n1)) { deleteBranch(n1); deleteBranch(n2); return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1"); } if (isZero(n1) && !isZero(n2)) { deleteBranch(n1); deleteBranch(n2); return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0"); } } CEvaluationNode * tmpNode = NULL; tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::POWER, "^"); tmpNode->addChild(n1); tmpNode->addChild(n2); //tmpNode->compile(NULL); return tmpNode; }
void CMathObject::appendDelays(CMath::DelayData & Delays) const { if (mpExpression == NULL) { return; } std::vector< CEvaluationNode * >::const_iterator it = mpExpression->getNodeList().begin(); std::vector< CEvaluationNode * >::const_iterator end = mpExpression->getNodeList().end(); for (; it != end; ++it) { switch (CEvaluationNode::type((*it)->getType())) { case CEvaluationNode::DELAY: { CEvaluationNode * pValueExpression = static_cast< CEvaluationNode * >((*it)->getChild()); std::string Expression = static_cast< CEvaluationNode * >(pValueExpression->getSibling())->buildInfix(); CMath::DelayData::iterator found = Delays.find(Expression); if (found == Delays.end()) { found = Delays.insert(std::make_pair(Expression, CMath::DelayValueData())); } Expression = pValueExpression->buildInfix(); found->second.insert(std::make_pair(Expression, std::make_pair((*it)->buildInfix(), const_cast< CMathObject * >(this)))); } break; default: break; } } return; }
bool CEvaluationNode::operator<(const CEvaluationNode& right) const { if (mainType() != right.mainType()) { return mainType() < right.mainType(); } if (subType() != right.subType()) { return subType() < right.subType(); } switch (mainType()) { case T_CONSTANT: case T_NUMBER: case T_OBJECT: case T_CALL: case T_STRUCTURE: case T_VARIABLE: case T_WHITESPACE: return getData() < right.getData(); break; case T_OPERATOR: case T_FUNCTION: case T_CHOICE: case T_LOGICAL: case T_MV_FUNCTION: case T_VECTOR: case T_DELAY: case T_INVALID: break; } const CEvaluationNode* pChild1 = dynamic_cast<const CEvaluationNode*>(this->getChild()); const CEvaluationNode* pChild2 = dynamic_cast<const CEvaluationNode*>(right.getChild()); while (true) { if (pChild1 == NULL || pChild2 == NULL) { return pChild1 < pChild2; } if (*pChild1 < *pChild2) return true; pChild1 = dynamic_cast<const CEvaluationNode*>(pChild1->getSibling()); pChild2 = dynamic_cast<const CEvaluationNode*>(pChild2->getSibling()); } return false; }
CEvaluationNode* CDerive::deriveBranch(const CEvaluationNode* node, unsigned C_INT32 variableIndex, const CCopasiObject * pObject) { 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(), variableIndex, pObject); if (!pLeftDeriv) return NULL; CEvaluationNode * pRightDeriv = deriveBranch(pENO->getRight(), variableIndex, pObject); 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 = pENO->getLeft()->copyBranch(); CEvaluationNode * pRightCopy = pENO->getRight()->copyBranch(); newNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::PLUS, "+"); CEvaluationNodeOperator * tmpNode; tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*"); tmpNode->addChild(pRightCopy); tmpNode->addChild(pLeftDeriv); //tmpNode->compile(NULL); newNode->addChild(tmpNode); tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*"); tmpNode->addChild(pRightDeriv); tmpNode->addChild(pLeftCopy); //tmpNode->compile(NULL); newNode->addChild(tmpNode); //if (newNode) newNode->compile(NULL); return newNode; } break; case CEvaluationNodeOperator::DIVIDE: { CEvaluationNode * pLeftCopy = pENO->getLeft()->copyBranch(); CEvaluationNode * pRightCopy = pENO->getRight()->copyBranch(); //numerator CEvaluationNodeOperator * minusNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MINUS, "+"); CEvaluationNodeOperator * tmpNode; tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*"); tmpNode->addChild(pRightCopy); tmpNode->addChild(pLeftDeriv); //tmpNode->compile(NULL); minusNode->addChild(tmpNode); tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*"); tmpNode->addChild(pRightDeriv); tmpNode->addChild(pLeftCopy); //tmpNode->compile(NULL); minusNode->addChild(tmpNode); minusNode->compile(NULL); //denominator CEvaluationNodeOperator * powerNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::POWER, "^"); pRightCopy = pENO->getRight()->copyBranch(); //new copy powerNode->addChild(pRightCopy); powerNode->addChild(new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "2")); //powerNode->compile(NULL); newNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::DIVIDE, "/"); newNode->addChild(minusNode); newNode->addChild(powerNode); //if (newNode) newNode->compile(NULL); return newNode; } break; case CEvaluationNodeOperator::PLUS: newNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::PLUS, "+"); newNode->addChild(pLeftDeriv); newNode->addChild(pRightDeriv); //TODO check for zeros //if (newNode) newNode->compile(NULL); return newNode; break; case CEvaluationNodeOperator::MINUS: newNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MINUS, "-"); newNode->addChild(pLeftDeriv); newNode->addChild(pRightDeriv); //TODO check for zeros //if (newNode) newNode->compile(NULL); return newNode; break; case CEvaluationNodeOperator::POWER: { CEvaluationNode * pLeftCopy = pENO->getLeft()->copyBranch(); CEvaluationNode * pRightCopy = pENO->getRight()->copyBranch(); // a^(b-1) CEvaluationNodeOperator * powerNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::POWER, "^"); powerNode->addChild(pLeftCopy); // add a CEvaluationNodeOperator * tmpNode; tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MINUS, "-"); tmpNode->addChild(pRightCopy); // add b tmpNode->addChild(new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1")); // 1 powerNode->addChild(tmpNode); // add b-1 // b*a´ + a*b´* ln a CEvaluationNodeOperator * plusNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::PLUS, "+"); tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*"); pRightCopy = pENO->getRight()->copyBranch(); //new copy of b tmpNode->addChild(pRightCopy); // add b tmpNode->addChild(pLeftDeriv); // add a´ plusNode->addChild(tmpNode); // add b*a´ tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*"); pLeftCopy = pENO->getLeft()->copyBranch(); //new copy of a tmpNode->addChild(pLeftCopy); // add a CEvaluationNodeOperator * tmptmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*"); tmptmpNode->addChild(pRightDeriv); // add b´ CEvaluationNodeFunction * funcNode = new CEvaluationNodeFunction(CEvaluationNodeFunction::LOG, "ln"); // ln a pLeftCopy = pENO->getLeft()->copyBranch(); //new copy of a funcNode->addChild(pLeftCopy); // add a tmptmpNode->addChild(funcNode); // add ln a tmpNode->addChild(tmptmpNode); // add b´ * ln a plusNode->addChild(tmpNode); // add a * b´ * ln a // a^(b-1)*(b*a´ + a*b´ * ln a) newNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*"); newNode->addChild(powerNode); newNode->addChild(plusNode); return newNode; } break; default: break; } } const CEvaluationNodeVariable * pENV = dynamic_cast<const CEvaluationNodeVariable*>(node); if (pENV) { if (pObject) return NULL; // if a variable node occurs, we are differentiating a function if (variableIndex == pENV->getIndex()) newNode = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1"); else newNode = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0"); return newNode; } const CEvaluationNodeNumber * pENN = dynamic_cast<const CEvaluationNodeNumber*>(node); if (pENN) { newNode = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0"); return newNode; } return newNode; }
//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; }
void test_depth_first_iterator::test_dfi() { std::string infix("7-(3+(4-6))+1*8"); CEvaluationTree* pTree = new CEvaluationTree(); pTree->setInfix(infix); std::string s = pTree->getInfix(); CPPUNIT_ASSERT(pTree->getRoot() != NULL); CEvaluationNodeDepthFirstIterator it(pTree->getRoot()); CPPUNIT_ASSERT(it.isValid()); CEvaluationNode* pNode = NULL; CEvaluationNodeNumber* pNumberNode = NULL; CEvaluationNodeOperator* pOperatorNode = NULL; // 7 pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER); pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode); CPPUNIT_ASSERT(pNumberNode != NULL); CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 7) / 7.0) <= std::numeric_limits<double>::min()); // 3 ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER); pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode); CPPUNIT_ASSERT(pNumberNode != NULL); CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 3) / 3.0) <= std::numeric_limits<double>::min()); // 4 ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER); pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode); CPPUNIT_ASSERT(pNumberNode != NULL); CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 4) / 4.0) <= std::numeric_limits<double>::min()); // 6 ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER); pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode); CPPUNIT_ASSERT(pNumberNode != NULL); CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 6) / 6.0) <= std::numeric_limits<double>::min()); // - ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR); pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode); CPPUNIT_ASSERT(pOperatorNode != NULL); CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::MINUS); // + ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR); pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode); CPPUNIT_ASSERT(pOperatorNode != NULL); CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::PLUS); // - ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR); pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode); CPPUNIT_ASSERT(pOperatorNode != NULL); CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::MINUS); // 1 ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER); pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode); CPPUNIT_ASSERT(pNumberNode != NULL); CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 1) / 1.0) <= std::numeric_limits<double>::min()); // 8 ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER); pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode); CPPUNIT_ASSERT(pNumberNode != NULL); CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 8) / 8.0) <= std::numeric_limits<double>::min()); // * ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR); pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode); CPPUNIT_ASSERT(pOperatorNode != NULL); CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::MULTIPLY); // + ++it; CPPUNIT_ASSERT(it.isValid() == true); pNode = *it; CPPUNIT_ASSERT(pNode != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR); pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode); CPPUNIT_ASSERT(pOperatorNode != NULL); CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::PLUS); ++it; CPPUNIT_ASSERT(it.isValid() == false); CPPUNIT_ASSERT(*it == NULL); delete pTree; }
CEvaluationNode* CEvaluationNodeLogical::createNodeFromASTTree(const ASTNode& node) { SubType subType; std::string data = ""; switch (node.getType()) { case AST_LOGICAL_AND: subType = AND; data = "and"; break; case AST_LOGICAL_OR: subType = OR; data = "or"; break; case AST_LOGICAL_XOR: subType = XOR; data = "xor"; break; case AST_RELATIONAL_EQ: subType = EQ; data = "eq"; break; case AST_RELATIONAL_GEQ: subType = GE; data = "ge"; break; case AST_RELATIONAL_GT: subType = GT; data = "gt"; break; case AST_RELATIONAL_LEQ: subType = LE; data = "le"; break; case AST_RELATIONAL_LT: subType = LT; data = "lt"; break; case AST_RELATIONAL_NEQ: subType = NE; data = "ne"; break; default: subType = INVALID; break; } CEvaluationNode* convertedNode = new CEvaluationNodeLogical(subType, data); // convert the two children int i, iMax = node.getNumChildren(); switch (subType) { case AND: case OR: case XOR: // these can have two or more children assert(iMax >= 2); convertedNode->addChild(CEvaluationTree::convertASTNode(*node.getChild(iMax - 1))); convertedNode->addChild(CEvaluationTree::convertASTNode(*node.getChild(iMax - 2))); iMax -= 3; for (i = iMax; i >= 0; --i) { CEvaluationNode* pTmpNode = new CEvaluationNodeLogical(subType, data); pTmpNode->addChild(convertedNode); pTmpNode->addChild(CEvaluationTree::convertASTNode(*node.getChild(i))); convertedNode = pTmpNode; } break; case EQ: case NE: case GE: case GT: case LE: case LT: // all these are binary convertedNode->addChild(CEvaluationTree::convertASTNode(*node.getLeftChild())); convertedNode->addChild(CEvaluationTree::convertASTNode(*node.getRightChild())); break; case INVALID: // do nothing break; } return convertedNode; }
// static CEvaluationNode * CEvaluationNodeLogical::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children) { assert(pASTNode->getNumChildren() == children.size()); size_t i = 0; size_t iMax = children.size(); SubType subType; std::string data = ""; switch (pASTNode->getType()) { case AST_LOGICAL_AND: subType = AND; data = "and"; break; case AST_LOGICAL_OR: subType = OR; data = "or"; break; case AST_LOGICAL_XOR: subType = XOR; data = "xor"; break; case AST_RELATIONAL_EQ: subType = EQ; data = "eq"; break; case AST_RELATIONAL_GEQ: subType = GE; data = "ge"; break; case AST_RELATIONAL_GT: subType = GT; data = "gt"; break; case AST_RELATIONAL_LEQ: subType = LE; data = "le"; break; case AST_RELATIONAL_LT: subType = LT; data = "lt"; break; case AST_RELATIONAL_NEQ: subType = NE; data = "ne"; break; default: subType = INVALID; break; } CEvaluationNode* pNode = NULL; // convert the two children switch (subType) { case AND: case OR: case XOR: // The number of chidren may vary switch (iMax) { case 0: if (subType == AND) pNode = new CEvaluationNodeConstant(CEvaluationNodeConstant::TRUE, "TRUE"); else pNode = new CEvaluationNodeConstant(CEvaluationNodeConstant::FALSE, "FALSE"); break; case 1: pNode = children[0]; break; default: { pNode = new CEvaluationNodeLogical(subType, data); CEvaluationNode * pCurrent = pNode; // We have at least 2 children while (i < iMax - 1) { // add the first value pCurrent->addChild(children[i++]); switch (iMax - i) { case 1: // We have only 1 more child pCurrent->addChild(children[i++]); break; default: // We have at least 2 more children { // create a new node with the same operator CEvaluationNode * pTmp = new CEvaluationNodeLogical(subType, data); pCurrent->addChild(pTmp); pCurrent = pTmp; } break; } } } break; } break; case EQ: case NE: case GE: case GT: case LE: case LT: // all these are binary assert(iMax == 2); pNode = new CEvaluationNodeLogical(subType, data); pNode->addChild(children[0]); pNode->addChild(children[1]); break; case INVALID: // do nothing break; } return pNode; }
CEvaluationNode* CEvaluationNodeNormalizer::normalizeModulusNode(const CEvaluationNodeOperator* pNode) { CEvaluationNode* pResult = NULL; if (pNode != NULL) { CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild())); if (pChild1 != NULL) { CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling())); if (pChild2 != NULL) { if (CEvaluationNode::type(pChild2->getType()) == CEvaluationNode::NUMBER) { // eliminate modulus 1 if (fabs(pChild2->value() - 1.0) < ZERO) { pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0"); delete pChild1; delete pChild2; pChild1 = NULL; pChild2 = NULL; } else if (CEvaluationNode::type(pChild1->getType()) == CEvaluationNode::NUMBER && (CEvaluationNodeNumber::SubType)CEvaluationNode::subType(pChild1->getType()) == CEvaluationNodeNumber::INTEGER && (CEvaluationNodeNumber::SubType)CEvaluationNode::subType(pChild2->getType()) == CEvaluationNodeNumber::INTEGER) { // if both children are numbers, do the calculation std::ostringstream os; os << (long)pChild1->value() % (long)pChild2->value(); pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, os.str()); delete pChild1; delete pChild2; pChild1 = NULL; pChild2 = NULL; } } else { // try to shorten numerator and denominator // TODO find out if a factor is involved if (*pChild1 == *pChild2) { pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0"); delete pChild1; delete pChild2; pChild1 = NULL; pChild2 = NULL; } } if (pResult == NULL) { pResult = new CEvaluationNodeOperator(CEvaluationNodeOperator::MODULUS, "%"); pResult->addChild(pChild1); pResult->addChild(pChild2); } } else { delete pChild1; pChild1 = NULL; } } if (pResult == NULL) pResult = pNode->copyBranch(); } return pResult; }
CEvaluationNode* CEvaluationNodeNormalizer::normalizeCEvaluationNodeFunction(const CEvaluationNodeFunction* pNode) { CEvaluationNode* pResult = NULL; if (pNode != NULL) { CEvaluationNode* pTmpResult; switch ((CEvaluationNodeFunction::SubType)CEvaluationNode::subType(pNode->getType())) { case CEvaluationNodeFunction::INVALID: break; case CEvaluationNodeFunction::LOG: case CEvaluationNodeFunction::LOG10: case CEvaluationNodeFunction::EXP: case CEvaluationNodeFunction::SIN: case CEvaluationNodeFunction::COS: case CEvaluationNodeFunction::TAN: case CEvaluationNodeFunction::SEC: case CEvaluationNodeFunction::CSC: case CEvaluationNodeFunction::COT: case CEvaluationNodeFunction::SINH: case CEvaluationNodeFunction::COSH: case CEvaluationNodeFunction::TANH: case CEvaluationNodeFunction::SECH: case CEvaluationNodeFunction::CSCH: case CEvaluationNodeFunction::COTH: case CEvaluationNodeFunction::ARCSIN: case CEvaluationNodeFunction::ARCCOS: case CEvaluationNodeFunction::ARCTAN: case CEvaluationNodeFunction::ARCSEC: case CEvaluationNodeFunction::ARCCSC: case CEvaluationNodeFunction::ARCCOT: case CEvaluationNodeFunction::ARCSINH: case CEvaluationNodeFunction::ARCCOSH: case CEvaluationNodeFunction::ARCTANH: case CEvaluationNodeFunction::ARCSECH: case CEvaluationNodeFunction::ARCCSCH: case CEvaluationNodeFunction::ARCCOTH: case CEvaluationNodeFunction::SQRT: case CEvaluationNodeFunction::ABS: case CEvaluationNodeFunction::FLOOR: case CEvaluationNodeFunction::CEIL: case CEvaluationNodeFunction::FACTORIAL: case CEvaluationNodeFunction::NOT: case CEvaluationNodeFunction::MINUS: pResult = new CEvaluationNodeFunction((CEvaluationNodeFunction::SubType)CEvaluationNode::subType(pNode->getType()), pNode->getData()); pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild())); if (pTmpResult != NULL) { pResult->addChild(pTmpResult); } else { delete pResult; pResult = NULL; } break; case CEvaluationNodeFunction::RUNIFORM: case CEvaluationNodeFunction::RNORMAL: //case CEvaluationNodeFunction::DELAY: // normalize all children pResult = new CEvaluationNodeFunction((CEvaluationNodeFunction::SubType)CEvaluationNode::subType(pNode->getType()), pNode->getData()); pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild())); if (pTmpResult != NULL) { pResult->addChild(pTmpResult); pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling())); if (pTmpResult != NULL) { pResult->addChild(pTmpResult); } else { delete pResult; pResult = NULL; } } else { delete pResult; pResult = NULL; } break; /* case CEvaluationNodeFunction::MINUS: // relace the - by a multiplication with -1 // !!! Maybe this is not possible since CEvaluationNodeNumber // elements can not hold negative numbers. pResult=new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY,""); */ case CEvaluationNodeFunction::PLUS: // eliminate the plus pResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild())); break; } if (pResult == NULL) pResult = pNode->copyBranch(); } return pResult; }
CEvaluationNode* CEvaluationNodeNormalizer::normalizeMinusNode(const CEvaluationNodeOperator* pNode) { CEvaluationNode* pResult = NULL; if (pNode != NULL) { CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild())); if (pChild1 != NULL) { CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling())); if (pChild2 != NULL) { if (CEvaluationNode::type(pChild2->getType()) == CEvaluationNode::NUMBER) { // eliminate subtraction of 0 if (fabs(pChild2->getValue()) < ZERO) { pResult = pChild1; delete pChild2; pChild1 = NULL; pChild2 = NULL; } else if (CEvaluationNode::type(pChild1->getType()) == CEvaluationNode::NUMBER) { // if both children are numbers, do the calculation std::ostringstream os; os << pChild1->getValue() - pChild2->getValue(); pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, os.str()); delete pChild1; delete pChild2; pChild1 = NULL; pChild2 = NULL; } } else { // TODO find out if a factor is involved if (*pChild1 == *pChild2) { pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, "0.0"); delete pChild1; delete pChild2; pChild1 = NULL; pChild2 = NULL; } } if (pResult == NULL) { pResult = new CEvaluationNodeOperator(CEvaluationNodeOperator::MINUS, "-"); pResult->addChild(pChild1); pResult->addChild(pChild2); } } else { delete pChild1; pChild1 = NULL; } } if (pResult == NULL) pResult = pNode->copyBranch(); } return pResult; }
// static CEvaluationNode * CEvaluationNodeChoice::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children) { assert(pASTNode->getNumChildren() == children.size()); size_t i = 0, iMax = children.size(); // a piecewise function definition can have zero or more children. if (iMax == 0) { // create a NaN node return new CEvaluationNodeConstant(CEvaluationNodeConstant::_NaN, "NAN"); } if (iMax == 1) { // this must be the otherwise // It is not clearly specified what happens if there are no pieces, but // an otherwise. I would assume that in this case, the otherwise always // takes effect return children[0]; } SubType subType; std::string data = ""; switch (pASTNode->getType()) { case AST_FUNCTION_PIECEWISE: subType = IF; data = "if"; break; default: subType = INVALID; break; } CEvaluationNodeChoice * pNode = new CEvaluationNodeChoice(subType, data); CEvaluationNode * pCurrent = pNode; // We have at least 2 children while (i < iMax - 1) { // add the condition pCurrent->addChild(children[i + 1]); // the true value pCurrent->addChild(children[i]); i += 2; switch (iMax - i) { case 0: // We are missing the false value pCurrent->addChild(new CEvaluationNodeConstant(CEvaluationNodeConstant::_NaN, "NAN")); break; case 1: // the false value pCurrent->addChild(children[i++]); break; default: // We have at least 2 more children { // create a new piecewise as the false value CEvaluationNode * pTmp = new CEvaluationNodeChoice(subType, data); pCurrent->addChild(pTmp); pCurrent = pTmp; } break; } } return pNode; }
void CQMathMatrixWidget::slotDerivButtonPressed() { #ifdef _DERIV_TEST_ std::cout << "Deriv" << std::endl; CModel* pModel = CCopasiRootContainer::getDatamodelList()->operator[](0).getModel(); CEvaluationNode* tmpnode = pModel->prepareElasticity(&pModel->getReactions()[0], &pModel->getMetabolites()[0], false); CEvaluationNode* tmpnode2 = pModel->prepareElasticity(&pModel->getReactions()[0], &pModel->getMetabolites()[0], true); //create empty environment. Variable nodes should not occur in an expression std::vector<std::vector<std::string> > env; std::string tmpstring = tmpnode->buildMMLString(false, env); std::string tmpstring2 = tmpnode2->buildMMLString(false, env); mpMML->setBaseFontPointSize(qApp->font().pointSize()); mpMML->setFontName(QtMmlWidget::NormalFont, qApp->font().family()); mpMML->setContent(tmpstring.c_str()); mpMML2->setBaseFontPointSize(qApp->font().pointSize()); mpMML2->setFontName(QtMmlWidget::NormalFont, qApp->font().family()); mpMML2->setContent(tmpstring2.c_str()); QTableWidget * pTable = new QTableWidget(pModel->getReactions().size(), pModel->getMetabolites().size()); pTable->show(); int i, imax = pModel->getMetabolites().size(); int j, jmax = pModel->getReactions().size(); for (i = 0; i < imax; ++i) for (j = 0; j < jmax; ++j) { //CEvaluationNode* tmpnode = pModel->prepareElasticity(pModel->getReactions()[j], // pModel->getMetabolites()[i], false); CEvaluationNode* tmpnode2 = pModel->prepareElasticity(&pModel->getReactions()[j], &pModel->getMetabolites()[i], true); //evaluate CExpression * tmpExp = new CExpression("tmp expr", pModel); tmpExp->setRoot(tmpnode2); tmpExp->compile(); std::cout << tmpExp->calcValue() << std::endl; //create empty environment. Variable nodes should not occur in an expression std::vector<std::vector<std::string> > env; //std::string tmpstring = tmpnode->buildMMLString(false, env); std::string tmpstring2 = tmpnode2->buildMMLString(false, env); QtMmlWidget* tmpmml = new QtMmlWidget(); tmpmml->setBaseFontPointSize(qApp->font().pointSize() - 2); tmpmml->setFontName(QtMmlWidget::NormalFont, qApp->font().family()); tmpmml->setContent(tmpstring2.c_str()); pTable->setCellWidget(j, i, tmpmml); //tmpmml = new QtMmlWidget(); //tmpmml->setBaseFontPointSize(qApp->font().pointSize()-2); //tmpmml->setFontName(QtMmlWidget::NormalFont, qApp->font().family()); //tmpmml->setContent(tmpstring.c_str()); //pTable->setCellWidget(i, 1, tmpmml); } pTable->resizeColumnsToContents(); pTable->resizeRowsToContents(); #endif }
CEvaluationNode* CEvaluationNodeNormalizer::normalizeMultiplyNode(const CEvaluationNodeOperator* pNode) { CEvaluationNode* pResult = NULL; if (pNode != NULL) { CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild())); if (pChild1 != NULL) { CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling())); if (pChild2 != NULL) { // if one of the child nodes is zero, replace the node with a number // node of value 0 // if one of the nodes is a number node of 1, replace the node by the // other child if (CEvaluationNode::type(pChild1->getType()) == CEvaluationNode::NUMBER) { if (fabs(pChild1->value() - 1.0) < ZERO) { pResult = pChild2; delete pChild1; pChild1 = NULL; pChild2 = NULL; } else if (fabs(pChild1->value()) < ZERO) { pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0"); // we are done delete pChild1; delete pChild2; pChild1 = NULL; pChild2 = NULL; } } if (pChild2 && CEvaluationNode::type(pChild2->getType()) == CEvaluationNode::NUMBER) { if (fabs(pChild2->value() - 1.0) < ZERO) { pResult = pChild1; delete pChild2; pChild2 = NULL; pChild1 = NULL; } else if (fabs(pChild2->value()) < ZERO) { pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0"); // we are done delete pChild1; delete pChild2; pChild1 = NULL; pChild2 = NULL; } } if (!pResult) { pResult = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*"); pResult->addChild(pChild1); pResult->addChild(pChild2); } if (pResult->getType() == CEvaluationNode::OPERATOR) { // multiply all number nodes in a multiplication chain std::vector<CEvaluationNode*> chainNodes; findChainNodes(dynamic_cast<CEvaluationNodeOperator*>(pResult), chainNodes); CEvaluationNodeNormalizer::eliminateMultipleNumbers((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pResult->getType()), chainNodes); // replace multiplication of identical items by a power node with the // correct power CEvaluationNodeNormalizer::collectIdenticalBranches((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pResult->getType()), chainNodes); // reorder nodes again CEvaluationNodeNormalizer::reorderNodes(chainNodes); // rebuild pResult; CEvaluationNodeOperator::SubType subType = (CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pResult->getType()); delete pResult; pResult = CEvaluationNodeNormalizer::buildOperatorBranchFromChain(subType, chainNodes); } } } if (pResult == NULL) pResult = pNode->copyBranch(); } return pResult; }
// static CEvaluationNode * CEvaluationNodeNumber::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children) { assert(pASTNode->getNumChildren() == children.size()); std::stringstream ss; ss.imbue(std::locale::classic()); ss.precision(std::numeric_limits<double>::digits10 + 2); SubType subType; std::string data = ""; CEvaluationNode* pNode = NULL; switch (pASTNode->getType()) { case AST_INTEGER: subType = SubType::INTEGER; if (pASTNode->getInteger() < 0) { pNode = new CEvaluationNodeFunction(SubType::MINUS, "-"); ss << abs(pASTNode->getInteger()); data = ss.str(); pNode->addChild(new CEvaluationNodeNumber(subType, data)); } else { ss << pASTNode->getInteger(); data = ss.str(); pNode = new CEvaluationNodeNumber(subType, data); } break; case AST_REAL: subType = SubType::DOUBLE; if (pASTNode->getReal() == (std::numeric_limits<C_FLOAT64>::infinity())) { pNode = new CEvaluationNodeConstant(SubType::Infinity, "INFINITY"); } else if (pASTNode->getReal() == (-std::numeric_limits<C_FLOAT64>::infinity())) { pNode = new CEvaluationNodeFunction(SubType::MINUS, "-"); pNode->addChild(new CEvaluationNodeConstant(SubType::Infinity, "INFINITY")); } else if (isnan(pASTNode->getReal())) { pNode = new CEvaluationNodeConstant(SubType::NaN, "NAN"); } else if (pASTNode->getReal() < 0.0) { pNode = new CEvaluationNodeFunction(SubType::MINUS, "-"); ss << fabs(pASTNode->getReal()); data = ss.str(); pNode->addChild(new CEvaluationNodeNumber(subType, data)); } else { ss << pASTNode->getReal(); data = ss.str(); pNode = new CEvaluationNodeNumber(subType, data); } break; case AST_REAL_E: subType = SubType::ENOTATION; if (pASTNode->getReal() == (std::numeric_limits<C_FLOAT64>::infinity())) { pNode = new CEvaluationNodeConstant(SubType::Infinity, "INFINITY"); } else if (pASTNode->getReal() == (-std::numeric_limits<C_FLOAT64>::infinity())) { pNode = new CEvaluationNodeFunction(SubType::MINUS, "-"); pNode->addChild(new CEvaluationNodeConstant(SubType::Infinity, "INFINITY")); } else if (isnan(pASTNode->getReal())) { pNode = new CEvaluationNodeConstant(SubType::NaN, "NAN"); } else if (pASTNode->getReal() < 0.0) { pNode = new CEvaluationNodeFunction(SubType::MINUS, "-"); ss << fabs(pASTNode->getReal()); data = ss.str(); pNode->addChild(new CEvaluationNodeNumber(subType, data)); } else { ss << pASTNode->getReal(); data = ss.str(); pNode = new CEvaluationNodeNumber(subType, data); } break; case AST_RATIONAL: subType = SubType::RATIONALE; if (pASTNode->getReal() < 0.0) // getReal returns the value of the node { pNode = new CEvaluationNodeFunction(SubType::MINUS, "-"); ss << "(" << abs(pASTNode->getNumerator()) << "/" << abs(pASTNode->getDenominator()) << ")"; data = ss.str(); pNode->addChild(new CEvaluationNodeNumber(subType, data)); } else { ss << "(" << pASTNode->getNumerator() << "/" << pASTNode->getDenominator() << ")"; data = ss.str(); pNode = new CEvaluationNodeNumber(subType, data); } break; default: subType = SubType::INVALID; break; } return pNode; }
void test_compare_utilities::test_copasi_function_expansion() { CCopasiDataModel* pDataModel = pCOPASIDATAMODEL;; std::istringstream iss(test_compare_utilities::MODEL_STRING1); CPPUNIT_ASSERT(load_cps_model_from_stream(iss, *pDataModel) == true); CFunctionDB* pFunctionDB = CCopasiRootContainer::getFunctionList(); // function_5 CEvaluationTree* pTree = pFunctionDB->findFunction("function_4"); CPPUNIT_ASSERT(pTree != NULL); // generate a call node CFunction* pFunction = dynamic_cast<CFunction*>(pTree); CPPUNIT_ASSERT(pFunction != NULL); CEvaluationNodeCall* pCallNode = new CEvaluationNodeCall(CEvaluationNode::S_FUNCTION, pFunction->getObjectName()); CPPUNIT_ASSERT(pCallNode != NULL); CFunctionParameters* pFunctionParameters = &pFunction->getVariables(); unsigned int i = 0, iMax = pFunctionParameters->size(); while (i < iMax) { CFunctionParameter* pParameter = (*pFunctionParameters)[i]; CPPUNIT_ASSERT(pParameter != NULL); CEvaluationNodeVariable* pVariableNode = new CEvaluationNodeVariable(CEvaluationNode::S_DEFAULT, pParameter->getObjectName()); pCallNode->addChild(pVariableNode); ++i; } CEvaluationNode* pExpanded = expand_function_calls(pCallNode, pFunctionDB); delete pCallNode; CPPUNIT_ASSERT(pExpanded != NULL); CPPUNIT_ASSERT(pExpanded->mainType() == CEvaluationNode::T_OPERATOR); CPPUNIT_ASSERT(pExpanded->subType() == CEvaluationNode::S_DIVIDE); CEvaluationNode* pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_PLUS); pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE); CPPUNIT_ASSERT(pChild->getData() == std::string("y")); pChild = dynamic_cast<CEvaluationNode*>(pChild->getSibling()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE); CPPUNIT_ASSERT(pChild->getData() == std::string("x")); CPPUNIT_ASSERT(pChild->getSibling() == NULL); pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild()->getSibling()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_NUMBER); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_DOUBLE); CPPUNIT_ASSERT((fabs(pChild->getValue() - 2.0) / 2.0) < 1e-6); CPPUNIT_ASSERT(pChild->getSibling() == NULL); delete pExpanded; // function_5 pTree = pFunctionDB->findFunction("function_5"); CPPUNIT_ASSERT(pTree != NULL); // generate a call node pFunction = dynamic_cast<CFunction*>(pTree); CPPUNIT_ASSERT(pFunction != NULL); pCallNode = new CEvaluationNodeCall(CEvaluationNode::S_FUNCTION, pFunction->getObjectName()); CPPUNIT_ASSERT(pCallNode != NULL); pFunctionParameters = &pFunction->getVariables(); i = 0, iMax = pFunctionParameters->size(); while (i < iMax) { CFunctionParameter* pParameter = (*pFunctionParameters)[i]; CPPUNIT_ASSERT(pParameter != NULL); CEvaluationNodeVariable* pVariableNode = new CEvaluationNodeVariable(CEvaluationNode::S_DEFAULT, pParameter->getObjectName()); pCallNode->addChild(pVariableNode); ++i; } pExpanded = expand_function_calls(pCallNode, pFunctionDB); delete pCallNode; CPPUNIT_ASSERT(pExpanded != NULL); CPPUNIT_ASSERT(pExpanded->mainType() == CEvaluationNode::T_OPERATOR); CPPUNIT_ASSERT(pExpanded->subType() == CEvaluationNode::S_PLUS); pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MINUS); pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE); CPPUNIT_ASSERT(pChild->getData() == std::string("a")); pChild = dynamic_cast<CEvaluationNode*>(pChild->getSibling()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MULTIPLY); CPPUNIT_ASSERT(pChild->getSibling() == NULL); pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE); CPPUNIT_ASSERT(pChild->getData() == std::string("c")); pChild = dynamic_cast<CEvaluationNode*>(pChild->getSibling()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_NUMBER); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_DOUBLE); CPPUNIT_ASSERT((fabs(pChild->getValue() - 1.3) / 1.3) < 1e-6); CPPUNIT_ASSERT(pChild->getSibling() == NULL); // (3*b)-5.23 pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild()->getSibling()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MINUS); // 3*b pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MULTIPLY); pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_NUMBER); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_DOUBLE); CPPUNIT_ASSERT((fabs(pChild->getValue() - 3.0) / 3.0) < 1e-6); pChild = dynamic_cast<CEvaluationNode*>(pChild->getSibling()); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE); CPPUNIT_ASSERT(pChild->getData() == std::string("b")); CPPUNIT_ASSERT(pChild->getSibling() == NULL); // 5.23 pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild()->getSibling()->getChild()->getSibling()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_NUMBER); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_DOUBLE); CPPUNIT_ASSERT((fabs(pChild->getValue() - 5.23) / 5.23) < 1e-6); CPPUNIT_ASSERT(pChild->getSibling() == NULL); delete pExpanded; // function_6 pTree = pFunctionDB->findFunction("function_6"); CPPUNIT_ASSERT(pTree != NULL); // generate a call node pFunction = dynamic_cast<CFunction*>(pTree); CPPUNIT_ASSERT(pFunction != NULL); pCallNode = new CEvaluationNodeCall(CEvaluationNode::S_FUNCTION, pFunction->getObjectName()); CPPUNIT_ASSERT(pCallNode != NULL); pFunctionParameters = &pFunction->getVariables(); i = 0, iMax = pFunctionParameters->size(); while (i < iMax) { CFunctionParameter* pParameter = (*pFunctionParameters)[i]; CPPUNIT_ASSERT(pParameter != NULL); CEvaluationNodeVariable* pVariableNode = new CEvaluationNodeVariable(CEvaluationNode::S_DEFAULT, pParameter->getObjectName()); pCallNode->addChild(pVariableNode); ++i; } pExpanded = expand_function_calls(pCallNode, pFunctionDB); delete pCallNode; CPPUNIT_ASSERT(pExpanded != NULL); // (k1-k3*1.3)+((3*k2)-5.23) CPPUNIT_ASSERT(pExpanded->mainType() == CEvaluationNode::T_OPERATOR); CPPUNIT_ASSERT(pExpanded->subType() == CEvaluationNode::S_PLUS); pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MINUS); pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE); CPPUNIT_ASSERT(pChild->getData() == std::string("k1")); pChild = dynamic_cast<CEvaluationNode*>(pChild->getSibling()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MULTIPLY); CPPUNIT_ASSERT(pChild->getSibling() == NULL); pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE); CPPUNIT_ASSERT(pChild->getData() == std::string("k3")); pChild = dynamic_cast<CEvaluationNode*>(pChild->getSibling()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_NUMBER); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_DOUBLE); CPPUNIT_ASSERT((fabs(pChild->getValue() - 1.3) / 1.3) < 1e-6); CPPUNIT_ASSERT(pChild->getSibling() == NULL); // (3*b)-5.23 pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild()->getSibling()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MINUS); // 3*b pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MULTIPLY); pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_NUMBER); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_DOUBLE); CPPUNIT_ASSERT((fabs(pChild->getValue() - 3.0) / 3.0) < 1e-6); pChild = dynamic_cast<CEvaluationNode*>(pChild->getSibling()); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE); CPPUNIT_ASSERT(pChild->getData() == std::string("k2")); CPPUNIT_ASSERT(pChild->getSibling() == NULL); // 5.23 pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild()->getSibling()->getChild()->getSibling()); CPPUNIT_ASSERT(pChild != NULL); CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_NUMBER); CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_DOUBLE); CPPUNIT_ASSERT((fabs(pChild->getValue() - 5.23) / 5.23) < 1e-6); CPPUNIT_ASSERT(pChild->getSibling() == NULL); delete pExpanded; }
CEvaluationNode* CEvaluationNodeNormalizer::normalizePlusNode(const CEvaluationNodeOperator* pNode) { CEvaluationNode* pResult = NULL; if (pNode != NULL) { CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild())); if (pChild1 != NULL) { CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling())); if (pChild2 != NULL) { // if one of the nodes is a number node of 0, replace the node by the // other child if (CEvaluationNode::type(pChild1->getType()) == CEvaluationNode::NUMBER) { if (fabs(pChild1->value()) < ZERO) { pResult = pChild2; delete pChild1; pChild1 = NULL; pChild2 = NULL; } } if (pChild2 != NULL && CEvaluationNode::type(pChild2->getType()) == CEvaluationNode::NUMBER) { if (fabs(pChild2->value()) < ZERO) { if (pChild2 != pResult) { pResult = pChild1; delete pChild2; } pChild1 = NULL; pChild2 = NULL; } } if (!pResult) { pResult = new CEvaluationNodeOperator(CEvaluationNodeOperator::PLUS, "+"); pResult->addChild(pChild1); pResult->addChild(pChild2); } if (pResult->getType() == CEvaluationNode::OPERATOR) { // add all number nodes in a summation chain std::vector<CEvaluationNode*> chainNodes; findChainNodes(dynamic_cast<CEvaluationNodeOperator*>(pResult), chainNodes); CEvaluationNodeNormalizer::eliminateMultipleNumbers((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pResult->getType()), chainNodes); // replace addition of identical items by a multiplication node with the // correct number CEvaluationNodeNormalizer::collectIdenticalBranches((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pResult->getType()), chainNodes); // reorder nodes again CEvaluationNodeNormalizer::reorderNodes(chainNodes); // rebuild pResult; CEvaluationNodeOperator::SubType subType = (CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pResult->getType()); delete pResult; pResult = CEvaluationNodeNormalizer::buildOperatorBranchFromChain(subType, chainNodes); } } else { delete pChild1; pChild1 = NULL; } } if (pResult == NULL) pResult = pNode->copyBranch(); } return pResult; }
CEvaluationNode* CEvaluationNodeNormalizer::normalizeDivideNode(const CEvaluationNodeOperator* pNode) { CEvaluationNode* pResult = NULL; if (pNode != NULL) { CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild())); if (pChild1 != NULL) { CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling())); if (pChild2 != NULL) { if (CEvaluationNode::type(pChild2->getType()) == CEvaluationNode::NUMBER) { // eliminate divisions by 1 if (fabs(pChild2->value() - 1.0) < ZERO) { pResult = pChild1; delete pChild2; pChild2 = NULL; } else if (CEvaluationNode::type(pChild1->getType()) == CEvaluationNode::NUMBER) { // if both children are numbers, do the calculation std::ostringstream os; os << pChild1->value() / pChild2->value(); pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, os.str()); delete pChild1; delete pChild2; pChild1 = NULL; pChild2 = NULL; } } else { // try to shorten numerator and denominator // TODO find out if a factor is involved if (*pChild1 == *pChild2) { pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, "1.0"); delete pChild1; delete pChild2; pChild1 = NULL; pChild2 = NULL; } } if (pResult == NULL) { pResult = new CEvaluationNodeOperator(CEvaluationNodeOperator::DIVIDE, "/"); pResult->addChild(pChild1); pResult->addChild(pChild2); } } else { delete pChild1; pChild1 = NULL; } } if (pResult == NULL) pResult = pNode->copyBranch(); } return pResult; }
// static CEvaluationNode * CEvaluationNodeFunction::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children) { assert(pASTNode->getNumChildren() == children.size()); size_t iMax = children.size(); int type = (int)pASTNode->getType(); SubType subType; std::string data = ""; if (type == AST_FUNCTION_ROOT) { CEvaluationNode * pNode = NULL; switch (iMax) { case 1: pNode = new CEvaluationNodeFunction(S_SQRT, "sqrt"); pNode->addChild(children[0]); break; case 2: /** * Replaces all root nodes with the corresponding power * operator since COPASI does not have the ROOT function. */ { pNode = new CEvaluationNodeOperator(S_POWER, "^"); pNode->addChild(children[1]); // Value CEvaluationNode * pExponent = new CEvaluationNodeOperator(S_DIVIDE, "/"); pNode->addChild(pExponent); pExponent->addChild(new CEvaluationNodeNumber(S_DOUBLE, "1")); pExponent->addChild(children[0]); // Degree } break; } return pNode; } else if (type == AST_FUNCTION_LOG && iMax == 2) { /** * Replaces all LOG10 (AST_FUNCTION_LOG) nodes that have two * children with the quotient of two LOG10 nodes with the base * as the argument for the divisor LOG10 node. */ CEvaluationNode * pNode = new CEvaluationNodeOperator(S_DIVIDE, "/"); CEvaluationNode * pValue = new CEvaluationNodeFunction(S_LOG10, "log10"); pValue->addChild(children[1]); CEvaluationNode * pBase = new CEvaluationNodeFunction(S_LOG10, "log10"); pBase->addChild(children[0]); pNode->addChild(pValue); pNode->addChild(pBase); return pNode; } switch (type) { case AST_FUNCTION_ABS: subType = S_ABS; data = "abs"; break; case AST_FUNCTION_ARCCOS: subType = S_ARCCOS; data = "acos"; break; case AST_FUNCTION_ARCCOSH: subType = S_ARCCOSH; data = "arccosh"; break; case AST_FUNCTION_ARCCOT: subType = S_ARCCOT; data = "arccot"; break; case AST_FUNCTION_ARCCOTH: subType = S_ARCCOTH; data = "arccoth"; break; case AST_FUNCTION_ARCCSC: subType = S_ARCCSC; data = "arccsc"; break; case AST_FUNCTION_ARCCSCH: subType = S_ARCCSCH; data = "arccsch"; break; case AST_FUNCTION_ARCSEC: subType = S_ARCSEC; data = "arcsec"; break; case AST_FUNCTION_ARCSECH: subType = S_ARCSECH; data = "arcsech"; break; case AST_FUNCTION_ARCSIN: subType = S_ARCSIN; data = "asin"; break; case AST_FUNCTION_ARCSINH: subType = S_ARCSINH; data = "arcsinh"; break; case AST_FUNCTION_ARCTAN: subType = S_ARCTAN; data = "atan"; break; case AST_FUNCTION_ARCTANH: subType = S_ARCTANH; data = "arctanh"; break; case AST_FUNCTION_CEILING: subType = S_CEIL; data = "ceil"; break; case AST_FUNCTION_COS: subType = S_COS; data = "cos"; break; case AST_FUNCTION_COSH: subType = S_COSH; data = "cosh"; break; case AST_FUNCTION_COT: subType = S_COT; data = "cot"; break; case AST_FUNCTION_COTH: subType = S_COTH; data = "coth"; break; case AST_FUNCTION_CSC: subType = S_CSC; data = "csc"; break; case AST_FUNCTION_CSCH: subType = S_CSCH; data = "csch"; break; case AST_FUNCTION_EXP: subType = S_EXP; data = "exp"; break; case AST_FUNCTION_FACTORIAL: subType = S_FACTORIAL; data = "factorial"; break; case AST_FUNCTION_FLOOR: subType = S_FLOOR; data = "floor"; break; case AST_FUNCTION_LN: subType = S_LOG; data = "log"; break; case AST_FUNCTION_LOG: subType = S_LOG10; data = "log10"; break; case AST_FUNCTION_SEC: subType = S_SEC; data = "sec"; break; case AST_FUNCTION_SECH: subType = S_SECH; data = "sech"; break; case AST_FUNCTION_SIN: subType = S_SIN; data = "sin"; break; case AST_FUNCTION_SINH: subType = S_SINH; data = "sinh"; break; case AST_FUNCTION_TAN: subType = S_TAN; data = "tan"; break; case AST_FUNCTION_TANH: subType = S_TANH; data = "tanh"; break; case AST_LOGICAL_NOT: subType = S_NOT; data = "not"; break; default: subType = S_INVALID; fatalError(); break; } assert(iMax == 1); CEvaluationNode * pNode = new CEvaluationNodeFunction(subType, data); if (!children.empty()) pNode->addChild(children[0]); return pNode; }