ASTNode* CompiledModelGenerator::cleanEquation(ASTNode* astP) { ASTNode& ast = *astP; //For convenience... if (ast.getType() == AST_PLUS && ast.getNumChildren() == 0) { ASTNode* result = new ASTNode(AST_INTEGER); result->setValue(0); return result; } else if (ast.getType() == AST_TIMES && ast.getNumChildren() == 0) { ASTNode* result = new ASTNode(AST_INTEGER); result->setValue(1); return result; } else if ((ast.getType() == AST_PLUS && ast.getNumChildren() == 1) || (ast.getType() == AST_TIMES && ast.getNumChildren() == 1)) { ASTNode *p = ast.getChild(0); return p ? new ASTNode(*p) : p; } for (int i = (int) ast.getNumChildren() - 1; i >= 0; i--) { ASTNode *p = ast.getChild(i); ast.replaceChild(i, cleanEquation(p)); delete p; } return new ASTNode(ast); }
/** * Sets the type of an ASTNode based on the given MathML <cn> element. * Errors will be logged in the stream's SBMLErrorLog object. */ static void setTypeCN (ASTNode& node, const XMLToken& element, XMLInputStream& stream) { string type = "real"; element.getAttributes().readInto("type", type); // here is the only place we might encounter the sbml:units attribute string units = ""; element.getAttributes().readInto("units", units); if (type == "real") { double value = 0; istringstream isreal; isreal.str( stream.next().getCharacters() ); isreal >> value; node.setValue(value); if (isreal.fail() || node.isInfinity() || node.isNegInfinity() ) { static_cast <SBMLErrorLog*> (stream.getErrorLog())->logError(FailedMathMLReadOfDouble, stream.getSBMLNamespaces()->getLevel(), stream.getSBMLNamespaces()->getVersion()); } }
/* * Subclasses should override this method to write out their contained * SBML objects as XML elements. Be sure to call your parents * implementation of this method as well. */ void SpeciesReference::writeElements (XMLOutputStream& stream) const { if ( mNotes != NULL ) stream << *mNotes; SpeciesReference * sr = const_cast <SpeciesReference *> (this); sr->syncAnnotation(); if ( mAnnotation != NULL ) stream << *mAnnotation; if (getLevel() == 2) { if (mStoichiometryMath || mDenominator != 1) { if (mStoichiometryMath != NULL) { mStoichiometryMath->write(stream); } else { ASTNode node; node.setValue(static_cast<long>(mStoichiometry), mDenominator); stream.startElement("stoichiometryMath"); writeMathML(&node, stream); stream.endElement("stoichiometryMath"); } } } // // (EXTENSION) // SBase::writeExtensionElements(stream); }
ASTNode* CEvaluationNodeNumber::toAST(const CDataModel* /* pDataModel */) const { SubType subType = (SubType)this->subType(); ASTNode* node = new ASTNode(); double num1; double num2; const char * end; const char * str = mData.c_str(); switch (subType) { case SubType::DOUBLE: node->setType(AST_REAL); node->setValue(*mpValue); break; case SubType::INTEGER: node->setType(AST_INTEGER); node->setValue((long)*mpValue); break; case SubType::ENOTATION: node->setType(AST_REAL_E); num2 = floor(log10(*mpValue)); num1 = pow(10.0, log10(*mpValue) - num2); node->setValue(num1, (long)num2); break; case SubType::RATIONALE: node->setType(AST_RATIONAL); str++; // Skip the '(' num1 = strToDouble(str, &end); end++; // Skip the '/' num2 = strToDouble(end, NULL); node->setValue((long)num1, (long)num2); break; case SubType::INVALID: break; } return node; }
/** * Ensures the given ASTNode has the appropriate number of arguments. If * arguments are missing, appropriate defaults (per the MathML 2.0 * specification) are added: * * log (x) -> log (10, x) * root(x) -> root( 2, x) */ static void checkFunctionArgs (ASTNode& node) { if (node.getNumChildren() == 1) { if (node.getType() == AST_FUNCTION_LOG) { ASTNode* child = new ASTNode; child->setValue(10); node.prependChild(child); } else if (node.getType() == AST_FUNCTION_ROOT) { ASTNode* child = new ASTNode; child->setValue(2); node.prependChild(child); } } }
END_TEST START_TEST (test_MathMLFromAST_replaceIDWithFunction_2) { const char* expected = wrapMathML ( " <apply>\n" " <power/>\n" " <apply>\n" " <plus/>\n" " <cn> 1 </cn>\n" " </apply>\n" " <cn> 2 </cn>\n" " </apply>\n" ); const char* original = wrapMathML ( " <apply>\n" " <power/>\n" " <ci> x </ci>\n" " <cn> 2 </cn>\n" " </apply>\n" ); N = new ASTNode(AST_POWER); ASTNode *n1 = new ASTNode(AST_NAME); n1->setName("x"); ASTNode *n2 = new ASTNode(); n2->setValue(2.0); N->addChild(n1); N->addChild(n2); ASTNode *replaced = new ASTNode(AST_PLUS); ASTNode *c = new ASTNode(); c->setValue(1.0); replaced->addChild(c); S = writeMathMLToString(N); fail_unless( equals(original, S) ); N->replaceIDWithFunction("x", replaced); S = writeMathMLToString(N); fail_unless( equals(expected, S) ); }
ASTNode* CEvaluationNodeConstant::toAST(const CCopasiDataModel* /*pDataModel*/) const { SubType subType = (SubType)this->subType(); ASTNode* node = new ASTNode(); switch (subType) { case S_PI: node->setType(AST_CONSTANT_PI); break; case S_EXPONENTIALE: node->setType(AST_CONSTANT_E); break; case S_TRUE: node->setType(AST_CONSTANT_TRUE); break; case S_FALSE: node->setType(AST_CONSTANT_FALSE); break; case S_INFINITY: node->setType(AST_REAL); node->setValue(std::numeric_limits<C_FLOAT64>::infinity()); break; case S_NAN: case S_INVALID: node->setType(AST_REAL); node->setValue(std::numeric_limits<C_FLOAT64>::quiet_NaN()); break; } return node; }
void BoostSpiritGrammar::buildAST(const iter_t &it, ASTNode *parent, const uint32_t &depth) const { ASTNode *child = NULL; string key; for (uint32_t j = 0; j < it->children.size(); j++) { string data((it->children.begin() + j)->value.begin(), (it->children.begin() + j)->value.end()); boost::algorithm::trim(data); if ( (data != "") && ((it->children.begin() + j)->value.id().to_long() == 0) && ((it->children.begin() + j)->children.size() == 0) ) { // Keys have no children and an ID of 0 because they are keywords from the grammar. key = data; child = new ASTNode(parent); child->setKey(key); parent->addChild(child); } else if ( (data != "") && ((it->children.begin() + j)->value.id().to_long() > 0) && ((it->children.begin() + j)->children.size() == 0) ) { // Values have an ID greater than 0 and no children. // Check if there's already a child with no value set. if ( (child == NULL) || (child->getValue<string>() != "") ) { child = new ASTNode(parent); parent->addChild(child); } child->setKey(key); child->setValue(data); } else if ( ((it->children.begin() + j)->value.id().to_long() > 0) && ((it->children.begin() + j)->children.size() > 0) ) { // Hierarchically sub-ordered values have also an ID greater than 0 but children as well. ASTNode *multipleChildren = new ASTNode(parent); buildAST(it->children.begin() + j, multipleChildren, depth + 1); multipleChildren->setKey(key); parent->addChild(multipleChildren); // ASTNode *multipleChildren = NULL; // if ( (parent != NULL) && (parent->getLastChild() != NULL) && (parent->getLastChild()->getKey() == key) && (parent->getLastChild()->getValue<string>() == "") ) { // // Re-use last added child if value is empty AND keys are identical. // multipleChildren = parent->getLastChild(); // } // else { // multipleChildren = new ASTNode(parent); // parent->addChild(multipleChildren); // } // buildAST(it->children.begin() + j, multipleChildren, depth + 1); // multipleChildren->setKey(key); } } }
void MMOMath::_processNode (ASTNode* node) { ASTNodeType_t t = node->getType (); if (t == AST_FUNCTION_ROOT) { ASTNode *first = new ASTNode (*node->getChild (0)); ASTNode *exp = new ASTNode (AST_DIVIDE); ASTNode *constant = new ASTNode (AST_REAL); constant->setValue (1); exp->addChild (constant); exp->addChild (first); node->setType (AST_POWER); node->removeChild (0); node->addChild (exp); } else if (t == AST_NAME && !_prefix.empty () && node->getId ().compare ("REPLACED_FUNCTION")) { string controlName = node->getName (); string flatName = _prefix + "_"; if (controlName.compare (0, flatName.size (), flatName)) { flatName.append (node->getName ()); node->setName (flatName.c_str ()); } } string package = MMOUtils::getInstance ()->checkPredefinedFunctions (node); if (!package.empty ()) { _imports[package] = package; } int childs = node->getNumChildren (); int i; for (i = 0; i < childs; i++) { _processNode (node->getChild (i)); } }
int Submodel::convertTimeAndExtent() { int ret=LIBSBML_OPERATION_SUCCESS; string tcf = ""; ASTNode* tcf_ast = NULL; if (isSetTimeConversionFactor()) { tcf = getTimeConversionFactor(); tcf_ast = new ASTNode(AST_NAME); tcf_ast->setName(tcf.c_str()); } string xcf = ""; ASTNode* xcf_ast = NULL; if (isSetExtentConversionFactor()) { xcf = getExtentConversionFactor(); xcf_ast = new ASTNode(AST_NAME); xcf_ast->setName(xcf.c_str()); } ASTNode* klmod = NULL; if (xcf_ast != NULL) { klmod = xcf_ast; } if (tcf_ast != NULL) { if (klmod==NULL) { klmod = new ASTNode(AST_INTEGER); klmod->setValue(1); } ASTNode* divide = new ASTNode(AST_DIVIDE); divide->addChild(klmod); divide->addChild(tcf_ast); klmod = divide; } ret = convertTimeAndExtentWith(tcf_ast, xcf_ast, klmod); delete klmod; return ret; }
END_TEST START_TEST (test_MathMLFromAST_sin) { const char* expected = wrapMathML ( " <apply>\n" " <sin/>\n" " <cn type=\"integer\"> 1 </cn>\n" " </apply>\n" ); N = new ASTNode(AST_FUNCTION_SIN); ASTNode* c = new ASTNode(AST_INTEGER); c->setValue(long(1)); fail_unless(N->addChild(c) == LIBSBML_OPERATION_SUCCESS); // N = SBML_parseFormula("sin(x)"); S = writeMathMLToString(N); fail_unless( equals(expected, S) ); }
END_TEST START_TEST (test_MathMLFromAST_func_style) { const char* expected = wrapMathML ( " <apply>\n" " <sin style=\"a\"/>\n" " <cn type=\"integer\"> 1 </cn>\n" " </apply>\n" ); N = new ASTNode(AST_FUNCTION_SIN); N->setStyle("a"); ASTNode * c = new ASTNode(AST_INTEGER); c->setValue((int)(1)); N->addChild(c); S = writeMathMLToString(N); fail_unless( equals(expected, S) ); }
void dealWithL1Stoichiometry(Model & m, bool l2) { unsigned int idCount = 0; char newid[15]; std::string id; for (unsigned int i = 0; i < m.getNumReactions(); i++) { Reaction *r = m.getReaction(i); unsigned int j; for (j = 0; j < r->getNumReactants(); j++) { SpeciesReference *sr = r->getReactant(j); if (sr->getDenominator() != 1) { long stoich = static_cast<long>(sr->getStoichiometry()); int denom = sr->getDenominator(); ASTNode *node = new ASTNode(); node->setValue(stoich, denom); if (l2 == true) { StoichiometryMath * sm = sr->createStoichiometryMath(); sm->setMath(node); } else { sprintf(newid, "speciesRefId_%u", idCount); id.assign(newid); idCount++; sr->setId(id); InitialAssignment * ar = m.createInitialAssignment(); ar->setSymbol(id); ar->setMath(node); sr->unsetStoichiometry(); } } } for (j = 0; j < r->getNumProducts(); j++) { SpeciesReference *sr = r->getProduct(j); if (sr->getDenominator() != 1) { long stoich = static_cast<long>(sr->getStoichiometry()); int denom = sr->getDenominator(); ASTNode *node = new ASTNode(); node->setValue(stoich, denom); if (l2 == true) { StoichiometryMath * sm = sr->createStoichiometryMath(); sm->setMath(node); } else { sprintf(newid, "speciesRefId_%u", idCount); id.assign(newid); idCount++; sr->setId(id); InitialAssignment * ar = m.createInitialAssignment(); ar->setSymbol(id); ar->setMath(node); sr->unsetStoichiometry(); } } } } }
END_TEST START_TEST(test_SBMLTransforms_evaluateAST) { double temp; const char * mathml; ASTNode * node = new ASTNode(); node->setValue((int)(2)); fail_unless(SBMLTransforms::evaluateASTNode(node) == 2); node->setValue((double) (3.2)); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 3.2)); node->setValue((long)(1), (long)(4)); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 0.25)); node->setValue((double) (4.234), (int) (2)); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 423.4)); node->setType(AST_NAME_AVOGADRO); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 6.02214179e23)); node->setType(AST_NAME_TIME); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 0.0)); node->setType(AST_NAME); fail_unless(util_isNaN(SBMLTransforms::evaluateASTNode(node))); node->setType(AST_CONSTANT_E); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), exp(1.0))); node->setType(AST_CONSTANT_FALSE); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 0.0)); node->setType(AST_CONSTANT_PI); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 4.0*atan(1.0))); node->setType(AST_CONSTANT_TRUE); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("2.5 + 6.1"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 8.6)); node = SBML_parseFormula("-4.3"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), -4.3)); node = SBML_parseFormula("9.2-4.3"); temp = 9.2-4.3; fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("2*3"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 6)); node = SBML_parseFormula("1/5"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 0.2)); node = SBML_parseFormula("pow(2, 3)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 8)); node = SBML_parseFormula("3^3"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 27)); node = SBML_parseFormula("abs(-9.456)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 9.456)); node = SBML_parseFormula("ceil(9.456)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 10)); node = SBML_parseFormula("exp(2.0)"); temp = exp(2.0); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("floor(2.04567)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 2)); node = SBML_parseFormula("ln(2.0)"); temp = log(2.0); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("log10(100.0)"); temp = log10(100.0); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("sin(2.0)"); temp = sin(2.0); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("cos(4.1)"); temp = cos(4.1); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("tan(0.345)"); temp = tan(0.345); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arcsin(0.456)"); temp = asin(0.456); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arccos(0.41)"); temp = acos(0.41); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arctan(0.345)"); temp = atan(0.345); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("sinh(2.0)"); temp = sinh(2.0); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("cosh(4.1)"); temp = cosh(4.1); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("tanh(0.345)"); temp = tanh(0.345); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("and(1, 0)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("or(1, 0)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("not(1)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("xor(1, 0)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("xor(1, 1)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("eq(1, 2)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("eq(1, 1)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("geq(2,1)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("geq(2,4)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("geq(2,2)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("gt(2,1)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("gt(2,4)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("leq(2,1)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("leq(2,4)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("leq(2,2)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("lt(2,1)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("lt(2,4)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("neq(2,2)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("neq(3,2)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("cot(2.0)"); temp = 1.0/tan(2.0); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("csc(4.1)"); temp = 1.0/sin(4.1); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("sec(0.345)"); temp = 1.0/cos(0.345); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("coth(2.0)"); temp = cosh(2.0)/sinh(2.0); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("sech(2.0)"); temp = 1.0/cosh(2.0); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("csch(2.0)"); temp = 1.0/sinh(2.0); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arccot(2.0)"); temp = atan(1/2.0); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arccsc(2.0)"); temp = asin(1/2.0); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arcsec(2.0)"); temp = acos(1/2.0); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arccosh(2.0)"); temp = log(2.0 + pow(3.0, 0.5)); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arccoth(2.0)"); temp = 0.5 * log(3.0); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arcsech(0.2)"); temp = log(2*pow(6, 0.5)+5); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arccsch(0.2)"); /* temp = log(5 +pow(26, 0.5)); * only matches to 15 dp and therefore fails !! */ temp = 2.312438341272753; fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arcsinh(3.0)"); temp = log(3.0 +pow(10.0, 0.5)); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arctanh(0.2)"); temp = 0.5 * log(1.5); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node->setType(AST_FUNCTION_DELAY); fail_unless(util_isNaN(SBMLTransforms::evaluateASTNode(node))); node = SBML_parseFormula("factorial(3)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 6)); node= SBML_parseFormula("piecewise()"); fail_unless(util_isNaN(SBMLTransforms::evaluateASTNode(node))); node= SBML_parseFormula("piecewise(1,false)"); fail_unless(util_isNaN(SBMLTransforms::evaluateASTNode(node))); node= SBML_parseFormula("piecewise(1,true)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 1)); node = SBML_parseFormula("piecewise(1.0, true, 0.0)"); temp = 1.0; fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("piecewise(1.0, false, 0.0)"); temp = 0.0; fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("piecewise(4.5)"); temp = 4.5; fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("piecewise(4.5, false, 5.5, true)"); temp = 5.5; fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("piecewise(4.5, true, 5.5, false)"); temp = 4.5; fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("piecewise(4.5, false, 5.5, false, 6.5)"); temp = 6.5; fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node= SBML_parseFormula("piecewise(4.5, true, 5.5, true)"); fail_unless(util_isNaN(SBMLTransforms::evaluateASTNode(node))); node = SBML_parseFormula("piecewise(4.5, true, 4.5, true)"); temp = 4.5; fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("root(2, 4)"); fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), 2)); mathml = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">" "<apply><plus/></apply></math>"; node = readMathMLFromString(mathml); temp = 0; fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); mathml = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">" "<apply><plus/><cn>2.3</cn></apply></math>"; node = readMathMLFromString(mathml); temp = 2.3; fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); mathml = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">" "<apply><times/></apply></math>"; node = readMathMLFromString(mathml); temp = 1.0; fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); mathml = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">" "<apply><times/><cn>6.5</cn></apply></math>"; node = readMathMLFromString(mathml); temp = 6.5; fail_unless(util_isEqual(SBMLTransforms::evaluateASTNode(node), temp)); }
END_TEST START_TEST(test_SBMLTransforms_evaluateAST) { double temp; ASTNode * node = new ASTNode(); node->setValue((int)(2)); fail_unless(SBMLTransforms::evaluateASTNode(node) == 2); node->setValue((double) (3.2)); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 3.2)); node->setValue((long)(1), (long)(4)); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 0.25)); node->setValue((double) (4.234), (int) (2)); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 423.4)); node->setType(AST_NAME_AVOGADRO); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 6.02214179e23)); node->setType(AST_NAME_TIME); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 0.0)); node->setType(AST_NAME); fail_unless(isnan(SBMLTransforms::evaluateASTNode(node))); node->setType(AST_CONSTANT_E); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), exp(1.0))); node->setType(AST_CONSTANT_FALSE); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 0.0)); node->setType(AST_CONSTANT_PI); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 4.0*atan(1.0))); node->setType(AST_CONSTANT_TRUE); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("2.5 + 6.1"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 8.6)); node = SBML_parseFormula("-4.3"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), -4.3)); node = SBML_parseFormula("9.2-4.3"); temp = 9.2-4.3; fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("2*3"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 6)); node = SBML_parseFormula("1/5"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 0.2)); node = SBML_parseFormula("pow(2, 3)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 8)); node = SBML_parseFormula("3^3"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 27)); node = SBML_parseFormula("abs(-9.456)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 9.456)); node = SBML_parseFormula("ceil(9.456)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 10)); node = SBML_parseFormula("exp(2.0)"); temp = exp(2.0); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("floor(2.04567)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 2)); node = SBML_parseFormula("ln(2.0)"); temp = log(2.0); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("log10(100.0)"); temp = log10(100.0); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("sin(2.0)"); temp = sin(2.0); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("cos(4.1)"); temp = cos(4.1); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("tan(0.345)"); temp = tan(0.345); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arcsin(0.456)"); temp = asin(0.456); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arccos(0.41)"); temp = acos(0.41); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arctan(0.345)"); temp = atan(0.345); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("sinh(2.0)"); temp = sinh(2.0); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("cosh(4.1)"); temp = cosh(4.1); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("tanh(0.345)"); temp = tanh(0.345); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("and(1, 0)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("or(1, 0)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("not(1)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("xor(1, 0)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("xor(1, 1)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("eq(1, 2)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("eq(1, 1)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("geq(2,1)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("geq(2,4)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("geq(2,2)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("gt(2,1)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("gt(2,4)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("leq(2,1)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("leq(2,4)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("leq(2,2)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("lt(2,1)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("lt(2,4)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("neq(2,2)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 0.0)); node = SBML_parseFormula("neq(3,2)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 1.0)); node = SBML_parseFormula("cot(2.0)"); temp = 1.0/tan(2.0); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("csc(4.1)"); temp = 1.0/sin(4.1); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("sec(0.345)"); temp = 1.0/cos(0.345); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("coth(2.0)"); temp = cosh(2.0)/sinh(2.0); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("sech(2.0)"); temp = 1.0/cosh(2.0); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("csch(2.0)"); temp = 1.0/sinh(2.0); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arccot(2.0)"); temp = atan(1/2.0); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arccsc(2.0)"); temp = asin(1/2.0); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arcsec(2.0)"); temp = acos(1/2.0); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arccosh(2.0)"); temp = log(2.0 + pow(3.0, 0.5)); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arccoth(2.0)"); temp = 0.5 * log(3.0); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arcsech(0.2)"); temp = log(2*pow(6, 0.5)+5); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arccsch(0.2)"); /* temp = log(5 +pow(26, 0.5)); * only matches to 15 dp and therefore fails !! */ temp = 2.312438341272753; fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arcsinh(3.0)"); temp = log(3.0 +pow(10.0, 0.5)); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node = SBML_parseFormula("arctanh(0.2)"); temp = 0.5 * log(1.5); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), temp)); node->setType(AST_FUNCTION_DELAY); fail_unless(isnan(SBMLTransforms::evaluateASTNode(node))); node = SBML_parseFormula("factorial(3)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 6)); node->setType(AST_FUNCTION_PIECEWISE); fail_unless(isnan(SBMLTransforms::evaluateASTNode(node))); node = SBML_parseFormula("root(2, 4)"); fail_unless(equalDouble(SBMLTransforms::evaluateASTNode(node), 2)); }
ASTNode* CEvaluationNodeFunction::toAST(const CCopasiDataModel* pDataModel) const { SubType subType = (SubType)this->subType(); ASTNode* node = new ASTNode(); bool needFirstArg = true; switch (subType) { case S_INVALID: break; case S_LOG: node->setType(AST_FUNCTION_LN); break; case S_LOG10: { // log 10 needs two children, the log and the base node->setType(AST_FUNCTION_LOG); ASTNode* logBase = new ASTNode(); logBase->setType(AST_INTEGER); logBase->setValue(10); node->addChild(logBase); break; } case S_EXP: node->setType(AST_FUNCTION_EXP); break; case S_SIN: node->setType(AST_FUNCTION_SIN); break; case S_COS: node->setType(AST_FUNCTION_COS); break; case S_TAN: node->setType(AST_FUNCTION_TAN); break; case S_SEC: node->setType(AST_FUNCTION_SEC); break; case S_CSC: node->setType(AST_FUNCTION_CSC); break; case S_COT: node->setType(AST_FUNCTION_COT); break; case S_SINH: node->setType(AST_FUNCTION_SINH); break; case S_COSH: node->setType(AST_FUNCTION_COSH); break; case S_TANH: node->setType(AST_FUNCTION_TANH); break; case S_SECH: node->setType(AST_FUNCTION_SECH); break; case S_CSCH: node->setType(AST_FUNCTION_CSCH); break; case S_COTH: node->setType(AST_FUNCTION_COTH); break; case S_ARCSIN: node->setType(AST_FUNCTION_ARCSIN); break; case S_ARCCOS: node->setType(AST_FUNCTION_ARCCOS); break; case S_ARCTAN: node->setType(AST_FUNCTION_ARCTAN); break; case S_ARCSEC: node->setType(AST_FUNCTION_ARCSEC); break; case S_ARCCSC: node->setType(AST_FUNCTION_ARCCSC); break; case S_ARCCOT: node->setType(AST_FUNCTION_ARCCOT); break; case S_ARCSINH: node->setType(AST_FUNCTION_ARCSINH); break; case S_ARCCOSH: node->setType(AST_FUNCTION_ARCCOSH); break; case S_ARCTANH: node->setType(AST_FUNCTION_ARCTANH); break; case S_ARCSECH: node->setType(AST_FUNCTION_ARCSECH); break; case S_ARCCSCH: node->setType(AST_FUNCTION_ARCCSCH); break; case S_ARCCOTH: node->setType(AST_FUNCTION_ARCCOTH); break; case S_SQRT: node->setType(AST_FUNCTION_ROOT); break; case S_ABS: node->setType(AST_FUNCTION_ABS); break; case S_CEIL: node->setType(AST_FUNCTION_CEILING); break; case S_FLOOR: node->setType(AST_FUNCTION_FLOOR); break; case S_FACTORIAL: node->setType(AST_FUNCTION_FACTORIAL); break; case S_MINUS: node->setType(AST_MINUS); break; case S_PLUS: // if this is the unary plus as I suspect, // the node will be replaced by its only child delete node; node = dynamic_cast<const CEvaluationNode*>(this->getChild())->toAST(pDataModel); break; case S_NOT: node->setType(AST_LOGICAL_NOT); break; case S_RUNIFORM: { needFirstArg = false; node->setType(AST_FUNCTION); node->setName("RUNIFORM"); const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild()); const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling()); node->addChild(child->toAST(pDataModel)); node->addChild(sibling->toAST(pDataModel)); } break; case S_RNORMAL: { needFirstArg = false; node->setType(AST_FUNCTION); node->setName("RNORMAL"); const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild()); const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling()); node->addChild(child->toAST(pDataModel)); node->addChild(sibling->toAST(pDataModel)); } break; case S_RGAMMA: { needFirstArg = false; node->setType(AST_FUNCTION); node->setName("RGAMMA"); const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild()); const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling()); node->addChild(child->toAST(pDataModel)); node->addChild(sibling->toAST(pDataModel)); } break; case S_RPOISSON: { needFirstArg = false; node->setType(AST_FUNCTION); node->setName("RPOISSON"); const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild()); node->addChild(child->toAST(pDataModel)); } break; case S_MAX: { needFirstArg = false; node->setType(AST_FUNCTION); node->setName("MAX"); const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild()); const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling()); node->addChild(child->toAST(pDataModel)); node->addChild(sibling->toAST(pDataModel)); } break; case S_MIN: { needFirstArg = false; node->setType(AST_FUNCTION); node->setName("MIN"); const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild()); const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling()); node->addChild(child->toAST(pDataModel)); node->addChild(sibling->toAST(pDataModel)); } break; // :TODO: Bug 894: Implement me. //fatalError(); break; } if (subType != S_INVALID) { // the following is a workaround for a bug in libsbml 3.1.1 and 3.2.0 // where libsbml does not handle the case correctly that a root // function can have one or two children (MathML.cpp in function // writeFunctionRoot) if (subType == S_SQRT) { // add a degree node of value 2 as the first child ASTNode* pDegreeNode = new ASTNode(); pDegreeNode->setType(AST_INTEGER); pDegreeNode->setValue(2); node->addChild(pDegreeNode); } if (needFirstArg) { const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild()); node->addChild(child->toAST(pDataModel)); } } return node; }