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; }
bool CNormalProduct::simplify() { bool result = true; // don't work on the items in the set directly // make a copy, otherwise the set will be messed up std::set<CNormalItemPower*, compareItemPowers> itemPowersCopy(this->mItemPowers); std::set<CNormalItemPower*, compareItemPowers>::iterator it = itemPowersCopy.begin(), endit = itemPowersCopy.end(); CNormalItemPower* pTmpItemPower = NULL; this->mItemPowers.clear(); while (it != endit && result == true) { pTmpItemPower = *it; result = pTmpItemPower->simplify(); if (result) { this->multiply(*pTmpItemPower); } delete pTmpItemPower; ++it; } // we should combine all general power items of type power into // one large general power item which is again simplified // this we only do if the CNormalItemPower parent has an exponent of 1 it = this->mItemPowers.begin(); endit = this->mItemPowers.end(); std::vector<CNormalItemPower*> tmpV; // create a unit CNormalItemPower with one unit CNormalGeneralPower // and an exponent of 1 CNormalGeneralPower* pGeneralPower = NULL; //CNormalGeneralPower::createUnitGeneralPower(); while (it != endit) { if ((*it)->getExp() == 1.0 && (*it)->getItemType() == CNormalItemPower::POWER && dynamic_cast<CNormalGeneralPower*>(&(*it)->getItem())->getType() == CNormalGeneralPower::POWER && dynamic_cast<CNormalGeneralPower*>(&(*it)->getItem())->getRight().checkIsOne() ) { if (pGeneralPower) { pGeneralPower->multiply(*static_cast<CNormalGeneralPower*>(&(*it)->getItem())); } else { pGeneralPower = static_cast<CNormalGeneralPower*>(&(*it)->getItem()); pGeneralPower = new CNormalGeneralPower(*pGeneralPower); } delete *it; } else { if ((*it)->getItemType() == CNormalItemPower::POWER && dynamic_cast<CNormalGeneralPower*>(&(*it)->getItem())->getType() == CNormalGeneralPower::POWER && dynamic_cast<CNormalGeneralPower*>(&(*it)->getItem())->getLeft().checkIsOne() ) { delete *it; } else { tmpV.push_back(*it); } } ++ it; } if (pGeneralPower && !pGeneralPower->checkIsOne()) { CNormalItemPower* pTmpItemPower = new CNormalItemPower(); pTmpItemPower->setExp(1.0); pTmpItemPower->setItem(*pGeneralPower); tmpV.push_back(pTmpItemPower); } delete pGeneralPower; // clear the current set of items and add all the item in tmpV this->mItemPowers.clear(); std::vector<CNormalItemPower*>::iterator vIt = tmpV.begin(); std::vector<CNormalItemPower*>::iterator vEndIt = tmpV.end(); while (vIt != vEndIt) { this->multiply(**vIt); delete *vIt; ++vIt; } return result; }