Esempio n. 1
0
/**
 * Add product to this sum.
 * @return true.
 */
bool CNormalSum::add(const CNormalProduct& product)
{
    if (fabs(product.getFactor()) < 1.0E-100)
    {
        return true;
    }

    std::set<CNormalProduct*, compareProducts >::iterator it;
    std::set<CNormalProduct*, compareProducts >::iterator itEnd = mProducts.end();

    for (it = mProducts.begin(); it != itEnd; ++it)
    {
        if ((*it)->checkSamePowerList(product))
        {
            (*it)->setFactor((*it)->getFactor() + product.getFactor());

            // if this results in a 0, remove the item
            if (fabs((*it)->getFactor()) < 1.0E-100)
            {
                mProducts.erase(*it);
            }

            return true;
        }
    }

    CNormalProduct* tmp = new CNormalProduct(product);
    mProducts.insert(tmp);
    return true;
}
Esempio n. 2
0
/**
 * Add product to this sum.
 * @return true.
 */
bool CNormalSum::add(const CNormalProduct& product)
{
  if (fabs(product.getFactor()) < 1.0E-100)
    {
      return true;
    }

  std::set<CNormalProduct*, compareProducts >::iterator it = mProducts.begin();
  std::set<CNormalProduct*, compareProducts >::iterator itEnd = mProducts.end();

  while (it != itEnd)
    {
      if ((*it)->checkSamePowerList(product))
        {
          (*it)->setFactor((*it)->getFactor() + product.getFactor());

          // if this results in a 0, remove the item
          if (fabs((*it)->getFactor()) < 1.0E-100)
            {
              //unsigned int count=this->mProducts.size();
              mProducts.erase(it);
              //assert(count == this->mProducts.size()+1);
            }

          return true;
        }

      ++it;
    }

  CNormalProduct* tmp = new CNormalProduct(product);
  /*bool result=*/mProducts.insert(tmp);//.second;
  //assert(result == true);
  return true;
}
Esempio n. 3
0
/**
 * Multiply this product with another product.
 * @return true
 */
bool CNormalProduct::multiply(const CNormalProduct& product)
{
  multiply(product.getFactor());
  if (fabs(mFactor) < 1.0E-100)
    return true;
  multiply(product.getItemPowers());
  return true;
}
Esempio n. 4
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;
  CNormalBase* pTmpProduct2;

  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())
            {
              // this copy returns a CNormalSum
              // in order to keep the factor, we have to multiply
              // the sum with the factor
              pTmpProduct2 = ((CNormalGeneralPower&)(*pTmpProduct->getItemPowers().begin())->getItem()).getLeft().getNumerator().copy();
              dynamic_cast<CNormalSum*>(pTmpProduct2)->multiply(pTmpProduct->getFactor());
              newProducts.push_back(pTmpProduct2);
            }
          else
            {
              // this copy returns a fraction
              // so in order to retain the factor, we need to multiply the fraction with
              // a factor
              pTmpProduct2 = ((CNormalGeneralPower&)(*pTmpProduct->getItemPowers().begin())->getItem()).getLeft().copy();
              dynamic_cast<CNormalFraction*>(pTmpProduct2)->multiply(pTmpProduct->getFactor());
              newProducts.push_back(pTmpProduct2);
            }

          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;
}