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; }
// This is only used when reading Gepasi Files void CKinFunction::createParameters() { CCopasiVectorN < CFunctionParameter > Substrates; CCopasiVectorN < CFunctionParameter > Products; CCopasiVectorN < CFunctionParameter > Modifiers; CCopasiVectorN < CFunctionParameter > Parameters; CCopasiVectorN < CFunctionParameter > Volumes; size_t i, imax = mNodes.size(); CFunctionParameter *pParameter; for (i = 0; i < imax; i++) { if (mNodes[i]->getType() == N_IDENTIFIER) { // We need to check that we have no reserved name. const char *Reserved[] = {"pi", "exponentiale", "true", "false", "infinity", "nan", "PI", "EXPONENTIALE", "TRUE", "FALSE", "INFINITY", "NAN" }; std::string Name = mNodes[i]->getName(); size_t j, jmax = 12; for (j = 0; j < jmax; j++) if (Name == Reserved[j]) break; if (j != jmax) { // It is save to prepend the identifyer with '_' since this is not allowed in // Gepasi but within COPASI. std::string OldName = Name; Name = "_" + Name; // We have to replace the corresponding CEvaluationNodes to reflect the change. std::vector< CEvaluationNode * >::iterator it = mpNodeList->begin(); std::vector< CEvaluationNode * >::iterator end = mpNodeList->end(); for (; it != end; ++it) if (((*it)->getType() & 0xFF000000) == CEvaluationNode::CONSTANT && (*it)->getData() == OldName) (*it)->setData(Name); // The Infix has changed we need to update it. setInfix(mpRoot->buildInfix()); } pParameter = new CFunctionParameter(Name); pParameter->setType(CFunctionParameter::FLOAT64); switch (mNodes[i]->getSubtype()) { case N_SUBSTRATE: pParameter->setUsage(CFunctionParameter::SUBSTRATE); if (Substrates.getIndex(pParameter->getObjectName()) == C_INVALID_INDEX) Substrates.add(pParameter, false); else pdelete(pParameter); break; case N_PRODUCT: pParameter->setUsage(CFunctionParameter::PRODUCT); if (Products.getIndex(pParameter->getObjectName()) == C_INVALID_INDEX) Products.add(pParameter, false); else pdelete(pParameter); break; case N_MODIFIER: pParameter->setUsage(CFunctionParameter::MODIFIER); if (Modifiers.getIndex(pParameter->getObjectName()) == C_INVALID_INDEX) Modifiers.add(pParameter, false); else pdelete(pParameter); break; case N_KCONSTANT: case N_NOP: pParameter->setUsage(CFunctionParameter::PARAMETER); if (Parameters.getIndex(pParameter->getObjectName()) == C_INVALID_INDEX) Parameters.add(pParameter, false); else pdelete(pParameter); break; case N_VOLUME: pParameter->setUsage(CFunctionParameter::VOLUME); if (Volumes.getIndex(pParameter->getObjectName()) == C_INVALID_INDEX) Volumes.add(pParameter, false); else pdelete(pParameter); break; default: pdelete(pParameter); fatalError(); } } } getVariables().cleanup(); imax = Substrates.size(); for (i = 0; i < imax; i++) getVariables().add(Substrates[i], true); Substrates.cleanup(); imax = Products.size(); for (i = 0; i < imax; i++) getVariables().add(Products[i], true); Products.cleanup(); imax = Modifiers.size(); for (i = 0; i < imax; i++) getVariables().add(Modifiers[i], true); Modifiers.cleanup(); imax = Parameters.size(); for (i = 0; i < imax; i++) getVariables().add(Parameters[i], true); Parameters.cleanup(); imax = Volumes.size(); for (i = 0; i < imax; i++) getVariables().add(Volumes[i], true); Volumes.cleanup(); }