예제 #1
0
// TODO Replace the recursive call (not critical since only used for debug)
void CEvaluationNode::printRecursively(std::ostream & os, int indent) const
{
  int i;

  os << std::endl;

  for (i = 0; i < indent; ++i) os << " ";

  os << "mData: " << mData << std::endl;

  for (i = 0; i < indent; ++i) os << " ";

  os << "mType: " << type(mType) << "  subType: " << subType(mType) << std::endl;

  for (i = 0; i < indent; ++i) os << " ";

  os << "mValue: " << mValue << std::endl;

  CEvaluationNode* tmp;

  tmp = (CEvaluationNode*)getChild();

  while (tmp)
    {
      tmp -> printRecursively(os, indent + 2);
      tmp = (CEvaluationNode*)tmp->getSibling();
    }
}
예제 #2
0
bool CEvaluationNode::operator<(const CEvaluationNode& right) const
{
  bool result = false;

  if (this->getType() < right.getType())
    {
      result = true;
    }
  else if (this->getType() == right.getType())
    {
      switch (CEvaluationNode::type(this->getType()))
        {
          case CEvaluationNode::CONSTANT:
          case CEvaluationNode::NUMBER:
          case CEvaluationNode::OBJECT:
          case CEvaluationNode::CALL:
          case CEvaluationNode::STRUCTURE:
          case CEvaluationNode::VARIABLE:
          case CEvaluationNode::WHITESPACE:
            result = (this->getData() < right.getData());
            break;

          case CEvaluationNode::OPERATOR:
          case CEvaluationNode::FUNCTION:
          case CEvaluationNode::CHOICE:
          case CEvaluationNode::LOGICAL:
          case CEvaluationNode::MV_FUNCTION:
          case CEvaluationNode::VECTOR:
          case CEvaluationNode::DELAY:
          case CEvaluationNode::INVALID:
            break;
        }

      const CEvaluationNode* pChild1 = dynamic_cast<const CEvaluationNode*>(this->getChild());

      const CEvaluationNode* pChild2 = dynamic_cast<const CEvaluationNode*>(right.getChild());

      while (result == false)
        {
          if (pChild1 == NULL || pChild2 == NULL)
            {
              if (pChild1 == NULL && pChild2 != NULL)
                {
                  result = true;
                }
            }
          else
            {
              result = (*pChild1 < *pChild2);
            }

          pChild1 = dynamic_cast<const CEvaluationNode*>(pChild1->getSibling());
          pChild2 = dynamic_cast<const CEvaluationNode*>(pChild2->getSibling());
        }
    }

  return result;
}
예제 #3
0
CEvaluationNode* CEvaluationNode::copyNode(const std::vector<CEvaluationNode*>& children) const
{
  CEvaluationNode *newnode = create(mType, getData());
  std::vector<CEvaluationNode*>::const_iterator it = children.begin(), endit = children.end();

  while (it != endit)
    {
      newnode->addChild(*it);
      ++it;
    }

  return newnode;
}
예제 #4
0
//static
void CDerive::compileTree(CEvaluationNode* node, const CEvaluationTree * pTree)
{
  if (!node) return;

  node->compile(pTree);

  CEvaluationNode* child = dynamic_cast<CEvaluationNode*>(node->getChild());

  while (child != NULL)
    {
      compileTree(child, pTree);
      child = dynamic_cast<CEvaluationNode*>(child->getSibling());
    }
}
CEvaluationNode* CEvaluationNodeNormalizer::normalizePowerNode(const CEvaluationNodeOperator* pNode)
{
  CEvaluationNode* pResult = NULL;

  if (pNode != NULL)
    {
      CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));

      if (pChild1 != NULL)
        {
          CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));

          if (pChild2 != NULL)
            {
              if (CEvaluationNode::type(pChild2->getType()) == CEvaluationNode::NUMBER)
                {
                  if (pChild2->value() - 1.0 < ZERO)
                    {
                      // replace it with the first child
                      pResult = pChild1;
                      delete pChild2;
                      pChild2 = NULL;
                    }
                  else if (pChild2->value() < ZERO)
                    {
                      // replace it by a number node of 1
                      pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1");
                      delete pChild1;
                      delete pChild2;
                      pChild1 = NULL;
                      pChild2 = NULL;
                    }
                }
              else
                {
                  pResult = new CEvaluationNodeOperator(CEvaluationNodeOperator::POWER, "^");
                  pResult->addChild(pChild1);
                  pResult->addChild(pChild2);
                }
            }
        }

      if (pResult == NULL) pResult = pNode->copyBranch();
    }

  return pResult;
}
예제 #6
0
CEvaluationNode * CMathExpression::createMassActionPart(const C_FLOAT64 * pK,
    const CCallParameters< C_FLOAT64 > * pSpecies)
{
  CEvaluationNode * pPart = new CEvaluationNodeOperator(CEvaluationNode::S_MULTIPLY, "*");
  pPart->addChild(createNodeFromValue(pK));

  if (pSpecies->size() == 0)
    return pPart;

  CEvaluationNode * pNode = pPart;
  CCallParameters< C_FLOAT64 >::const_iterator itSpecies = pSpecies->begin();
  CCallParameters< C_FLOAT64 >::const_iterator endSpecies = pSpecies->end();

  for (; itSpecies != endSpecies - 1; ++itSpecies)
    {
      CEvaluationNode * p = new CEvaluationNodeOperator(CEvaluationNode::S_MULTIPLY, "*");
      p->addChild(createNodeFromValue(itSpecies->value));
      pNode->addChild(p);
      pNode = p;
    }

  pNode->addChild(createNodeFromValue(itSpecies->value));

  return pPart;
}
예제 #7
0
파일: CDerive.cpp 프로젝트: jonasfoe/COPASI
CEvaluationNode* CDerive::subtract(CEvaluationNode *n1, CEvaluationNode *n2, bool simplify)
{
  if (simplify)
    {
      if (isZero(n1))
        {
          if (isZero(n2))
            {
              deleteBranch(n1);
              deleteBranch(n2);
              return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0");
            }

          //else
          //{
          //  deleteBranch(n1);
          //  return n2;
          //}
        }

      if (isZero(n2))
        {
          deleteBranch(n2);
          return n1;
        }

      // "numerical" simplification
      const CEvaluationNodeNumber * tmp1 = dynamic_cast<CEvaluationNodeNumber*>(n1);
      const CEvaluationNodeNumber * tmp2 = dynamic_cast<CEvaluationNodeNumber*>(n2);

      if (tmp1 && tmp2)
        {
          CEvaluationNode* tmpNN = new CEvaluationNodeNumber(tmp1->getValue() - tmp2->getValue());
          return tmpNN;
        }
    }

  CEvaluationNode *newNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MINUS, "-");
  newNode->addChild(n1);
  newNode->addChild(n2);

  return newNode;
}
예제 #8
0
// static
CEvaluationNode * CEvaluationNodeDelay::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children)
{
  assert(pASTNode->getNumChildren() == children.size());

  size_t i = 0, iMax = children.size();

  SubType subType = SubType::DELAY;
  std::string data = "delay";

  CEvaluationNode * pConvertedNode = new CEvaluationNodeDelay(subType, data);

  for (i = 0; i < iMax; ++i)
    {
      pConvertedNode->addChild(children[i]);
    }

  pConvertedNode->compile(NULL);
  return pConvertedNode;
}
예제 #9
0
파일: CDerive.cpp 프로젝트: jonasfoe/COPASI
CEvaluationNode* CDerive::add(CEvaluationNode* n1, CEvaluationNode* n2, bool simplify)
{
  if (simplify)
    {
      if (isZero(n1))
        {
          if (isZero(n2))
            {
              deleteBranch(n1);
              deleteBranch(n2);
              return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0");
            }
          else
            {
              deleteBranch(n1);
              return n2;
            }
        }

      if (isZero(n2))
        {
          deleteBranch(n2);
          return n1;
        }

      // "numerical" simplification
      const CEvaluationNodeNumber * tmp1 = dynamic_cast<CEvaluationNodeNumber*>(n1);
      const CEvaluationNodeNumber * tmp2 = dynamic_cast<CEvaluationNodeNumber*>(n2);

      if (tmp1 && tmp2)
        {
          return new CEvaluationNodeNumber(tmp1->getValue() + tmp2->getValue());
        }
    }

  CEvaluationNode *newNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::PLUS, "+");
  newNode->addChild(n1);
  newNode->addChild(n2);

  return newNode;
}
예제 #10
0
파일: CDerive.cpp 프로젝트: jonasfoe/COPASI
CEvaluationNode* CDerive::divide(CEvaluationNode* n1, CEvaluationNode* n2, bool simplify)
{
  if (simplify)
    {
      if (isZero(n1))
        {
          deleteBranch(n1);
          deleteBranch(n2);
          return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0");
        }

      /*if (isOne(n1))
      {
        if (isOne(n2))
        {
          deleteBranch(n1);
          deleteBranch(n2);
          return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1");
        }
        else
        {
          deleteBranch(n1);
          return n2;
        }
      }*/

      if (isOne(n2))
        {
          deleteBranch(n2);
          return n1;
        }
    }

  CEvaluationNode * tmpNode = NULL;
  tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::DIVIDE, "/");
  tmpNode->addChild(n1);
  tmpNode->addChild(n2);
  //tmpNode->compile(NULL);

  return tmpNode;
}
예제 #11
0
파일: CDerive.cpp 프로젝트: jonasfoe/COPASI
CEvaluationNode* CDerive::multiply(CEvaluationNode* n1, CEvaluationNode* n2, bool simplify)
{
  if (simplify)
    {
      if (isZero(n1) || isZero(n2))
        {
          deleteBranch(n1);
          deleteBranch(n2);
          return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0");
        }

      if (isOne(n1))
        {
          if (isOne(n2))
            {
              deleteBranch(n1);
              deleteBranch(n2);
              return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1");
            }
          else
            {
              deleteBranch(n1);
              return n2;
            }
        }

      if (isOne(n2))
        {
          deleteBranch(n2);
          return n1;
        }
    }

  CEvaluationNode * tmpNode = NULL;
  tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*");
  tmpNode->addChild(n1);
  tmpNode->addChild(n2);
  //tmpNode->compile(NULL);

  return tmpNode;
}
예제 #12
0
파일: CDerive.cpp 프로젝트: jonasfoe/COPASI
CEvaluationNode* CDerive::power(CEvaluationNode* n1, CEvaluationNode* n2, bool simplify)
{
  if (simplify)
    {
      if (isOne(n2))
        {
          deleteBranch(n2);
          return n1;
        }

      if (isOne(n1))
        {
          deleteBranch(n1);
          deleteBranch(n2);
          return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1");
        }

      if (isZero(n2) && !isZero(n1))
        {
          deleteBranch(n1);
          deleteBranch(n2);
          return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1");
        }

      if (isZero(n1) && !isZero(n2))
        {
          deleteBranch(n1);
          deleteBranch(n2);
          return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0");
        }
    }

  CEvaluationNode * tmpNode = NULL;
  tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::POWER, "^");
  tmpNode->addChild(n1);
  tmpNode->addChild(n2);
  //tmpNode->compile(NULL);

  return tmpNode;
}
예제 #13
0
void CMathObject::appendDelays(CMath::DelayData & Delays) const
{
  if (mpExpression == NULL)
    {
      return;
    }

  std::vector< CEvaluationNode * >::const_iterator it = mpExpression->getNodeList().begin();
  std::vector< CEvaluationNode * >::const_iterator end = mpExpression->getNodeList().end();

  for (; it != end; ++it)
    {
      switch (CEvaluationNode::type((*it)->getType()))
        {
          case CEvaluationNode::DELAY:
          {
            CEvaluationNode * pValueExpression = static_cast< CEvaluationNode * >((*it)->getChild());
            std::string Expression = static_cast< CEvaluationNode * >(pValueExpression->getSibling())->buildInfix();

            CMath::DelayData::iterator found = Delays.find(Expression);

            if (found == Delays.end())
              {
                found = Delays.insert(std::make_pair(Expression, CMath::DelayValueData()));
              }

            Expression = pValueExpression->buildInfix();
            found->second.insert(std::make_pair(Expression, std::make_pair((*it)->buildInfix(), const_cast< CMathObject * >(this))));
          }
          break;

          default:
            break;
        }
    }

  return;
}
예제 #14
0
bool CEvaluationNode::operator<(const CEvaluationNode& right) const
{
  if (mainType() != right.mainType())
    {
      return mainType() < right.mainType();
    }

  if (subType() != right.subType())
    {
      return subType() < right.subType();
    }

  switch (mainType())
    {
      case T_CONSTANT:
      case T_NUMBER:
      case T_OBJECT:
      case T_CALL:
      case T_STRUCTURE:
      case T_VARIABLE:
      case T_WHITESPACE:
        return getData() < right.getData();
        break;

      case T_OPERATOR:
      case T_FUNCTION:
      case T_CHOICE:
      case T_LOGICAL:
      case T_MV_FUNCTION:
      case T_VECTOR:
      case T_DELAY:
      case T_INVALID:
        break;
    }

  const CEvaluationNode* pChild1 = dynamic_cast<const CEvaluationNode*>(this->getChild());
  const CEvaluationNode* pChild2 = dynamic_cast<const CEvaluationNode*>(right.getChild());

  while (true)
    {
      if (pChild1 == NULL || pChild2 == NULL)
        {
          return pChild1 < pChild2;
        }

      if (*pChild1 < *pChild2) return true;

      pChild1 = dynamic_cast<const CEvaluationNode*>(pChild1->getSibling());
      pChild2 = dynamic_cast<const CEvaluationNode*>(pChild2->getSibling());
    }

  return false;
}
예제 #15
0
CEvaluationNode* CDerive::deriveBranch(const CEvaluationNode* node, unsigned C_INT32 variableIndex, const CCopasiObject * pObject)
{
  CEvaluationNode * newNode = NULL;

  const CEvaluationNodeOperator * pENO = dynamic_cast<const CEvaluationNodeOperator*>(node);

  if (pENO)
    {
      if (!pENO->getLeft() || !pENO->getRight()) return NULL;

      CEvaluationNode * pLeftDeriv = deriveBranch(pENO->getLeft(), variableIndex, pObject);

      if (!pLeftDeriv) return NULL;

      CEvaluationNode * pRightDeriv = deriveBranch(pENO->getRight(), variableIndex, pObject);

      if (!pRightDeriv) {delete pLeftDeriv; return NULL;}

      // we now know that derivations of the left and right branch exist

      switch ((CEvaluationNodeOperator::SubType) CEvaluationNode::subType(pENO->getType()))
        {
          case CEvaluationNodeOperator::MULTIPLY:
          {
            CEvaluationNode * pLeftCopy = pENO->getLeft()->copyBranch();
            CEvaluationNode * pRightCopy = pENO->getRight()->copyBranch();

            newNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::PLUS, "+");

            CEvaluationNodeOperator * tmpNode;
            tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*");
            tmpNode->addChild(pRightCopy);
            tmpNode->addChild(pLeftDeriv);
            //tmpNode->compile(NULL);
            newNode->addChild(tmpNode);

            tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*");
            tmpNode->addChild(pRightDeriv);
            tmpNode->addChild(pLeftCopy);
            //tmpNode->compile(NULL);
            newNode->addChild(tmpNode);

            //if (newNode) newNode->compile(NULL);
            return newNode;
          }
          break;

          case CEvaluationNodeOperator::DIVIDE:
          {
            CEvaluationNode * pLeftCopy = pENO->getLeft()->copyBranch();
            CEvaluationNode * pRightCopy = pENO->getRight()->copyBranch();

            //numerator
            CEvaluationNodeOperator * minusNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MINUS, "+");

            CEvaluationNodeOperator * tmpNode;
            tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*");
            tmpNode->addChild(pRightCopy);
            tmpNode->addChild(pLeftDeriv);
            //tmpNode->compile(NULL);
            minusNode->addChild(tmpNode);

            tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*");
            tmpNode->addChild(pRightDeriv);
            tmpNode->addChild(pLeftCopy);
            //tmpNode->compile(NULL);
            minusNode->addChild(tmpNode);

            minusNode->compile(NULL);

            //denominator
            CEvaluationNodeOperator * powerNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::POWER, "^");
            pRightCopy = pENO->getRight()->copyBranch();  //new copy
            powerNode->addChild(pRightCopy);
            powerNode->addChild(new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "2"));
            //powerNode->compile(NULL);

            newNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::DIVIDE, "/");
            newNode->addChild(minusNode);
            newNode->addChild(powerNode);
            //if (newNode) newNode->compile(NULL);
            return newNode;
          }
          break;

          case CEvaluationNodeOperator::PLUS:
            newNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::PLUS, "+");
            newNode->addChild(pLeftDeriv);
            newNode->addChild(pRightDeriv);
            //TODO check for zeros

            //if (newNode) newNode->compile(NULL);
            return newNode;
            break;

          case CEvaluationNodeOperator::MINUS:
            newNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MINUS, "-");
            newNode->addChild(pLeftDeriv);
            newNode->addChild(pRightDeriv);
            //TODO check for zeros

            //if (newNode) newNode->compile(NULL);
            return newNode;
            break;

          case CEvaluationNodeOperator::POWER:
          {
            CEvaluationNode * pLeftCopy = pENO->getLeft()->copyBranch();
            CEvaluationNode * pRightCopy = pENO->getRight()->copyBranch();

            // a^(b-1)
            CEvaluationNodeOperator * powerNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::POWER, "^");
            powerNode->addChild(pLeftCopy); // add a

            CEvaluationNodeOperator * tmpNode;
            tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MINUS, "-");
            tmpNode->addChild(pRightCopy); // add b
            tmpNode->addChild(new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1")); // 1
            powerNode->addChild(tmpNode); // add b-1

            // b*a´ + a*b´* ln a
            CEvaluationNodeOperator * plusNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::PLUS, "+");

            tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*");
            pRightCopy = pENO->getRight()->copyBranch();  //new copy of b
            tmpNode->addChild(pRightCopy); // add b
            tmpNode->addChild(pLeftDeriv); // add a´
            plusNode->addChild(tmpNode); // add b*a´

            tmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*");
            pLeftCopy = pENO->getLeft()->copyBranch();  //new copy of a
            tmpNode->addChild(pLeftCopy); // add a

            CEvaluationNodeOperator * tmptmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*");
            tmptmpNode->addChild(pRightDeriv); // add b´
            CEvaluationNodeFunction * funcNode = new CEvaluationNodeFunction(CEvaluationNodeFunction::LOG, "ln"); // ln a
            pLeftCopy = pENO->getLeft()->copyBranch();  //new copy of a
            funcNode->addChild(pLeftCopy); // add a
            tmptmpNode->addChild(funcNode); // add ln a

            tmpNode->addChild(tmptmpNode); // add b´ * ln a
            plusNode->addChild(tmpNode); // add a * b´ * ln a

            // a^(b-1)*(b*a´ + a*b´ * ln a)
            newNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*");
            newNode->addChild(powerNode);
            newNode->addChild(plusNode);
            return newNode;
          }
          break;

          default:
            break;
        }
    }

  const CEvaluationNodeVariable * pENV = dynamic_cast<const CEvaluationNodeVariable*>(node);

  if (pENV)
    {
      if (pObject) return NULL; // if a variable node occurs, we are differentiating a function

      if (variableIndex == pENV->getIndex())
        newNode = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1");
      else
        newNode = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0");

      return newNode;
    }

  const CEvaluationNodeNumber * pENN = dynamic_cast<const CEvaluationNodeNumber*>(node);

  if (pENN)
    {
      newNode = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0");
      return newNode;
    }

  return newNode;
}
예제 #16
0
파일: CDerive.cpp 프로젝트: jonasfoe/COPASI
//TODO remove pModel
CEvaluationNode* CDerive::deriveBranch(const CEvaluationNode* node, const CCopasiObject * pObject,
                                       std::vector<const CEvaluationNode*>& env,
                                       //std::vector<const CCopasiObject*>& objenv,
                                       const CEvaluationTree* pTree,
                                       bool simplify)
{
  CEvaluationNode * newNode = NULL;

  const CEvaluationNodeOperator * pENO = dynamic_cast<const CEvaluationNodeOperator*>(node);

  if (pENO)
    {
      if (!pENO->getLeft() || !pENO->getRight()) return NULL;

      CEvaluationNode * pLeftDeriv = deriveBranch(pENO->getLeft(), pObject, env, pTree, simplify);

      if (!pLeftDeriv) return NULL;

      CEvaluationNode * pRightDeriv = deriveBranch(pENO->getRight(), pObject, env, pTree, simplify);

      if (!pRightDeriv) {delete pLeftDeriv; return NULL;}

      // we now know that derivations of the left and right branch exist

      switch ((CEvaluationNodeOperator::SubType) CEvaluationNode::subType(pENO->getType()))
        {
          case CEvaluationNodeOperator::MULTIPLY:
          {
            CEvaluationNode * pLeftCopy = copyBranch_var2obj(pENO->getLeft(), env);
            CEvaluationNode * pRightCopy = copyBranch_var2obj(pENO->getRight(), env);

            CEvaluationNode * tmpNode1 = multiply(pRightCopy, pLeftDeriv, simplify);
            CEvaluationNode * tmpNode2 = multiply(pRightDeriv, pLeftCopy, simplify);

            return add(tmpNode1, tmpNode2, simplify);
          }
          break;

          case CEvaluationNodeOperator::DIVIDE:
          {
            CEvaluationNode * pLeftCopy = copyBranch_var2obj(pENO->getLeft(), env);
            CEvaluationNode * pRightCopy = copyBranch_var2obj(pENO->getRight(), env);

            //numerator
            CEvaluationNode * tmpNode1 = multiply(pRightCopy, pLeftDeriv, simplify);
            CEvaluationNode * tmpNode2 = multiply(pRightDeriv, pLeftCopy, simplify);

            CEvaluationNode * minusNode = subtract(tmpNode1, tmpNode2, simplify);

            minusNode->compile(NULL);

            //denominator
            CEvaluationNode * powerNode = power(copyBranch_var2obj(pENO->getRight(), env),
                                                new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "2"),
                                                simplify);

            return divide(minusNode, powerNode, simplify);
          }
          break;

          case CEvaluationNodeOperator::PLUS:

            return add(pLeftDeriv, pRightDeriv, simplify);
            break;

          case CEvaluationNodeOperator::MINUS:

            return subtract(pLeftDeriv, pRightDeriv, simplify);
            break;

          case CEvaluationNodeOperator::POWER:
          {
            // b-1
            CEvaluationNode * tmpNode = subtract(copyBranch_var2obj(pENO->getRight(), env),
                                                 new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1"),
                                                 simplify);

            // a^(b-1)
            CEvaluationNode * powerNode = power(copyBranch_var2obj(pENO->getLeft(), env), tmpNode, simplify);

            // b*a'
            tmpNode = multiply(copyBranch_var2obj(pENO->getRight(), env),
                               pLeftDeriv, simplify);

            // ln a
            CEvaluationNodeFunction * funcNode = new CEvaluationNodeFunction(CEvaluationNodeFunction::LOG, "ln");
            funcNode->addChild(copyBranch_var2obj(pENO->getLeft(), env)); // add a

            // a * b' * ln a
            CEvaluationNode * tmpNode2 = multiply(copyBranch_var2obj(pENO->getLeft(), env),
                                                  multiply(pRightDeriv, funcNode, simplify),
                                                  simplify);

            // b*a + a*b * ln a
            CEvaluationNode * plusNode = add(tmpNode, tmpNode2, simplify);

            // a^(b-1)*(b*a + a*b * ln a)
            return multiply(powerNode, plusNode, simplify);
          }
          break;

          default:
            break;
        }
    }

  const CEvaluationNodeVariable * pENV = dynamic_cast<const CEvaluationNodeVariable*>(node);

  if (pENV)
    {
      if (!env[pENV->getIndex()])
        return NULL;

      //basically just expand the tree.
      return deriveBranch(env[pENV->getIndex()], pObject, env, pTree, simplify);
    }

  const CEvaluationNodeNumber * pENN = dynamic_cast<const CEvaluationNodeNumber*>(node);

  if (pENN)
    {
      newNode = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0");
      return newNode;
    }

  const CEvaluationNodeObject *pENObj = dynamic_cast<const CEvaluationNodeObject*>(node);

  if (pENObj)
    {
      //first check whether the object is the derivation variable
      if (pObject->getCN() == pENObj->getObjectCN())
        {
          //std::cout << "*";
          return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "1");
        }

      //now we need to check if we know something about the object so that it needs to be expanded
      const CCopasiObject * tmpObj = (const CCopasiObject *)pENObj->getObjectInterfacePtr();

      if (!tmpObj)
        return NULL;

      //object is a concentration?
      if (tmpObj->getObjectName() == "Concentration")
        {
          //std::cout << "Concentration found" << std::endl;
          //In this context, the concentration is expanded as "amount of substance/volume"
          std::string tmpstr = tmpObj->getObjectParent() ? "<" + tmpObj->getObjectParent()->getCN() + ",Reference=ParticleNumber>" : "<>";
          CEvaluationNodeObject* amount = new CEvaluationNodeObject(CEvaluationNodeObject::CN, tmpstr);
          amount->compile(pTree);

          tmpstr = tmpObj->getObjectAncestor("Compartment") ? "<" + tmpObj->getObjectAncestor("Compartment")->getCN() + ",Reference=Volume>"  : "<>";
          CEvaluationNodeObject* volume = new CEvaluationNodeObject(CEvaluationNodeObject::CN, tmpstr);
          volume->compile(pTree);
          CEvaluationNodeObject* volume2 = new CEvaluationNodeObject(CEvaluationNodeObject::CN, tmpstr); //we need this node twice
          volume2->compile(pTree);

          CEvaluationNode* damount = deriveBranch(amount, pObject, env, pTree, simplify);
          CEvaluationNode* dvolume = deriveBranch(volume, pObject, env, pTree, simplify);

          // A / V - A*V /V^2
          return
            subtract(divide(damount, volume, simplify),
                     divide(multiply(amount, dvolume, simplify),
                            power(volume2, new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "2"), simplify),
                            simplify),
                     simplify);
        }

      //TODO:
      //object is an object with an assignment
      //object is dependent species
      //object is a reaction rate

      // otherwise return 0.
      return new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0");
    }

  const CEvaluationNodeCall  *pENCall = dynamic_cast<const CEvaluationNodeCall*>(node);

  if (pENCall)
    {

      //is it a function?
      const CFunction * tmpFunction = dynamic_cast<const CFunction*>(pENCall->getCalledTree());

//     const std::vector<CEvaluationNode *> getListOfChildNodes() const {return mCallNodes;}

      //create call environment for the called function
      std::vector<const CEvaluationNode*> subenv;
      size_t i, imax = pENCall->getListOfChildNodes().size();
      subenv.resize(imax);

      for (i = 0; i < imax; ++i)
        {
          CEvaluationNode* tmpnode = copyBranch_var2obj(pENCall->getListOfChildNodes()[i], env);
          compileTree(tmpnode, pTree);
          subenv[i] = tmpnode;
        }

      return deriveBranch(pENCall->getCalledTree()->getRoot(), pObject,
                          subenv,
                          pTree, simplify);
    }

  return newNode;
}
void test_depth_first_iterator::test_dfi()
{
  std::string infix("7-(3+(4-6))+1*8");
  CEvaluationTree* pTree = new CEvaluationTree();
  pTree->setInfix(infix);
  std::string s = pTree->getInfix();
  CPPUNIT_ASSERT(pTree->getRoot() != NULL);
  CEvaluationNodeDepthFirstIterator it(pTree->getRoot());
  CPPUNIT_ASSERT(it.isValid());
  CEvaluationNode* pNode = NULL;
  CEvaluationNodeNumber* pNumberNode = NULL;
  CEvaluationNodeOperator* pOperatorNode = NULL;
  // 7
  pNode = *it;
  CPPUNIT_ASSERT(pNode != NULL);
  CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER);
  pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode);
  CPPUNIT_ASSERT(pNumberNode != NULL);
  CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 7) / 7.0) <= std::numeric_limits<double>::min());
  // 3
  ++it;
  CPPUNIT_ASSERT(it.isValid() == true);
  pNode = *it;
  CPPUNIT_ASSERT(pNode != NULL);
  CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER);
  pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode);
  CPPUNIT_ASSERT(pNumberNode != NULL);
  CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 3) / 3.0) <= std::numeric_limits<double>::min());
  // 4
  ++it;
  CPPUNIT_ASSERT(it.isValid() == true);
  pNode = *it;
  CPPUNIT_ASSERT(pNode != NULL);
  CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER);
  pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode);
  CPPUNIT_ASSERT(pNumberNode != NULL);
  CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 4) / 4.0) <= std::numeric_limits<double>::min());
  // 6
  ++it;
  CPPUNIT_ASSERT(it.isValid() == true);
  pNode = *it;
  CPPUNIT_ASSERT(pNode != NULL);
  CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER);
  pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode);
  CPPUNIT_ASSERT(pNumberNode != NULL);
  CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 6) / 6.0) <= std::numeric_limits<double>::min());
  // -
  ++it;
  CPPUNIT_ASSERT(it.isValid() == true);
  pNode = *it;
  CPPUNIT_ASSERT(pNode != NULL);
  CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR);
  pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode);
  CPPUNIT_ASSERT(pOperatorNode != NULL);
  CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::MINUS);
  // +
  ++it;
  CPPUNIT_ASSERT(it.isValid() == true);
  pNode = *it;
  CPPUNIT_ASSERT(pNode != NULL);
  CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR);
  pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode);
  CPPUNIT_ASSERT(pOperatorNode != NULL);
  CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::PLUS);
  // -
  ++it;
  CPPUNIT_ASSERT(it.isValid() == true);
  pNode = *it;
  CPPUNIT_ASSERT(pNode != NULL);
  CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR);
  pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode);
  CPPUNIT_ASSERT(pOperatorNode != NULL);
  CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::MINUS);
  // 1
  ++it;
  CPPUNIT_ASSERT(it.isValid() == true);
  pNode = *it;
  CPPUNIT_ASSERT(pNode != NULL);
  CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER);
  pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode);
  CPPUNIT_ASSERT(pNumberNode != NULL);
  CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 1) / 1.0) <= std::numeric_limits<double>::min());
  // 8
  ++it;
  CPPUNIT_ASSERT(it.isValid() == true);
  pNode = *it;
  CPPUNIT_ASSERT(pNode != NULL);
  CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER);
  pNumberNode = dynamic_cast<CEvaluationNodeNumber*>(pNode);
  CPPUNIT_ASSERT(pNumberNode != NULL);
  CPPUNIT_ASSERT((fabs(pNumberNode->getValue() - 8) / 8.0) <= std::numeric_limits<double>::min());
  // *
  ++it;
  CPPUNIT_ASSERT(it.isValid() == true);
  pNode = *it;
  CPPUNIT_ASSERT(pNode != NULL);
  CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR);
  pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode);
  CPPUNIT_ASSERT(pOperatorNode != NULL);
  CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::MULTIPLY);
  // +
  ++it;
  CPPUNIT_ASSERT(it.isValid() == true);
  pNode = *it;
  CPPUNIT_ASSERT(pNode != NULL);
  CPPUNIT_ASSERT(CEvaluationNode::type(pNode->getType()) == CEvaluationNode::OPERATOR);
  pOperatorNode = dynamic_cast<CEvaluationNodeOperator*>(pNode);
  CPPUNIT_ASSERT(pOperatorNode != NULL);
  CPPUNIT_ASSERT((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOperatorNode->getType()) == CEvaluationNodeOperator::PLUS);

  ++it;
  CPPUNIT_ASSERT(it.isValid() == false);
  CPPUNIT_ASSERT(*it == NULL);

  delete pTree;
}
예제 #18
0
CEvaluationNode* CEvaluationNodeLogical::createNodeFromASTTree(const ASTNode& node)
{
  SubType subType;
  std::string data = "";

  switch (node.getType())
    {
      case AST_LOGICAL_AND:
        subType = AND;
        data = "and";
        break;
      case AST_LOGICAL_OR:
        subType = OR;
        data = "or";
        break;
      case AST_LOGICAL_XOR:
        subType = XOR;
        data = "xor";
        break;
      case AST_RELATIONAL_EQ:
        subType = EQ;
        data = "eq";
        break;
      case AST_RELATIONAL_GEQ:
        subType = GE;
        data = "ge";
        break;
      case AST_RELATIONAL_GT:
        subType = GT;
        data = "gt";
        break;
      case AST_RELATIONAL_LEQ:
        subType = LE;
        data = "le";
        break;
      case AST_RELATIONAL_LT:
        subType = LT;
        data = "lt";
        break;
      case AST_RELATIONAL_NEQ:
        subType = NE;
        data = "ne";
        break;
      default:
        subType = INVALID;
        break;
    }

  CEvaluationNode* convertedNode = new CEvaluationNodeLogical(subType, data);
  // convert the two children
  int i, iMax = node.getNumChildren();

  switch (subType)
    {
      case AND:
      case OR:
      case XOR:
        // these can have two or more children
        assert(iMax >= 2);
        convertedNode->addChild(CEvaluationTree::convertASTNode(*node.getChild(iMax - 1)));
        convertedNode->addChild(CEvaluationTree::convertASTNode(*node.getChild(iMax - 2)));
        iMax -= 3;

        for (i = iMax; i >= 0; --i)
          {
            CEvaluationNode* pTmpNode = new CEvaluationNodeLogical(subType, data);
            pTmpNode->addChild(convertedNode);
            pTmpNode->addChild(CEvaluationTree::convertASTNode(*node.getChild(i)));
            convertedNode = pTmpNode;
          }

        break;
      case EQ:
      case NE:
      case GE:
      case GT:
      case LE:
      case LT:
        // all these are binary
        convertedNode->addChild(CEvaluationTree::convertASTNode(*node.getLeftChild()));
        convertedNode->addChild(CEvaluationTree::convertASTNode(*node.getRightChild()));
        break;
      case INVALID:
        // do nothing
        break;
    }

  return convertedNode;
}
예제 #19
0
// static
CEvaluationNode * CEvaluationNodeLogical::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children)
{
    assert(pASTNode->getNumChildren() == children.size());

    size_t i = 0;
    size_t iMax = children.size();

    SubType subType;
    std::string data = "";

    switch (pASTNode->getType())
    {
    case AST_LOGICAL_AND:
        subType = AND;
        data = "and";
        break;

    case AST_LOGICAL_OR:
        subType = OR;
        data = "or";
        break;

    case AST_LOGICAL_XOR:
        subType = XOR;
        data = "xor";
        break;

    case AST_RELATIONAL_EQ:
        subType = EQ;
        data = "eq";
        break;

    case AST_RELATIONAL_GEQ:
        subType = GE;
        data = "ge";
        break;

    case AST_RELATIONAL_GT:
        subType = GT;
        data = "gt";
        break;

    case AST_RELATIONAL_LEQ:
        subType = LE;
        data = "le";
        break;

    case AST_RELATIONAL_LT:
        subType = LT;
        data = "lt";
        break;

    case AST_RELATIONAL_NEQ:
        subType = NE;
        data = "ne";
        break;

    default:
        subType = INVALID;
        break;
    }

    CEvaluationNode* pNode = NULL;
    // convert the two children

    switch (subType)
    {
    case AND:
    case OR:
    case XOR:

        // The number of chidren may vary
        switch (iMax)
        {
        case 0:

            if (subType == AND)
                pNode = new CEvaluationNodeConstant(CEvaluationNodeConstant::TRUE, "TRUE");
            else
                pNode = new CEvaluationNodeConstant(CEvaluationNodeConstant::FALSE, "FALSE");

            break;

        case 1:
            pNode = children[0];
            break;

        default:
        {
            pNode = new CEvaluationNodeLogical(subType, data);
            CEvaluationNode * pCurrent = pNode;

            // We have at least 2 children
            while (i < iMax - 1)
            {
                // add the first value
                pCurrent->addChild(children[i++]);

                switch (iMax - i)
                {
                case 1:
                    // We have only 1 more child
                    pCurrent->addChild(children[i++]);
                    break;

                default:
                    // We have at least 2 more children
                {
                    // create a new node with the same operator
                    CEvaluationNode * pTmp = new CEvaluationNodeLogical(subType, data);
                    pCurrent->addChild(pTmp);
                    pCurrent = pTmp;
                }
                break;
                }
            }
        }
        break;
        }

        break;

    case EQ:
    case NE:
    case GE:
    case GT:
    case LE:
    case LT:
        // all these are binary
        assert(iMax == 2);
        pNode = new CEvaluationNodeLogical(subType, data);
        pNode->addChild(children[0]);
        pNode->addChild(children[1]);
        break;

    case INVALID:
        // do nothing
        break;
    }

    return pNode;
}
CEvaluationNode* CEvaluationNodeNormalizer::normalizeModulusNode(const CEvaluationNodeOperator* pNode)
{
  CEvaluationNode* pResult = NULL;

  if (pNode != NULL)
    {
      CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));

      if (pChild1 != NULL)
        {
          CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));

          if (pChild2 != NULL)
            {
              if (CEvaluationNode::type(pChild2->getType()) == CEvaluationNode::NUMBER)
                {
                  // eliminate modulus 1
                  if (fabs(pChild2->value() - 1.0) < ZERO)
                    {
                      pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0");
                      delete pChild1;
                      delete pChild2;
                      pChild1 = NULL;
                      pChild2 = NULL;
                    }
                  else if (CEvaluationNode::type(pChild1->getType()) == CEvaluationNode::NUMBER &&
                           (CEvaluationNodeNumber::SubType)CEvaluationNode::subType(pChild1->getType()) == CEvaluationNodeNumber::INTEGER &&
                           (CEvaluationNodeNumber::SubType)CEvaluationNode::subType(pChild2->getType()) == CEvaluationNodeNumber::INTEGER)
                    {
                      // if both children are numbers, do the calculation
                      std::ostringstream os;
                      os << (long)pChild1->value() % (long)pChild2->value();
                      pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, os.str());
                      delete pChild1;
                      delete pChild2;
                      pChild1 = NULL;
                      pChild2 = NULL;
                    }
                }
              else
                {
                  // try to shorten numerator and denominator
                  // TODO find out if a factor is involved
                  if (*pChild1 == *pChild2)
                    {
                      pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0");
                      delete pChild1;
                      delete pChild2;
                      pChild1 = NULL;
                      pChild2 = NULL;
                    }
                }

              if (pResult == NULL)
                {
                  pResult = new CEvaluationNodeOperator(CEvaluationNodeOperator::MODULUS, "%");
                  pResult->addChild(pChild1);
                  pResult->addChild(pChild2);
                }
            }
          else
            {
              delete pChild1;
              pChild1 = NULL;
            }
        }

      if (pResult == NULL) pResult = pNode->copyBranch();
    }

  return pResult;
}
CEvaluationNode* CEvaluationNodeNormalizer::normalizeCEvaluationNodeFunction(const CEvaluationNodeFunction* pNode)
{
  CEvaluationNode* pResult = NULL;

  if (pNode != NULL)
    {
      CEvaluationNode* pTmpResult;

      switch ((CEvaluationNodeFunction::SubType)CEvaluationNode::subType(pNode->getType()))
        {
          case CEvaluationNodeFunction::INVALID:
            break;
          case CEvaluationNodeFunction::LOG:
          case CEvaluationNodeFunction::LOG10:
          case CEvaluationNodeFunction::EXP:
          case CEvaluationNodeFunction::SIN:
          case CEvaluationNodeFunction::COS:
          case CEvaluationNodeFunction::TAN:
          case CEvaluationNodeFunction::SEC:
          case CEvaluationNodeFunction::CSC:
          case CEvaluationNodeFunction::COT:
          case CEvaluationNodeFunction::SINH:
          case CEvaluationNodeFunction::COSH:
          case CEvaluationNodeFunction::TANH:
          case CEvaluationNodeFunction::SECH:
          case CEvaluationNodeFunction::CSCH:
          case CEvaluationNodeFunction::COTH:
          case CEvaluationNodeFunction::ARCSIN:
          case CEvaluationNodeFunction::ARCCOS:
          case CEvaluationNodeFunction::ARCTAN:
          case CEvaluationNodeFunction::ARCSEC:
          case CEvaluationNodeFunction::ARCCSC:
          case CEvaluationNodeFunction::ARCCOT:
          case CEvaluationNodeFunction::ARCSINH:
          case CEvaluationNodeFunction::ARCCOSH:
          case CEvaluationNodeFunction::ARCTANH:
          case CEvaluationNodeFunction::ARCSECH:
          case CEvaluationNodeFunction::ARCCSCH:
          case CEvaluationNodeFunction::ARCCOTH:
          case CEvaluationNodeFunction::SQRT:
          case CEvaluationNodeFunction::ABS:
          case CEvaluationNodeFunction::FLOOR:
          case CEvaluationNodeFunction::CEIL:
          case CEvaluationNodeFunction::FACTORIAL:
          case CEvaluationNodeFunction::NOT:
          case CEvaluationNodeFunction::MINUS:
            pResult = new CEvaluationNodeFunction((CEvaluationNodeFunction::SubType)CEvaluationNode::subType(pNode->getType()), pNode->getData());
            pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));

            if (pTmpResult != NULL)
              {
                pResult->addChild(pTmpResult);
              }
            else
              {
                delete pResult;
                pResult = NULL;
              }

            break;
          case CEvaluationNodeFunction::RUNIFORM:
          case CEvaluationNodeFunction::RNORMAL:
            //case CEvaluationNodeFunction::DELAY:
            // normalize all children
            pResult = new CEvaluationNodeFunction((CEvaluationNodeFunction::SubType)CEvaluationNode::subType(pNode->getType()), pNode->getData());
            pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));

            if (pTmpResult != NULL)
              {
                pResult->addChild(pTmpResult);
                pTmpResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));

                if (pTmpResult != NULL)
                  {
                    pResult->addChild(pTmpResult);
                  }
                else
                  {
                    delete pResult;
                    pResult = NULL;
                  }
              }
            else
              {
                delete pResult;
                pResult = NULL;
              }

            break;
            /*
            case CEvaluationNodeFunction::MINUS:
                // relace the - by a multiplication with -1
                // !!! Maybe this is not possible since CEvaluationNodeNumber
                // elements can not hold negative numbers.
                pResult=new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY,"");
            */
          case CEvaluationNodeFunction::PLUS:
            // eliminate the plus
            pResult = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));
            break;
        }

      if (pResult == NULL) pResult = pNode->copyBranch();
    }

  return pResult;
}
예제 #22
0
CEvaluationNode* CEvaluationNodeNormalizer::normalizeMinusNode(const CEvaluationNodeOperator* pNode)
{
  CEvaluationNode* pResult = NULL;

  if (pNode != NULL)
    {
      CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));

      if (pChild1 != NULL)
        {
          CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));

          if (pChild2 != NULL)
            {
              if (CEvaluationNode::type(pChild2->getType()) == CEvaluationNode::NUMBER)
                {
                  // eliminate subtraction of 0
                  if (fabs(pChild2->getValue()) < ZERO)
                    {
                      pResult = pChild1;
                      delete pChild2;
                      pChild1 = NULL;
                      pChild2 = NULL;
                    }
                  else if (CEvaluationNode::type(pChild1->getType()) == CEvaluationNode::NUMBER)
                    {
                      // if both children are numbers, do the calculation
                      std::ostringstream os;
                      os << pChild1->getValue() - pChild2->getValue();
                      pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, os.str());
                      delete pChild1;
                      delete pChild2;
                      pChild1 = NULL;
                      pChild2 = NULL;
                    }
                }
              else
                {
                  // TODO find out if a factor is involved
                  if (*pChild1 == *pChild2)
                    {
                      pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, "0.0");
                      delete pChild1;
                      delete pChild2;
                      pChild1 = NULL;
                      pChild2 = NULL;
                    }
                }

              if (pResult == NULL)
                {
                  pResult = new CEvaluationNodeOperator(CEvaluationNodeOperator::MINUS, "-");
                  pResult->addChild(pChild1);
                  pResult->addChild(pChild2);
                }
            }
          else
            {
              delete pChild1;
              pChild1 = NULL;
            }
        }

      if (pResult == NULL) pResult = pNode->copyBranch();
    }

  return pResult;
}
예제 #23
0
// static
CEvaluationNode * CEvaluationNodeChoice::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children)
{
  assert(pASTNode->getNumChildren() == children.size());

  size_t i = 0, iMax = children.size();

  // a piecewise function definition can have zero or more children.
  if (iMax == 0)
    {
      // create a NaN node
      return new CEvaluationNodeConstant(CEvaluationNodeConstant::_NaN, "NAN");
    }

  if (iMax == 1)
    {
      // this must be the otherwise
      // It is not clearly specified what happens if there are no pieces, but
      // an otherwise. I would assume that in this case, the otherwise always
      // takes effect

      return children[0];
    }

  SubType subType;
  std::string data = "";

  switch (pASTNode->getType())
    {
      case AST_FUNCTION_PIECEWISE:
        subType = IF;
        data = "if";
        break;

      default:
        subType = INVALID;
        break;
    }

  CEvaluationNodeChoice * pNode = new CEvaluationNodeChoice(subType, data);
  CEvaluationNode * pCurrent = pNode;

  // We have at least 2 children
  while (i < iMax - 1)
    {
      // add the condition
      pCurrent->addChild(children[i + 1]);
      // the true value
      pCurrent->addChild(children[i]);

      i += 2;

      switch (iMax - i)
        {
          case 0:
            // We are missing the false value
            pCurrent->addChild(new CEvaluationNodeConstant(CEvaluationNodeConstant::_NaN, "NAN"));
            break;

          case 1:
            // the false value
            pCurrent->addChild(children[i++]);
            break;

          default:
            // We have at least 2 more children
          {
            // create a new piecewise as the false value
            CEvaluationNode * pTmp = new CEvaluationNodeChoice(subType, data);
            pCurrent->addChild(pTmp);
            pCurrent = pTmp;
          }
          break;
        }
    }

  return pNode;
}
예제 #24
0
void CQMathMatrixWidget::slotDerivButtonPressed()
{
#ifdef _DERIV_TEST_
  std::cout << "Deriv" << std::endl;

  CModel* pModel = CCopasiRootContainer::getDatamodelList()->operator[](0).getModel();
  CEvaluationNode* tmpnode = pModel->prepareElasticity(&pModel->getReactions()[0],
                             &pModel->getMetabolites()[0], false);

  CEvaluationNode* tmpnode2 = pModel->prepareElasticity(&pModel->getReactions()[0],
                              &pModel->getMetabolites()[0], true);

  //create empty environment. Variable nodes should not occur in an expression
  std::vector<std::vector<std::string> > env;

  std::string tmpstring = tmpnode->buildMMLString(false, env);
  std::string tmpstring2 = tmpnode2->buildMMLString(false, env);

  mpMML->setBaseFontPointSize(qApp->font().pointSize());
  mpMML->setFontName(QtMmlWidget::NormalFont, qApp->font().family());

  mpMML->setContent(tmpstring.c_str());

  mpMML2->setBaseFontPointSize(qApp->font().pointSize());
  mpMML2->setFontName(QtMmlWidget::NormalFont, qApp->font().family());

  mpMML2->setContent(tmpstring2.c_str());

  QTableWidget * pTable = new QTableWidget(pModel->getReactions().size(), pModel->getMetabolites().size());
  pTable->show();

  int i, imax = pModel->getMetabolites().size();
  int j, jmax = pModel->getReactions().size();

  for (i = 0; i < imax; ++i)
    for (j = 0; j < jmax; ++j)
      {
        //CEvaluationNode* tmpnode = pModel->prepareElasticity(pModel->getReactions()[j],
        //                                                     pModel->getMetabolites()[i], false);

        CEvaluationNode* tmpnode2 = pModel->prepareElasticity(&pModel->getReactions()[j],
                                    &pModel->getMetabolites()[i], true);

        //evaluate
        CExpression * tmpExp = new CExpression("tmp expr", pModel);
        tmpExp->setRoot(tmpnode2);
        tmpExp->compile();
        std::cout << tmpExp->calcValue() << std::endl;

        //create empty environment. Variable nodes should not occur in an expression
        std::vector<std::vector<std::string> > env;

        //std::string tmpstring = tmpnode->buildMMLString(false, env);
        std::string tmpstring2 = tmpnode2->buildMMLString(false, env);

        QtMmlWidget* tmpmml = new QtMmlWidget();
        tmpmml->setBaseFontPointSize(qApp->font().pointSize() - 2);
        tmpmml->setFontName(QtMmlWidget::NormalFont, qApp->font().family());
        tmpmml->setContent(tmpstring2.c_str());
        pTable->setCellWidget(j, i, tmpmml);

        //tmpmml = new QtMmlWidget();
        //tmpmml->setBaseFontPointSize(qApp->font().pointSize()-2);
        //tmpmml->setFontName(QtMmlWidget::NormalFont, qApp->font().family());
        //tmpmml->setContent(tmpstring.c_str());
        //pTable->setCellWidget(i, 1, tmpmml);
      }

  pTable->resizeColumnsToContents();
  pTable->resizeRowsToContents();
#endif
}
CEvaluationNode* CEvaluationNodeNormalizer::normalizeMultiplyNode(const CEvaluationNodeOperator* pNode)
{
  CEvaluationNode* pResult = NULL;

  if (pNode != NULL)
    {
      CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));

      if (pChild1 != NULL)
        {
          CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));

          if (pChild2 != NULL)
            {
              // if one of the child nodes is zero, replace the node with a number
              // node of value 0

              // if one of the nodes is a number node of 1, replace the node by the
              // other child
              if (CEvaluationNode::type(pChild1->getType()) == CEvaluationNode::NUMBER)
                {
                  if (fabs(pChild1->value() - 1.0) < ZERO)
                    {
                      pResult = pChild2;
                      delete pChild1;
                      pChild1 = NULL;
                      pChild2 = NULL;
                    }
                  else if (fabs(pChild1->value()) < ZERO)
                    {
                      pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0");
                      // we are done
                      delete pChild1;
                      delete pChild2;
                      pChild1 = NULL;
                      pChild2 = NULL;
                    }
                }

              if (pChild2 && CEvaluationNode::type(pChild2->getType()) == CEvaluationNode::NUMBER)
                {
                  if (fabs(pChild2->value() - 1.0) < ZERO)
                    {
                      pResult = pChild1;
                      delete pChild2;
                      pChild2 = NULL;
                      pChild1 = NULL;
                    }
                  else if (fabs(pChild2->value()) < ZERO)
                    {
                      pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::INTEGER, "0");
                      // we are done
                      delete pChild1;
                      delete pChild2;
                      pChild1 = NULL;
                      pChild2 = NULL;
                    }
                }

              if (!pResult)
                {
                  pResult = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*");
                  pResult->addChild(pChild1);
                  pResult->addChild(pChild2);
                }

              if (pResult->getType() == CEvaluationNode::OPERATOR)
                {
                  // multiply all number nodes in a multiplication chain
                  std::vector<CEvaluationNode*> chainNodes;
                  findChainNodes(dynamic_cast<CEvaluationNodeOperator*>(pResult), chainNodes);
                  CEvaluationNodeNormalizer::eliminateMultipleNumbers((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pResult->getType()), chainNodes);
                  // replace multiplication of identical items by a power node with the
                  // correct power
                  CEvaluationNodeNormalizer::collectIdenticalBranches((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pResult->getType()), chainNodes);
                  // reorder nodes again
                  CEvaluationNodeNormalizer::reorderNodes(chainNodes);
                  // rebuild pResult;
                  CEvaluationNodeOperator::SubType subType = (CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pResult->getType());
                  delete pResult;
                  pResult = CEvaluationNodeNormalizer::buildOperatorBranchFromChain(subType, chainNodes);
                }
            }
        }

      if (pResult == NULL) pResult = pNode->copyBranch();
    }

  return pResult;
}
예제 #26
0
// static
CEvaluationNode * CEvaluationNodeNumber::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children)
{
  assert(pASTNode->getNumChildren() == children.size());

  std::stringstream ss;
  ss.imbue(std::locale::classic());
  ss.precision(std::numeric_limits<double>::digits10 + 2);

  SubType subType;
  std::string data = "";
  CEvaluationNode* pNode = NULL;

  switch (pASTNode->getType())
    {
      case AST_INTEGER:
        subType = SubType::INTEGER;

        if (pASTNode->getInteger() < 0)
          {
            pNode = new CEvaluationNodeFunction(SubType::MINUS, "-");

            ss << abs(pASTNode->getInteger());
            data = ss.str();
            pNode->addChild(new CEvaluationNodeNumber(subType, data));
          }
        else
          {
            ss << pASTNode->getInteger();
            data = ss.str();
            pNode = new CEvaluationNodeNumber(subType, data);
          }

        break;

      case AST_REAL:
        subType = SubType::DOUBLE;

        if (pASTNode->getReal() == (std::numeric_limits<C_FLOAT64>::infinity()))
          {
            pNode = new CEvaluationNodeConstant(SubType::Infinity, "INFINITY");
          }
        else if (pASTNode->getReal() == (-std::numeric_limits<C_FLOAT64>::infinity()))
          {
            pNode = new CEvaluationNodeFunction(SubType::MINUS, "-");
            pNode->addChild(new CEvaluationNodeConstant(SubType::Infinity, "INFINITY"));
          }
        else if (isnan(pASTNode->getReal()))
          {
            pNode = new CEvaluationNodeConstant(SubType::NaN, "NAN");
          }
        else if (pASTNode->getReal() < 0.0)
          {
            pNode = new CEvaluationNodeFunction(SubType::MINUS, "-");

            ss << fabs(pASTNode->getReal());
            data = ss.str();
            pNode->addChild(new CEvaluationNodeNumber(subType, data));
          }
        else
          {
            ss << pASTNode->getReal();
            data = ss.str();
            pNode = new CEvaluationNodeNumber(subType, data);
          }

        break;

      case AST_REAL_E:
        subType = SubType::ENOTATION;

        if (pASTNode->getReal() == (std::numeric_limits<C_FLOAT64>::infinity()))
          {
            pNode = new CEvaluationNodeConstant(SubType::Infinity, "INFINITY");
          }
        else if (pASTNode->getReal() == (-std::numeric_limits<C_FLOAT64>::infinity()))
          {
            pNode = new CEvaluationNodeFunction(SubType::MINUS, "-");
            pNode->addChild(new CEvaluationNodeConstant(SubType::Infinity, "INFINITY"));
          }
        else if (isnan(pASTNode->getReal()))
          {
            pNode = new CEvaluationNodeConstant(SubType::NaN, "NAN");
          }
        else if (pASTNode->getReal() < 0.0)
          {
            pNode = new CEvaluationNodeFunction(SubType::MINUS, "-");

            ss << fabs(pASTNode->getReal());
            data = ss.str();
            pNode->addChild(new CEvaluationNodeNumber(subType, data));
          }
        else
          {
            ss << pASTNode->getReal();
            data = ss.str();
            pNode = new CEvaluationNodeNumber(subType, data);
          }

        break;

      case AST_RATIONAL:
        subType = SubType::RATIONALE;

        if (pASTNode->getReal() < 0.0) // getReal returns the value of the node
          {
            pNode = new CEvaluationNodeFunction(SubType::MINUS, "-");

            ss << "(" << abs(pASTNode->getNumerator()) << "/" << abs(pASTNode->getDenominator()) << ")";
            data = ss.str();
            pNode->addChild(new CEvaluationNodeNumber(subType, data));
          }
        else
          {
            ss << "(" << pASTNode->getNumerator() << "/" << pASTNode->getDenominator() << ")";
            data = ss.str();
            pNode = new CEvaluationNodeNumber(subType, data);
          }

        break;

      default:
        subType = SubType::INVALID;
        break;
    }

  return pNode;
}
예제 #27
0
void test_compare_utilities::test_copasi_function_expansion()
{
  CCopasiDataModel* pDataModel = pCOPASIDATAMODEL;;
  std::istringstream iss(test_compare_utilities::MODEL_STRING1);
  CPPUNIT_ASSERT(load_cps_model_from_stream(iss, *pDataModel) == true);
  CFunctionDB* pFunctionDB = CCopasiRootContainer::getFunctionList();
  // function_5
  CEvaluationTree* pTree = pFunctionDB->findFunction("function_4");
  CPPUNIT_ASSERT(pTree != NULL);
  // generate a call node
  CFunction* pFunction = dynamic_cast<CFunction*>(pTree);
  CPPUNIT_ASSERT(pFunction != NULL);
  CEvaluationNodeCall* pCallNode = new CEvaluationNodeCall(CEvaluationNode::S_FUNCTION, pFunction->getObjectName());
  CPPUNIT_ASSERT(pCallNode != NULL);
  CFunctionParameters* pFunctionParameters = &pFunction->getVariables();
  unsigned int i = 0, iMax = pFunctionParameters->size();

  while (i < iMax)
    {
      CFunctionParameter* pParameter = (*pFunctionParameters)[i];
      CPPUNIT_ASSERT(pParameter != NULL);
      CEvaluationNodeVariable* pVariableNode = new CEvaluationNodeVariable(CEvaluationNode::S_DEFAULT, pParameter->getObjectName());
      pCallNode->addChild(pVariableNode);
      ++i;
    }

  CEvaluationNode* pExpanded = expand_function_calls(pCallNode, pFunctionDB);
  delete pCallNode;
  CPPUNIT_ASSERT(pExpanded != NULL);
  CPPUNIT_ASSERT(pExpanded->mainType() == CEvaluationNode::T_OPERATOR);
  CPPUNIT_ASSERT(pExpanded->subType() == CEvaluationNode::S_DIVIDE);
  CEvaluationNode* pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_PLUS);
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE);
  CPPUNIT_ASSERT(pChild->getData() == std::string("y"));
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getSibling());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE);
  CPPUNIT_ASSERT(pChild->getData() == std::string("x"));
  CPPUNIT_ASSERT(pChild->getSibling() == NULL);
  pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild()->getSibling());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_NUMBER);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_DOUBLE);
  CPPUNIT_ASSERT((fabs(pChild->getValue() - 2.0) / 2.0) < 1e-6);
  CPPUNIT_ASSERT(pChild->getSibling() == NULL);
  delete pExpanded;

  // function_5
  pTree = pFunctionDB->findFunction("function_5");
  CPPUNIT_ASSERT(pTree != NULL);
  // generate a call node
  pFunction = dynamic_cast<CFunction*>(pTree);
  CPPUNIT_ASSERT(pFunction != NULL);
  pCallNode = new CEvaluationNodeCall(CEvaluationNode::S_FUNCTION, pFunction->getObjectName());
  CPPUNIT_ASSERT(pCallNode != NULL);
  pFunctionParameters = &pFunction->getVariables();
  i = 0, iMax = pFunctionParameters->size();

  while (i < iMax)
    {
      CFunctionParameter* pParameter = (*pFunctionParameters)[i];
      CPPUNIT_ASSERT(pParameter != NULL);
      CEvaluationNodeVariable* pVariableNode = new CEvaluationNodeVariable(CEvaluationNode::S_DEFAULT, pParameter->getObjectName());
      pCallNode->addChild(pVariableNode);
      ++i;
    }

  pExpanded = expand_function_calls(pCallNode, pFunctionDB);
  delete pCallNode;
  CPPUNIT_ASSERT(pExpanded != NULL);
  CPPUNIT_ASSERT(pExpanded->mainType() == CEvaluationNode::T_OPERATOR);
  CPPUNIT_ASSERT(pExpanded->subType() == CEvaluationNode::S_PLUS);
  pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MINUS);
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE);
  CPPUNIT_ASSERT(pChild->getData() == std::string("a"));
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getSibling());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MULTIPLY);
  CPPUNIT_ASSERT(pChild->getSibling() == NULL);
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE);
  CPPUNIT_ASSERT(pChild->getData() == std::string("c"));
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getSibling());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_NUMBER);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_DOUBLE);
  CPPUNIT_ASSERT((fabs(pChild->getValue() - 1.3) / 1.3) < 1e-6);
  CPPUNIT_ASSERT(pChild->getSibling() == NULL);

  // (3*b)-5.23
  pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild()->getSibling());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MINUS);
  // 3*b
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MULTIPLY);
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_NUMBER);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_DOUBLE);
  CPPUNIT_ASSERT((fabs(pChild->getValue() - 3.0) / 3.0) < 1e-6);
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getSibling());
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE);
  CPPUNIT_ASSERT(pChild->getData() == std::string("b"));
  CPPUNIT_ASSERT(pChild->getSibling() == NULL);
  // 5.23
  pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild()->getSibling()->getChild()->getSibling());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_NUMBER);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_DOUBLE);
  CPPUNIT_ASSERT((fabs(pChild->getValue() - 5.23) / 5.23) < 1e-6);
  CPPUNIT_ASSERT(pChild->getSibling() == NULL);

  delete pExpanded;

  // function_6
  pTree = pFunctionDB->findFunction("function_6");
  CPPUNIT_ASSERT(pTree != NULL);
  // generate a call node
  pFunction = dynamic_cast<CFunction*>(pTree);
  CPPUNIT_ASSERT(pFunction != NULL);
  pCallNode = new CEvaluationNodeCall(CEvaluationNode::S_FUNCTION, pFunction->getObjectName());
  CPPUNIT_ASSERT(pCallNode != NULL);
  pFunctionParameters = &pFunction->getVariables();
  i = 0, iMax = pFunctionParameters->size();

  while (i < iMax)
    {
      CFunctionParameter* pParameter = (*pFunctionParameters)[i];
      CPPUNIT_ASSERT(pParameter != NULL);
      CEvaluationNodeVariable* pVariableNode = new CEvaluationNodeVariable(CEvaluationNode::S_DEFAULT, pParameter->getObjectName());
      pCallNode->addChild(pVariableNode);
      ++i;
    }

  pExpanded = expand_function_calls(pCallNode, pFunctionDB);
  delete pCallNode;
  CPPUNIT_ASSERT(pExpanded != NULL);
  // (k1-k3*1.3)+((3*k2)-5.23)
  CPPUNIT_ASSERT(pExpanded->mainType() == CEvaluationNode::T_OPERATOR);
  CPPUNIT_ASSERT(pExpanded->subType() == CEvaluationNode::S_PLUS);
  pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MINUS);
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE);
  CPPUNIT_ASSERT(pChild->getData() == std::string("k1"));
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getSibling());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MULTIPLY);
  CPPUNIT_ASSERT(pChild->getSibling() == NULL);
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE);
  CPPUNIT_ASSERT(pChild->getData() == std::string("k3"));
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getSibling());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_NUMBER);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_DOUBLE);
  CPPUNIT_ASSERT((fabs(pChild->getValue() - 1.3) / 1.3) < 1e-6);
  CPPUNIT_ASSERT(pChild->getSibling() == NULL);

  // (3*b)-5.23
  pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild()->getSibling());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MINUS);
  // 3*b
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_OPERATOR);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_MULTIPLY);
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getChild());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_NUMBER);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_DOUBLE);
  CPPUNIT_ASSERT((fabs(pChild->getValue() - 3.0) / 3.0) < 1e-6);
  pChild = dynamic_cast<CEvaluationNode*>(pChild->getSibling());
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_VARIABLE);
  CPPUNIT_ASSERT(pChild->getData() == std::string("k2"));
  CPPUNIT_ASSERT(pChild->getSibling() == NULL);
  // 5.23
  pChild = dynamic_cast<CEvaluationNode*>(pExpanded->getChild()->getSibling()->getChild()->getSibling());
  CPPUNIT_ASSERT(pChild != NULL);
  CPPUNIT_ASSERT(pChild->mainType() == CEvaluationNode::T_NUMBER);
  CPPUNIT_ASSERT(pChild->subType() == CEvaluationNode::S_DOUBLE);
  CPPUNIT_ASSERT((fabs(pChild->getValue() - 5.23) / 5.23) < 1e-6);
  CPPUNIT_ASSERT(pChild->getSibling() == NULL);

  delete pExpanded;
}
CEvaluationNode* CEvaluationNodeNormalizer::normalizePlusNode(const CEvaluationNodeOperator* pNode)
{
  CEvaluationNode* pResult = NULL;

  if (pNode != NULL)
    {
      CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));

      if (pChild1 != NULL)
        {
          CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));

          if (pChild2 != NULL)
            {
              // if one of the nodes is a number node of 0, replace the node by the
              // other child
              if (CEvaluationNode::type(pChild1->getType()) == CEvaluationNode::NUMBER)
                {
                  if (fabs(pChild1->value()) < ZERO)
                    {
                      pResult = pChild2;
                      delete pChild1;
                      pChild1 = NULL;
                      pChild2 = NULL;
                    }
                }

              if (pChild2 != NULL && CEvaluationNode::type(pChild2->getType()) == CEvaluationNode::NUMBER)
                {
                  if (fabs(pChild2->value()) < ZERO)
                    {
                      if (pChild2 != pResult)
                        {
                          pResult = pChild1;
                          delete pChild2;
                        }

                      pChild1 = NULL;
                      pChild2 = NULL;
                    }
                }

              if (!pResult)
                {
                  pResult = new CEvaluationNodeOperator(CEvaluationNodeOperator::PLUS, "+");
                  pResult->addChild(pChild1);
                  pResult->addChild(pChild2);
                }

              if (pResult->getType() == CEvaluationNode::OPERATOR)
                {
                  // add all number nodes in a summation chain
                  std::vector<CEvaluationNode*> chainNodes;
                  findChainNodes(dynamic_cast<CEvaluationNodeOperator*>(pResult), chainNodes);
                  CEvaluationNodeNormalizer::eliminateMultipleNumbers((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pResult->getType()), chainNodes);
                  // replace addition of identical items by a multiplication node with the
                  // correct number
                  CEvaluationNodeNormalizer::collectIdenticalBranches((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pResult->getType()), chainNodes);
                  // reorder nodes again
                  CEvaluationNodeNormalizer::reorderNodes(chainNodes);
                  // rebuild pResult;
                  CEvaluationNodeOperator::SubType subType = (CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pResult->getType());
                  delete pResult;
                  pResult = CEvaluationNodeNormalizer::buildOperatorBranchFromChain(subType, chainNodes);
                }
            }
          else
            {
              delete pChild1;
              pChild1 = NULL;
            }
        }

      if (pResult == NULL) pResult = pNode->copyBranch();
    }

  return pResult;
}
CEvaluationNode* CEvaluationNodeNormalizer::normalizeDivideNode(const CEvaluationNodeOperator* pNode)
{
  CEvaluationNode* pResult = NULL;

  if (pNode != NULL)
    {
      CEvaluationNode* pChild1 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()));

      if (pChild1 != NULL)
        {
          CEvaluationNode* pChild2 = CEvaluationNodeNormalizer::normalize(dynamic_cast<const CEvaluationNode*>(pNode->getChild()->getSibling()));

          if (pChild2 != NULL)
            {
              if (CEvaluationNode::type(pChild2->getType()) == CEvaluationNode::NUMBER)
                {
                  // eliminate divisions by 1
                  if (fabs(pChild2->value() - 1.0) < ZERO)
                    {
                      pResult = pChild1;
                      delete pChild2;
                      pChild2 = NULL;
                    }
                  else if (CEvaluationNode::type(pChild1->getType()) == CEvaluationNode::NUMBER)
                    {
                      // if both children are numbers, do the calculation
                      std::ostringstream os;
                      os << pChild1->value() / pChild2->value();
                      pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, os.str());
                      delete pChild1;
                      delete pChild2;
                      pChild1 = NULL;
                      pChild2 = NULL;
                    }
                }
              else
                {
                  // try to shorten numerator and denominator
                  // TODO find out if a factor is involved
                  if (*pChild1 == *pChild2)
                    {
                      pResult = new CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, "1.0");
                      delete pChild1;
                      delete pChild2;
                      pChild1 = NULL;
                      pChild2 = NULL;
                    }
                }

              if (pResult == NULL)
                {
                  pResult = new CEvaluationNodeOperator(CEvaluationNodeOperator::DIVIDE, "/");
                  pResult->addChild(pChild1);
                  pResult->addChild(pChild2);
                }
            }
          else
            {
              delete pChild1;
              pChild1 = NULL;
            }
        }

      if (pResult == NULL) pResult = pNode->copyBranch();
    }

  return pResult;
}
예제 #30
0
// static
CEvaluationNode * CEvaluationNodeFunction::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children)
{
    assert(pASTNode->getNumChildren() == children.size());

    size_t iMax = children.size();

    int type = (int)pASTNode->getType();
    SubType subType;
    std::string data = "";

    if (type == AST_FUNCTION_ROOT)
    {
        CEvaluationNode * pNode = NULL;

        switch (iMax)
        {
        case 1:
            pNode = new CEvaluationNodeFunction(S_SQRT, "sqrt");
            pNode->addChild(children[0]);
            break;

        case 2:
            /**
             * Replaces all root nodes with the corresponding power
             * operator since COPASI does not have the ROOT function.
             */
        {
            pNode = new CEvaluationNodeOperator(S_POWER, "^");
            pNode->addChild(children[1]); // Value
            CEvaluationNode * pExponent = new CEvaluationNodeOperator(S_DIVIDE, "/");
            pNode->addChild(pExponent);
            pExponent->addChild(new CEvaluationNodeNumber(S_DOUBLE, "1"));
            pExponent->addChild(children[0]); // Degree
        }
        break;
        }

        return pNode;
    }
    else if (type == AST_FUNCTION_LOG && iMax == 2)
    {
        /**
         * Replaces all LOG10 (AST_FUNCTION_LOG) nodes that have two
         * children with the quotient of two LOG10 nodes with the base
         * as the argument for the divisor LOG10 node.
         */

        CEvaluationNode * pNode = new CEvaluationNodeOperator(S_DIVIDE, "/");
        CEvaluationNode * pValue = new CEvaluationNodeFunction(S_LOG10, "log10");
        pValue->addChild(children[1]);
        CEvaluationNode * pBase = new CEvaluationNodeFunction(S_LOG10, "log10");
        pBase->addChild(children[0]);
        pNode->addChild(pValue);
        pNode->addChild(pBase);

        return pNode;
    }

    switch (type)
    {
    case AST_FUNCTION_ABS:
        subType = S_ABS;
        data = "abs";
        break;

    case AST_FUNCTION_ARCCOS:
        subType = S_ARCCOS;
        data = "acos";
        break;

    case AST_FUNCTION_ARCCOSH:
        subType = S_ARCCOSH;
        data = "arccosh";
        break;

    case AST_FUNCTION_ARCCOT:
        subType = S_ARCCOT;
        data = "arccot";
        break;

    case AST_FUNCTION_ARCCOTH:
        subType = S_ARCCOTH;
        data = "arccoth";
        break;

    case AST_FUNCTION_ARCCSC:
        subType = S_ARCCSC;
        data = "arccsc";
        break;

    case AST_FUNCTION_ARCCSCH:
        subType = S_ARCCSCH;
        data = "arccsch";
        break;

    case AST_FUNCTION_ARCSEC:
        subType = S_ARCSEC;
        data = "arcsec";
        break;

    case AST_FUNCTION_ARCSECH:
        subType = S_ARCSECH;
        data = "arcsech";
        break;

    case AST_FUNCTION_ARCSIN:
        subType = S_ARCSIN;
        data = "asin";
        break;

    case AST_FUNCTION_ARCSINH:
        subType = S_ARCSINH;
        data = "arcsinh";
        break;

    case AST_FUNCTION_ARCTAN:
        subType = S_ARCTAN;
        data = "atan";
        break;

    case AST_FUNCTION_ARCTANH:
        subType = S_ARCTANH;
        data = "arctanh";
        break;

    case AST_FUNCTION_CEILING:
        subType = S_CEIL;
        data = "ceil";
        break;

    case AST_FUNCTION_COS:
        subType = S_COS;
        data = "cos";
        break;

    case AST_FUNCTION_COSH:
        subType = S_COSH;
        data = "cosh";
        break;

    case AST_FUNCTION_COT:
        subType = S_COT;
        data = "cot";
        break;

    case AST_FUNCTION_COTH:
        subType = S_COTH;
        data = "coth";
        break;

    case AST_FUNCTION_CSC:
        subType = S_CSC;
        data = "csc";
        break;

    case AST_FUNCTION_CSCH:
        subType = S_CSCH;
        data = "csch";
        break;

    case AST_FUNCTION_EXP:
        subType = S_EXP;
        data = "exp";
        break;

    case AST_FUNCTION_FACTORIAL:
        subType = S_FACTORIAL;
        data = "factorial";
        break;

    case AST_FUNCTION_FLOOR:
        subType = S_FLOOR;
        data = "floor";
        break;

    case AST_FUNCTION_LN:
        subType = S_LOG;
        data = "log";
        break;

    case AST_FUNCTION_LOG:
        subType = S_LOG10;
        data = "log10";
        break;

    case AST_FUNCTION_SEC:
        subType = S_SEC;
        data = "sec";
        break;

    case AST_FUNCTION_SECH:
        subType = S_SECH;
        data = "sech";
        break;

    case AST_FUNCTION_SIN:
        subType = S_SIN;
        data = "sin";
        break;

    case AST_FUNCTION_SINH:
        subType = S_SINH;
        data = "sinh";
        break;

    case AST_FUNCTION_TAN:
        subType = S_TAN;
        data = "tan";
        break;

    case AST_FUNCTION_TANH:
        subType = S_TANH;
        data = "tanh";
        break;

    case AST_LOGICAL_NOT:
        subType = S_NOT;
        data = "not";
        break;

    default:
        subType = S_INVALID;
        fatalError();
        break;
    }

    assert(iMax == 1);
    CEvaluationNode * pNode = new CEvaluationNodeFunction(subType, data);

    if (!children.empty())
        pNode->addChild(children[0]);

    return pNode;
}