Esempio n. 1
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;
}
Esempio n. 2
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;
}
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;
}
Esempio n. 4
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
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;
}
Esempio n. 11
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::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;
}
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::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;
}
Esempio n. 16
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;
}
Esempio n. 17
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;
}
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;
}
Esempio n. 19
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;
}
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;
}
Esempio n. 21
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;
}
Esempio n. 22
0
CEvaluationNode* CEvaluationNodeFunction::simplifyNode(const std::vector<CEvaluationNode*>& children) const
{
    assert(children.size() > 0);
    CEvaluationNode* child1 = children[0];

    switch (mSubType)
    {
    case S_MINUS:
    {
        switch (child1->mainType())
        {
        case CEvaluationNode::T_OPERATOR:
        {
            switch (child1->subType())
            {
            case S_DIVIDE:
            {
                // -(a/b) -> (-a)/b
                // want to recognize a fraction in a sum easily
                CEvaluationNode *newnode = CEvaluationNode::create(T_OPERATOR, S_DIVIDE, "/");
                CEvaluationNode *newchild1 = CEvaluationNode::create(T_FUNCTION, S_MINUS, "-");
                CEvaluationNode *newchild2 = dynamic_cast<CEvaluationNode*>(child1->getChild()->getSibling())->copyBranch();
                CEvaluationNode *grandchild = dynamic_cast<CEvaluationNode*>(child1->getChild())->copyBranch();
                newnode->addChild(newchild1, NULL);
                newnode->addChild(newchild2, newchild1);
                newchild1->addChild(grandchild, NULL);
                delete child1;
                return newnode;
            }

            case S_PLUS:
            {
                // -(a+b) -> (-a)+(-b)
                // negativity should be property of product
                CEvaluationNode *newnode = CEvaluationNode::create(T_OPERATOR, S_PLUS, "+");
                CEvaluationNode *newchild1 = CEvaluationNode::create(T_FUNCTION, S_MINUS, "-");
                CEvaluationNode *newchild2 = CEvaluationNode::create(T_FUNCTION, S_MINUS, "-");
                CEvaluationNode *grandchild1 = dynamic_cast<CEvaluationNode*>(child1->getChild())->copyBranch();
                CEvaluationNode *grandchild2 = dynamic_cast<CEvaluationNode*>(child1->getChild()->getSibling())->copyBranch();
                newnode->addChild(newchild1, NULL);
                newnode->addChild(newchild2, newchild1);
                newchild1->addChild(grandchild1, NULL);
                newchild2->addChild(grandchild2, NULL);
                delete child1;
                return newnode;
            }

            default:        // cases POWER, MULTIPLY, MODULUS. don't expect MINUS to occur anymore
            {
                CEvaluationNode *newnode = copyNode(children);
                return newnode;
            }
            }
        }

        case CEvaluationNode::T_FUNCTION:
        {
            if (child1->getData() == "-")
            {
                // -(-a) -> a
                CEvaluationNode *newnode = dynamic_cast<CEvaluationNode*>(child1->getChild())->copyBranch();
                delete child1;
                return newnode;
            }

            // default: copy
            CEvaluationNode *newnode = copyNode(children);
            return newnode;
        }

        case CEvaluationNode::T_NUMBER:
        {
            std::stringstream tmp;
            tmp << *child1->getValuePointer() *(-1.0);
            CEvaluationNode* newnode = CEvaluationNode::create(T_NUMBER, S_DOUBLE, tmp.str());
            delete child1;
            return newnode;
        }

        default:         //cases VARIABLE, CONSTANT..
        {
            CEvaluationNode *newnode = copyNode(children);
            return newnode;
        }
        }

        break;
    }

    case S_SQRT:
    {
        // write as ^0.5
        CEvaluationNode* newnode = CEvaluationNode::create(T_OPERATOR, S_POWER, "^");
        CEvaluationNode* newchild2 = CEvaluationNode::create(T_NUMBER, S_DOUBLE, "0.5");
        newnode->addChild(child1, NULL);
        newnode->addChild(newchild2, child1);
        return newnode;
    }

    default:
    {
        CEvaluationNode *newnode = copyNode(children);
        return newnode;
    }
    }
}