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);
}
예제 #2
0
/**
 * 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());
    }

  }
예제 #3
0
/*
 * 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);

}
예제 #4
0
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;
}
예제 #5
0
/**
 * 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) );

}
예제 #7
0
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;
}
예제 #8
0
            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);
                    }
                }
            }
예제 #9
0
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));
    }
}
예제 #10
0
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) );
}
예제 #13
0
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();
        }
      }
    }
  }
}
예제 #14
0
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));
  
}
예제 #16
0
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;
}