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