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; }
CNormalProduct * CNormalProduct::createProduct(const CEvaluationNode* node) { CNormalProduct * product = new CNormalProduct(); switch (node->mainType()) { case CEvaluationNode::T_OPERATOR: // PLUS(->createSum), MINUS(translated as +(-..)) and DIVIDE(->createFraction) do not occur. { if (node->getData() == "^") { if (CEvaluationNode::type(static_cast<const CEvaluationNode*>(node->getChild()->getSibling())->getType()) == CEvaluationNode::T_NUMBER) { CNormalItemPower* power = CNormalItemPower::createItemPower(node); product->multiply(*power); delete power; return product; } else { CNormalItem* item = CNormalItem::createItem(node); product->multiply(*item); delete item; return product; } } if (node->getData() == "*") { CNormalProduct* product1 = createProduct(static_cast<const CEvaluationNode*>(node->getChild())); CNormalProduct* product2 = createProduct(static_cast<const CEvaluationNode*>(node->getChild()->getSibling())); product->multiply(*product1); product->multiply(*product2); delete product1; delete product2; return product; } //default (case MODULUS): CNormalItem* item = CNormalItem::createItem(node); product->multiply(*item); delete item; return product; } case CEvaluationNode::T_NUMBER: { product->multiply(node->value()); return product; } case CEvaluationNode::T_FUNCTION: { if (node->getData() == "-") { product->multiply(-1.0); CNormalProduct * product2 = createProduct(dynamic_cast<const CEvaluationNode*>(node->getChild())); product->multiply(*product2); delete product2; return product; } CNormalItem * item = CNormalItem::createItem(node); product->multiply(*item); delete item; return product; } default: //cases VARIABLE, CONSTANT, CALL, CHOICE, LOGICAL, OBJECT, VECTOR { CNormalItem * item = CNormalItem::createItem(node); product->multiply(*item); delete item; return product; } } }