Ejemplo n.º 1
0
CNormalSum* CNormalSum::createSum(const CEvaluationNode* node)
{
  CNormalSum* sum = new CNormalSum();
  if (node->getData() != "+")
    {
      if (node->getData() == "/")
        {
          CNormalFraction* fraction = CNormalFraction::createFraction(node);
          sum->add(*fraction);
          delete fraction;
          return sum;
        }
      else
        {
          CNormalProduct* product = CNormalProduct::createProduct(node);
          sum->add(*product);
          delete product;
          return sum;
        }
    }
  else
    {
      CNormalSum* sum1 = createSum(static_cast<const CEvaluationNode*>(node->getChild()));
      CNormalSum* sum2 = createSum(static_cast<const CEvaluationNode*>(node->getChild()->getSibling()));
      sum->add(*sum1);
      sum->add(*sum2);
      delete sum1;
      delete sum2;
      return sum;
    }
}
Ejemplo n.º 2
0
void CNormalProduct::setDenominatorsOne()
{
  // goes through all items and sets the denominators of the bases of all
  // general power items of type power to one
  CNormalSum* pTmpSum = new CNormalSum();
  CNormalProduct* pTmpProduct = new CNormalProduct();
  pTmpSum->add(*pTmpProduct);
  delete pTmpProduct;
  std::set<CNormalItemPower*, compareItemPowers>::iterator it = this->mItemPowers.begin(), endit = this->mItemPowers.end();
  while (it != endit)
    {
      if ((*it)->getItemType() == CNormalItemPower::POWER)
        {
          CNormalGeneralPower* pGenPow = dynamic_cast<CNormalGeneralPower*>(&(*it)->getItem());
          assert(pGenPow != NULL);
          // only set the denominator to 1 if it is a power item
          if (pGenPow->getType() == CNormalGeneralPower::POWER)
            {
              pGenPow->getLeft().setDenominator(*pTmpSum);
            }
        }
      ++it;
    }
  delete pTmpSum;
}
Ejemplo n.º 3
0
CNormalSum* CNormalSum::createUnitSum()
{
    CNormalSum* pSum = new CNormalSum();
    CNormalProduct* pTmpProduct = CNormalProduct::createUnitProduct();
    pSum->add(*pTmpProduct);
    delete pTmpProduct;
    return pSum;
}
Ejemplo n.º 4
0
bool CNormalSum::add(const CNormalSum& sum)
{
  std::set<CNormalProduct*, compareProducts>::const_iterator itProduct;
  std::set<CNormalProduct*, compareProducts>::const_iterator itProductEnd = sum.getProducts().end();
  for (itProduct = sum.getProducts().begin(); itProduct != itProductEnd; ++itProduct)
    add(**itProduct);

  std::set<CNormalFraction*>::const_iterator itFraction;
  std::set<CNormalFraction*>::const_iterator itFractionEnd = sum.getFractions().end();
  for (itFraction = sum.getFractions().begin(); itFraction != itFractionEnd; ++itFraction)
    add(**itFraction);

  return true;
}
Ejemplo n.º 5
0
CNormalGeneralPower* CNormalProduct::getDenominator() const
  {
    // go though all items that are general powers and check for general items
    // of type power that have denominators in their base that differ from 1
    // from all those denominators create a common denoninator and return it

    // first we generate a general power that is 1
    CNormalGeneralPower* pResult = new CNormalGeneralPower();
    pResult->setType(CNormalGeneralPower::POWER);
    CNormalSum* pTmpSum = new CNormalSum();
    CNormalFraction* pTmpFrac = new CNormalFraction();
    CNormalProduct* pTmpProduct = new CNormalProduct();
    pTmpSum->add(*pTmpProduct);
    delete pTmpProduct;
    pTmpFrac->setNumerator(*pTmpSum);
    pTmpFrac->setDenominator(*pTmpSum);
    pResult->setLeft(*pTmpFrac);
    pResult->setRight(*pTmpFrac);
    delete pTmpFrac;
    std::set<CNormalItemPower*, compareItemPowers>::const_iterator it = this->mItemPowers.begin(), endit = this->mItemPowers.end();
    while (it != endit)
      {
        if ((*it)->getItemType() == CNormalItemPower::POWER)
          {
            CNormalGeneralPower* pTmpPow = dynamic_cast<CNormalGeneralPower*>(&(*it)->getItem());
            assert(pTmpPow != NULL);
            // only set the numerator to 1 if it is a power item and the
            // denominator is not 1
            if (pTmpPow->getType() == CNormalGeneralPower::POWER && !pTmpPow->getLeft().checkDenominatorOne())
              {
                // set the numerator to 1
                pTmpPow = new CNormalGeneralPower(*pTmpPow);
                pTmpPow->getLeft().setNumerator(*pTmpSum);
                pResult->multiply(*pTmpPow);
                delete pTmpPow;
              }
          }
        ++it;
      }
    delete pTmpSum;
    return pResult;
  }
Ejemplo n.º 6
0
/**
 * Multiply this product with a lcm.
 * @return true
 */
const CNormalSum* CNormalProduct::multiply(const CNormalLcm& lcm)
{
  if (fabs(mFactor) < 1.0E-100)
    {
      CNormalSum* zeroSum = new CNormalSum();
      zeroSum->add(*this);
      return zeroSum;
    }
  CNormalLcm* tmp = new CNormalLcm(lcm);
  multiply(tmp->getItemPowers());
  CNormalSum* sum = new CNormalSum();
  sum->add(*this);
  std::vector<CNormalSum*>::const_iterator it;
  std::vector<CNormalSum*>::const_iterator itEnd = tmp->getSums().end();
  for (it = tmp->getSums().begin(); it != itEnd; ++it)
    {
      sum->multiply(**it);
    }
  delete tmp;
  return sum;
}
Ejemplo n.º 7
0
/**
 * Add a sum to this sum.
 * @return true.
 */
bool CNormalSum::add(const CNormalSum& sum)
{
    std::set<CNormalProduct*, compareProducts >::const_iterator itProduct = sum.mProducts.begin();
    std::set<CNormalProduct*, compareProducts >::const_iterator itProductEnd = sum.mProducts.end();

    while (itProduct != itProductEnd)
    {
        add(**itProduct);
        ++itProduct;
    }

    std::set<CNormalFraction*>::const_iterator itFraction = sum.getFractions().begin();
    std::set<CNormalFraction*>::const_iterator itFractionEnd = sum.getFractions().end();

    while (itFraction != itFractionEnd)
    {
        add(**itFraction);
        ++itFraction;
    }

    return true;
}
Ejemplo n.º 8
0
/**
 * Multiply this product with a sum NOT CONTAINING FRACTIONS!.
 * @return sum.
 */
CNormalSum* CNormalProduct::multiply(const CNormalSum& sum)
{
  if (fabs(mFactor) < 1.0E-100)
    {
      CNormalSum* zeroSum = new CNormalSum();
      zeroSum->add(*this);
      return zeroSum;
    }
  CNormalSum* tmp = new CNormalSum(sum);
  CNormalSum* newsum = new CNormalSum();
  std::set<CNormalProduct*, compareProducts>::const_iterator it;
  std::set<CNormalProduct*, compareProducts>::const_iterator itEnd = tmp->getProducts().end();
  for (it = tmp->getProducts().begin(); it != itEnd; ++it)
    {
      (*it)->multiply(*this);
      newsum->add(**it);
    }
  delete tmp;
  return newsum;
}
Ejemplo n.º 9
0
bool CNormalSum::simplify()
{
    bool result = true;
    // it is a bad idea to work directly on the items in the set.
    // this messes up the set
    // better copy the set first
    std::set<CNormalFraction*> fractionsCopy(this->mFractions);
    this->mFractions.clear();
    std::set<CNormalFraction*>::iterator it3 = fractionsCopy.begin(), endit3 = fractionsCopy.end();
    CNormalFraction* pTmpFraction = NULL;

    while (it3 != endit3)
    {
        pTmpFraction = *it3;
        pTmpFraction->simplify();
        this->add(*pTmpFraction);
        delete pTmpFraction;
        ++it3;
    }

    std::set<CNormalProduct*, compareProducts>::iterator it = this->mProducts.begin(), endit = this->mProducts.end();
    // add code to find general power items with exponent 1 where the parent
    // power item also has exponent 1
    // if the base of those has a denominator of 1, we add the products of
    // the numerator to this sum, otherwise, we have to add the whole base
    // to the fractions of this sum
    // afterwards, we have to simplify all products and all fractions again
    std::vector<CNormalBase*> newProducts;
    // go through all products and check the denominators
    CNormalProduct* pTmpProduct;

    while (it != endit)
    {
        pTmpProduct = *it;
        pTmpProduct->simplify();

        if (pTmpProduct->getItemPowers().size() == 1 &&
                fabs(((*pTmpProduct->getItemPowers().begin())->getExp() - 1.0) / 1.0) < 1e-12 &&
                (*pTmpProduct->getItemPowers().begin())->getItemType() == CNormalItemPower::POWER &&
                ((CNormalGeneralPower&)(*pTmpProduct->getItemPowers().begin())->getItem()).getRight().checkNumeratorOne() &&
                ((CNormalGeneralPower&)(*pTmpProduct->getItemPowers().begin())->getItem()).getRight().checkDenominatorOne()
           )
        {
            if (((CNormalGeneralPower&)(*pTmpProduct->getItemPowers().begin())->getItem()).getLeft().checkDenominatorOne())
            {
                newProducts.push_back(((CNormalGeneralPower&)(*pTmpProduct->getItemPowers().begin())->getItem()).getLeft().getNumerator().copy());
            }
            else
            {
                newProducts.push_back(((CNormalGeneralPower&)(*pTmpProduct->getItemPowers().begin())->getItem()).getLeft().copy());
            }

            delete pTmpProduct;
        }
        else
        {
            // if the denominator is not NULL, transform the product to a fraction
            CNormalGeneralPower* pDenom = pTmpProduct->getDenominator();

            if (pDenom == NULL || pDenom->checkIsOne())
            {
                newProducts.push_back(pTmpProduct);
            }
            else
            {
                // before creating the product, the denominators of all general items in
                // the product have to be set to 1 by calling setDenominatorsOne on the product
                pTmpProduct->setDenominatorsOne();
                CNormalFraction* pFraction = NULL;

                if (pDenom->getRight().checkIsOne())
                {
                    // the denominator is the left side of pDenom
                    pFraction = new CNormalFraction(pDenom->getLeft());
                    //
                    //pFraction = new CNormalFraction(pDenom->getLeft());
                    //// now we set the numerator
                    //CNormalSum* pSum = new CNormalSum();
                    //pSum->add(**it);
                    //pFraction->setNumerator(*pSum);
                    //delete pSum;
                }
                else
                {
                    // the fraction has the found denominator as its denominator and the
                    // numerator is the product of all items
                    pFraction = new CNormalFraction();
                    CNormalSum* pSum = new CNormalSum();
                    pSum->add(*pTmpProduct);
                    pFraction->setNumerator(*pSum);
                    delete pSum;
                    // now we have to invert the general fraction that is the
                    // denominator
                    CNormalFraction* pTmpFraction = CNormalFraction::createUnitFraction();
                    CNormalSum* pTmpSum = new CNormalSum(pDenom->getLeft().getDenominator());
                    pTmpFraction->setNumerator(*pTmpSum);
                    delete pTmpSum;
                    pDenom->setLeft(*pTmpFraction);
                    delete pTmpFraction;
                    CNormalProduct* pTmpProduct = CNormalProduct::createUnitProduct();
                    CNormalItemPower* pTmpItemPower = new CNormalItemPower();
                    pTmpItemPower->setExp(1.0);
                    pTmpItemPower->setItem(*pDenom);
                    pTmpProduct->multiply(*pTmpItemPower);
                    delete pTmpItemPower;
                    pTmpSum = new CNormalSum();
                    pTmpSum->add(*pTmpProduct);
                    delete pTmpProduct;
                    pFraction->setDenominator(*pTmpSum);
                    delete pTmpSum;
                }

                delete pTmpProduct;
                newProducts.push_back(pFraction);
            }

            if (pDenom != NULL) delete pDenom;
        }

        ++it;
    }

    this->mProducts.clear();
    std::vector<CNormalBase*>::const_iterator it2 = newProducts.begin(), endit2 = newProducts.end();
    const CNormalFraction* pFrac = NULL;
    const CNormalSum* pSum = NULL;
    const CNormalProduct* pProd = NULL;
    std::set<CNormalSum*> multipliers;

    while (it2 != endit2)
    {
        pProd = dynamic_cast<const CNormalProduct*>(*it2);

        if (pProd != NULL)
        {
            this->add(*pProd);
        }
        else
        {
            pFrac = dynamic_cast<const CNormalFraction*>(*it2);

            if (pFrac != NULL)
            {
                this->add(*pFrac);
            }
            else
            {
                pSum = dynamic_cast<const CNormalSum*>(*it2);

                if (pSum != NULL)
                {
                    this->add(*pSum);
                    /*
                    // check if the sum contains more then one product
                    // we have to multiply the sum with that other sum in the end
                    if(pSum->getProducts().size()>1)
                    {
                      multipliers.insert(static_cast<CNormalSum*>(pSum->copy()));
                    }
                    else
                    {
                      if(pSum->getProducts().size()==1 && (*pSum->getProducts().begin())->getItemPowers.size()==1)
                      {
                          // check if the one item power is a general power with
                          // an exponent of one and a denominator of one.
                          const CNormalItemPower* pPower=(*(*pSum->getProducts().begin())->getItemPowers().begin());
                          if(fabs(pPow->getExp()-1.0/1.0)<1e-12 && pPower->getItemType()==CNormalItemPower::POWER)
                          {
                              // check if it is a power operator and not modulo,
                              // check if the exponent is one and the denominator
                              // is one
                              const CNormalGeneralPower* pGenPow=static_cast<const CNormalGeneralPower*>(pPower->getItem());
                              if(pGenPow->getType()==CNormalGeneralPower::POWER && pGenPower->getRight().checkIsOne() && pGenPower->getLeft().checkDenominatorOne())
                              {
                                  // check if there are more then one product in
                              }
                              else
                              {
                                  this->add(*pSum);
                              }
                          }
                          else
                          {
                              this->add(*pSum);
                          }
                      }
                      else
                      {
                        this->add(*pSum);
                      }
                    }*/
                }
                else
                {
                    // this can never happen
                    fatalError();
                }
            }
        }

        delete *it2;
        ++it2;
    }

    std::set<CNormalSum*>::iterator it4 = multipliers.begin(), endit4 = multipliers.end();

    while (it4 != endit4)
    {
        this->multiply(**it4);
        delete *it4;
        ++it4;
    }

    return result;
}