bool CODEExporterC::exportSingleFunction(const CFunction *func, std::set<std::string>& isExported) { CFunctionDB* pFunctionDB = CCopasiRootContainer::getFunctionList(); CFunction* tmpfunc = NULL; tmpfunc = new CFunction(*func, NO_PARENT); if (func->getType() != CEvaluationTree::MassAction) { CCopasiTree< CEvaluationNode>::iterator treeIt = tmpfunc->getRoot(); CCopasiTree< CEvaluationNode>::iterator newIt = treeIt; size_t j, varbs_size = tmpfunc->getVariables().size(); std::map< std::string, std::string > parameterNameMap; std::set<std::string> parameterNameSet; std::map< CFunctionParameter::Role, std::string > constName; std::map< CFunctionParameter::Role, size_t > tmpIndex; constName[CFunctionParameter::SUBSTRATE] = "sub_"; tmpIndex[CFunctionParameter::SUBSTRATE] = 0; constName[CFunctionParameter::PRODUCT] = "prod_"; tmpIndex[CFunctionParameter::PRODUCT] = 0; constName[CFunctionParameter::PARAMETER] = "param_"; tmpIndex[CFunctionParameter::PARAMETER] = 0; constName[CFunctionParameter::MODIFIER] = "modif_"; tmpIndex[CFunctionParameter::MODIFIER] = 0; constName[CFunctionParameter::VOLUME] = "volume_"; tmpIndex[CFunctionParameter::VOLUME] = 0; constName[CFunctionParameter::VARIABLE] = "varb_"; tmpIndex[CFunctionParameter::VARIABLE] = 0; constName[CFunctionParameter::TIME] = "time_"; tmpIndex[CFunctionParameter::VARIABLE] = 0; for (j = 0; j < varbs_size; ++j) { if (parameterNameSet.find(tmpfunc->getVariables()[j]->getObjectName()) == parameterNameSet.end()) { std::ostringstream tmpName; CFunctionParameter::Role role = tmpfunc->getVariables()[j]->getUsage(); tmpName << constName[role] << tmpIndex[role]; parameterNameMap[ tmpfunc->getVariables()[j]->getObjectName()] = tmpName.str(); parameterNameSet.insert(tmpfunc->getVariables()[j]->getObjectName()); tmpIndex[role]++; } } CODEExporter::modifyTreeForMassAction(tmpfunc); while (newIt != NULL) { if (newIt->mainType() == CEvaluationNode::T_VARIABLE) { newIt->setData(parameterNameMap[ tmpfunc->getVariables()[newIt->getData()]->getObjectName()]); } if (newIt->mainType() == CEvaluationNode::T_CALL) { const CFunction* callfunc; callfunc = static_cast<CFunction*>(pFunctionDB->findFunction((*newIt).getData())); if (callfunc->getType() != CEvaluationTree::MassAction) newIt->setData(NameMap[callfunc->getKey()]); } ++newIt; } std::string name = func->getObjectName(); if (isExported.find(name) == isExported.end()) { size_t j, varbs_size = tmpfunc->getVariables().size(); std::string mappedName = NameMap[func->getKey()]; if (mappedName.empty()) { NameMap[func->getKey()] = translateObjectName(name); mappedName = NameMap[func->getKey()]; } functions << "double " << mappedName << "("; headers << "double " << mappedName << "("; for (j = 0; j < varbs_size; ++j) { functions << "double " << parameterNameMap[ tmpfunc->getVariables()[j]->getObjectName().c_str()]; if (j != varbs_size - 1) functions << ", "; headers << "double " << parameterNameMap[ tmpfunc->getVariables()[j]->getObjectName().c_str()]; if (j != varbs_size - 1) headers << ", "; } functions << ") "; functions << '\t' << "//" << name << std::endl; functions << "{return " << tmpfunc->getRoot()->buildCCodeString().c_str() << ";} " << std::endl; headers << "); " << std::endl; isExported.insert(name); } } return true; }
CMathExpression::CMathExpression(const CFunction & src, const CCallParameters< C_FLOAT64 > & callParameters, CMathContainer & container, const bool & replaceDiscontinuousNodes): CEvaluationTree(src.getObjectName(), &container, CEvaluationTree::MathExpression), mPrerequisites() { clearNodes(); // Deal with the different function types switch (src.getType()) { case CEvaluationTree::Function: case CEvaluationTree::PreDefined: case CEvaluationTree::UserDefined: { // Create a vector of CEvaluationNodeObject for each variable CMath::Variables< CEvaluationNode * > Variables; CCallParameters< C_FLOAT64 >::const_iterator it = callParameters.begin(); CCallParameters< C_FLOAT64 >::const_iterator end = callParameters.end(); for (; it != end; ++it) { Variables.push_back(createNodeFromValue(it->value)); } // Create a converted copy of the existing expression tree. mpRootNode = container.copyBranch(src.getRoot(), Variables, replaceDiscontinuousNodes); // Deleted the created variables CMath::Variables< CEvaluationNode * >::iterator itVar = Variables.begin(); CMath::Variables< CEvaluationNode * >::iterator endVar = Variables.end(); for (; itVar != endVar; ++itVar) { pdelete(*itVar); } } break; case CEvaluationTree::MassAction: { // We build a mass action expression based on the call parameters. CCallParameters< C_FLOAT64 >::const_iterator it = callParameters.begin(); // Handle the case we were have an invalid number of call parameters. if (callParameters.size() < 2) { mpRootNode = NULL; } else { // We always have reactants const C_FLOAT64 * pK = it->value; ++it; const CCallParameters< C_FLOAT64 > * pSpecies = it->vector; ++it; CEvaluationNode * pPart = createMassActionPart(pK, pSpecies); if (callParameters.size() < 4) { mpRootNode = pPart; } else { mpRootNode = new CEvaluationNodeOperator(CEvaluationNode::S_MINUS, "-"); mpRootNode->addChild(pPart); pK = it->value; ++it; pSpecies = it->vector; ++it; pPart = createMassActionPart(pK, pSpecies); mpRootNode->addChild(pPart); } } } break; case CEvaluationTree::MathExpression: case CEvaluationTree::Expression: // This cannot happen and is only here to satisfy the compiler. break; } compile(); }