COPASI API
4.16.103
|
#include <CNormalTranslation.h>
Static Public Member Functions | |
static CEvaluationNode * | createChain (const CEvaluationNode *pLink, const CEvaluationNode *pNeutralElement, const std::vector< const CEvaluationNode * > &elements) |
static CEvaluationNode * | createChain (const CEvaluationNode *pLink, const CEvaluationNode *pNeutralElement, const std::vector< CEvaluationNode * > &elements) |
static CEvaluationNode * | createOperatorChain (CEvaluationNodeOperator::SubType type, const char *data, const std::vector< CEvaluationNode * > &nodes) |
static CEvaluationNode * | createOperatorChain (CEvaluationNodeOperator::SubType type, const char *data, const std::vector< const CEvaluationNode * > &nodes) |
static CEvaluationNode * | expandPowerBases (const CEvaluationNode *pRoot) |
static CEvaluationNode * | expandPowerExponents (const CEvaluationNode *pRoot) |
static CEvaluationNode * | expandProducts (const CEvaluationNode *pOrig) |
static void | findSummands (const CEvaluationNode *pRoot, std::vector< const CEvaluationNode * > &summands) |
static bool | has_duplicate_nodes (const CEvaluationNode *pNode) |
static CEvaluationNode * | newEvaluateNumbers (const CEvaluationNode *pOrig) |
static CNormalFraction * | normAndSimplify (const CEvaluationNode *root0) |
static CNormalFraction * | normAndSimplifyReptdly (const CEvaluationTree *tree0, unsigned int depth=0) |
static CNormalFraction * | normAndSimplifyReptdly (const CEvaluationNode *tree0, unsigned int depth=0) |
static CEvaluationNode * | simplifyTree (const CEvaluationNode *node) |
static CEvaluationNode * | simplifyTreeReptdly (const CEvaluationNode *root0) |
static void | splitProduct (const CEvaluationNode *pRoot, std::vector< const CEvaluationNode * > &multiplications, std::vector< const CEvaluationNode * > &divisions, bool division) |
static void | splitSum (const CEvaluationNode *pRoot, std::vector< CEvaluationNode * > &additions, std::vector< CEvaluationNode * > &substractions, bool minus) |
static void | splitSum (const CEvaluationNode *pRoot, std::vector< const CEvaluationNode * > &additions, std::vector< const CEvaluationNode * > &substractions, bool minus) |
Static Public Attributes | |
static const CEvaluationNode | NEUTRAL_ELEMENT_ADD = CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, "0.0") |
static const CEvaluationNode | NEUTRAL_ELEMENT_AND = CEvaluationNodeConstant(CEvaluationNodeConstant::TRUE, "TRUE") |
static const CEvaluationNode | NEUTRAL_ELEMENT_MULTIPLY = CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, "1.0") |
static const CEvaluationNode | NEUTRAL_ELEMENT_OR = CEvaluationNodeConstant(CEvaluationNodeConstant::FALSE, "FALSE") |
static const CEvaluationNode | ONE_NODE = CNormalTranslation::NEUTRAL_ELEMENT_MULTIPLY |
static const CEvaluationNode | PLUS_NODE = CEvaluationNodeOperator(CEvaluationNodeOperator::PLUS, "+") |
static const CEvaluationNode | TIMES_NODE = CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*") |
static const CEvaluationNode | ZERO_NODE = CNormalTranslation::NEUTRAL_ELEMENT_ADD |
Static Protected Attributes | |
static const unsigned int | RECURSION_LIMIT = 20 |
static const double | ZERO = 1e-100 |
The class for simplification and translation of trees into CNormal
Definition at line 84 of file CNormalTranslation.h.
|
static |
More general version of createOperatorChain. This method can also be used to combine logical item chains. Once I know this works, I will replace createOperatorChain with this method.
This version of create chain copies the given elements in the vector and then calls the createChain method which does not need copying.
Definition at line 5905 of file CNormalTranslation.cpp.
Referenced by convertToCEvaluationNode(), createFraction(), createProduct(), expandPowerBases(), expandPowerExponents(), expandPowerNodes(), factorize(), matchSummands(), multiply(), newCancel(), and newEvaluateNumbers().
|
static |
More general version of createOperatorChain. This version does not copy the nodes in the given vector, but uses them directly. This method can also be used to combine logical item chains. method.
This method creates a chain of operations. The individual elements are linked with copies of pLink. NULL is returned if elements is empty. So if this method is used to create a chanin of OR linked elements which will be embedded in another and linked chain, the neutral element should be a TRUE node since AND combining something with true does not change the result. The neutral element is the element that does not change the result of the operation represented be pLink. So if pLink represents a multiplication, the neutral element is the number node 1.0. This method does not copy the elements in the given vector, but uses them in the chain directly.
Definition at line 5933 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), CEvaluationNode::copyBranch(), and pResult.
|
static |
Given a vector of nodes, this method creates a multiplication chain of all the nodes. The chain contains copies of the nodes passed in.
Given a vector of nodes, this method creates a multiplication chain of all the nodes. The chain contains the original nodes and not copies.
Definition at line 5887 of file CNormalTranslation.cpp.
Referenced by factorize(), and matchSummands().
|
static |
Given a vector of nodes, this method creates a multiplication chain of all the nodes. The chain contains copies of the nodes passed in.
Concatenates the goven nodes by the given operation. So if the nodes are node1, node2,node3 and the operation is multiplication, this will create node1 * node2 * node3 The node that is returned contains copies of the original nodes and the caller is responsible for freeing the memory.
Definition at line 298 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), CEvaluationNode::copyBranch(), CEvaluationNodeNumber::DOUBLE, and pResult.
|
staticprotected |
This routine is responsible for all elementary eliminations, e.g. addition of 0. These steps can not lead to new simplifications in the children of the node being simplified, so it is not necessary to run this on the children again.
This routine is responsible for all elementary eliminations, e.g. addition of 0. These steps can not lead to new simplifications in the children of the node being simplified, so it is not necessary to run this on the children again.
Calls one of the following: elementaryEliminationPower elementaryEliminationModulus elementaryEliminationMultiply elementaryEliminationDivide elementaryEliminationPlus elementaryEliminationMinus elementaryEliminationFunction
Which method is called depends on the node passed to the method. The method is called recursively on the children of the passed in node.
Definition at line 622 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), CEvaluationNodeOperator::DIVIDE, elementaryEliminationDivide(), elementaryEliminationFunction(), elementaryEliminationMinus(), elementaryEliminationModulus(), elementaryEliminationMultiply(), elementaryEliminationPlus(), elementaryEliminationPower(), fatalError, CEvaluationNode::FUNCTION, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNodeOperator::MINUS, CEvaluationNodeOperator::MODULUS, CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::OPERATOR, CEvaluationNodeOperator::PLUS, CEvaluationNodeOperator::POWER, pResult, CCopasiNode< _Data >::removeChild(), CEvaluationNode::subType(), and CEvaluationNode::type().
Referenced by eliminate().
|
staticprotected |
This method makes the elementary elimination on a divide node.
This method makes the elementary elimination on a divide node.
The following eliminations are made: a) Nan / x -> Nan b) x / NaN -> NaN c) x / 0 -> NaN d) 0 / x -> 0 e) x / x -> 1 f) x / 1 -> x
The caller is responsible for freeing the memory for the returned object.
Definition at line 1116 of file CNormalTranslation.cpp.
References CEvaluationNodeConstant::_NaN, CEvaluationNode::CONSTANT, CEvaluationNode::copyBranch(), createNormalRepresentation(), CEvaluationNodeOperator::DIVIDE, CEvaluationNodeNumber::DOUBLE, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNode::NUMBER, CEvaluationNode::OPERATOR, pResult, CEvaluationNode::subType(), CNormalFraction::toString(), CEvaluationNode::type(), and ZERO.
Referenced by elementaryElimination().
|
staticprotected |
This method makes elementary eliminations on function nodes
This method makes elementary eliminations on function nodes The elimiation made here are:
a) unary plus nodes are replaced by their child b) unary minus nodes of numbers are replaced by the corresponding number * -1 c) Function calls to NaN nodes are replaced by NaN
The node returned by this method is a new node and the caller is responsible for freeing the memory.
Definition at line 700 of file CNormalTranslation.cpp.
References CEvaluationNodeConstant::_NaN, CEvaluationNode::CONSTANT, CEvaluationNode::copyBranch(), CEvaluationNodeNumber::DOUBLE, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNodeFunction::INVALID, CEvaluationNodeFunction::MINUS, CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::NUMBER, CEvaluationNodeFunction::PLUS, pResult, CEvaluationNode::subType(), and CEvaluationNode::type().
Referenced by elementaryElimination().
|
staticprotected |
This method makes the elementary elimination on a minus node.
This method makes the elementary elimination on a minus node. The following eliminations are made: a) NaN - x -> NaN b) x - NaN -> NaN c) x - x -> 0 d) x - 0 -> x e) 0 - x -> -1 * x
The caller is responsible for freeing the memory of the returned object.
Definition at line 1222 of file CNormalTranslation.cpp.
References CEvaluationNodeConstant::_NaN, CCopasiNode< _Data >::addChild(), CEvaluationNode::CONSTANT, CEvaluationNode::copyBranch(), createNormalRepresentation(), CEvaluationNodeNumber::DOUBLE, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNodeOperator::MINUS, CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::NUMBER, CEvaluationNode::OPERATOR, pResult, CEvaluationNode::subType(), CNormalFraction::toString(), CEvaluationNode::type(), and ZERO.
Referenced by elementaryElimination().
|
staticprotected |
This method makes the elementary elimination on a modulus node.
This method makes the elementary elimination on a modulus node. The following eliminations are made: a) NaNx -> NaN b) xNaN -> NaN c) xx -> 0 d) 0x -> 0 e) 1n -> 1 (n is a number, other than 1)
The caller is responsible for freeing the memory of the returned object.
Definition at line 987 of file CNormalTranslation.cpp.
References CEvaluationNodeConstant::_NaN, CEvaluationNode::CONSTANT, createNormalRepresentation(), CEvaluationNodeNumber::DOUBLE, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNode::getValue(), CEvaluationNodeOperator::MODULUS, CEvaluationNode::NUMBER, CEvaluationNode::OPERATOR, pResult, CEvaluationNode::subType(), CNormalFraction::toString(), CEvaluationNode::type(), and ZERO.
Referenced by elementaryElimination().
|
staticprotected |
This method makes the elementary elimination on a multiply node.
This method makes the elementary elimination on a multiply node. The following eliminations are made: a) NaN * x -> NaN b) 0 * x -> 0 c) 1 * x -> x
The caller is responsible for freeing the memory of the returned object.
Definition at line 1060 of file CNormalTranslation.cpp.
References CEvaluationNodeConstant::_NaN, CEvaluationNode::CONSTANT, CEvaluationNode::copyBranch(), CEvaluationNodeNumber::DOUBLE, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::NUMBER, CEvaluationNode::OPERATOR, pResult, CEvaluationNode::subType(), CEvaluationNode::type(), and ZERO.
Referenced by elementaryElimination().
|
staticprotected |
This method makes the elementary elimination on a plus node.
This method makes the elementary elimination on a plus node. The following eliminations are made: a) NaN + x -> NaN b) 0 + x -> x (also x + 0)
The caller is responsible for freeing the memory for the returned object.
Definition at line 1176 of file CNormalTranslation.cpp.
References CEvaluationNodeConstant::_NaN, CEvaluationNode::CONSTANT, CEvaluationNode::copyBranch(), CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNode::NUMBER, CEvaluationNode::OPERATOR, CEvaluationNodeOperator::PLUS, pResult, CEvaluationNode::subType(), CEvaluationNode::type(), and ZERO.
Referenced by elementaryElimination().
|
staticprotected |
This method makes the elementary elimination on a power node.
This method makes the elementary elimination on a power node. This method makes the following elimination a) x^NaN -> NaN b) 0^0 -> NaN c) 0^(-x) -> NaN d) 0^x -> 0 e) 1^x -> 1 f) NaN^x -> NaN g) NFINITY^(-NaN) -> NaN i) INFINITY^-x -> 0.0 // x being a positive number j) INFINITY^x -> INFINITY // x being a positive number k) INFINITY^0 -> 1 l) INFINITY^0 -> 1.0 m) INFINITY^(-x) -> 0.0 n) INFINITY^x -> INFINITY o) INFINITY ^ x -> INFINITY p) x^0 -> 1 q) x^1 -> x
The caller is responsible for releasing the memory for the returned object.
Definition at line 787 of file CNormalTranslation.cpp.
References CEvaluationNodeConstant::_INFINITY, CEvaluationNodeConstant::_NaN, CEvaluationNode::CONSTANT, CEvaluationNode::copyBranch(), CEvaluationNodeNumber::DOUBLE, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNode::getValue(), CEvaluationNode::NUMBER, CEvaluationNode::OPERATOR, CEvaluationNodeOperator::POWER, pResult, CEvaluationNode::subType(), CEvaluationNode::type(), and ZERO.
Referenced by elementaryElimination().
|
staticprotected |
This method elminates subexpressions from an expression
This method elminates subexpressions from an expression It calls: elementaryElimination eliminateNestedPowers eliminatePowersOfFractions eliminateDirectlyNestedFunctions cancel
These functions are called as long as the resulting tree contains changes
Definition at line 402 of file CNormalTranslation.cpp.
References CEvaluationNode::buildInfix(), CEvaluationNode::copyBranch(), elementaryElimination(), eliminateDirectlyNestedFractions(), eliminateNestedPowers(), eliminatePowersOfFractions(), newCancel(), and pResult.
Referenced by simplify().
|
staticprotected |
This method eliminates directly nested fractions. ((a/b)/(c/d)) -> (a*d)/(b*c)
This method does all the canceling on a given node and its children. If no canceling was done, NULL is returned.
Obsolete recursive version This method does all the canceling on a given node and its children. CEvaluationNode* CNormalTranslation::cancel(const CEvaluationNode* pOrig) { TODO I think this method has much potential for improvement TODO since the comparison code seems to spend about 85% of the time TODO here, this is where I should start making optimizations
try to find multiplication chains where something is divided by itself or multiplied by -1 times itself also consider powers (it's the bases that have to match)
try to find addition changes where there is a subtraction of two identical nodes or an addition of one node and the same node times -1 CEvaluationNode* pResult = NULL; std::vector<CEvaluationNode*> children; std::cout << "Canceling: " << pOrig->buildInfix() << std::endl;
if (CEvaluationNode::type(pOrig->getType()) == CEvaluationNode::OPERATOR) { if (((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOrig->getType())) == CEvaluationNodeOperator::PLUS || ((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOrig->getType())) == CEvaluationNodeOperator::MINUS) {
we are in a sum std::vector<CEvaluationNode*> additions, subtractions; CNormalTranslation::splitSum(pOrig, additions, subtractions, false); CNormalTranslation::swapNegativeNumbers(additions, subtractions); collect all nodes in additions and subtractions unsigned int i, iMax = additions.size();
for (i = 0; i < iMax; ++i) { CEvaluationNode* pChild = CNormalTranslation::cancel(additions[i]); delete additions[i]; additions[i] = pChild; }
iMax = subtractions.size();
for (i = 0; i < iMax; ++i) { CEvaluationNode* pChild = CNormalTranslation::cancel(subtractions[i]); delete subtractions[i]; subtractions[i] = pChild; }
find identical nodes in additions and subtractions The first entry in the pair is the collected factor the second entry is the original branch make sure the collected factor is again simplified std::vector<std::pair<CEvaluationNode*, CEvaluationNode*> > collected = CNormalTranslation::matchSummands(additions, subtractions); iMax = additions.size();
for (i = 0; i < iMax; ++i) { delete additions[i]; }
additions.clear(); iMax = subtractions.size();
for (i = 0; i < iMax; ++i) { delete subtractions[i]; }
subtractions.clear(); std::vector<CEvaluationNode*> chain; iMax = collected.size();
for (i = 0; i < iMax; ++i) { std::pair<CEvaluationNode*, CEvaluationNode*> pair = collected[i];
CEvaluationNode* pTmpNode = CNormalTranslation::eliminate(pair.first); delete pair.first; if simplified node is 0.0, we ignore this node if (CEvaluationNode::type(pair.first->getType()) == CEvaluationNode::NUMBER && fabs(dynamic_cast<CEvaluationNodeNumber*>(pair.first)->getValue()) < ZERO) { delete pair.first; delete pair.second; } else if (CEvaluationNode::type(pair.first->getType()) == CEvaluationNode::NUMBER && fabs(dynamic_cast<CEvaluationNodeNumber*>(pair.first)->getValue() - 1.0) < ZERO) { delete pair.first; chain.push_back(pair.second); } else { CEvaluationNode* pMult = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*"); pMult->addChild(pair.first); pMult->addChild(pair.second); chain.push_back(pMult); } }
pResult = CNormalTranslation::createChain(&CNormalTranslation::PLUS_NODE, &CNormalTranslation::ZERO_NODE, chain); assert(pResult != NULL); } else if (((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOrig->getType())) == CEvaluationNodeOperator::MULTIPLY || ((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pOrig->getType())) == CEvaluationNodeOperator::DIVIDE) { we are in a product std::vector<const CEvaluationNode*> multiplications, divisions; CNormalTranslation::splitProduct(pOrig, multiplications, divisions, false); collect all nodes in multiplications and divisions unsigned int i, iMax = multiplications.size();
for (i = 0; i < iMax; ++i) { multiplications[i] = CNormalTranslation::cancel(multiplications[i]); }
iMax = divisions.size();
for (i = 0; i < iMax; ++i) { divisions[i] = CNormalTranslation::cancel(divisions[i]); }
find identical nodes in multiplications and divisions The first entry in the pair is the collected power exponent the second entry is the original power base make sure the collected factor is again simplified std::vector<std::pair<CEvaluationNode*, CEvaluationNode*> > collected = CNormalTranslation::matchPowerBases(multiplications, divisions); iMax = multiplications.size();
for (i = 0; i < iMax; ++i) { delete multiplications[i]; }
multiplications.clear(); iMax = divisions.size();
for (i = 0; i < iMax; ++i) { delete divisions[i]; }
divisions.clear(); std::vector<CEvaluationNode*> numeratorChain; std::vector<CEvaluationNode*> denominatorChain; iMax = collected.size();
for (i = 0; i < iMax; ++i) { std::pair<CEvaluationNode*, CEvaluationNode*> pair = collected[i];
CEvaluationNode* pTmpNode = CNormalTranslation::eliminate(pair.first); delete pair.first; if simplified node is a 0.0, we ignore this node if (CEvaluationNode::type(pair.first->getType()) == CEvaluationNode::NUMBER) { if (fabs(dynamic_cast<CEvaluationNodeNumber*>(pair.first)->getValue()) < ZERO) { delete pair.first; delete pair.second; } else if (dynamic_cast<CEvaluationNodeNumber*>(pair.first)->getValue() > 0.0) { if (fabs(dynamic_cast<CEvaluationNodeNumber*>(pair.first)->getValue() - 1.0) < ZERO) { delete pair.first; numeratorChain.push_back(pair.second); } else { CEvaluationNode* pPower = new CEvaluationNodeOperator(CEvaluationNodeOperator::POWER, "^"); pPower->addChild(pair.second); pPower->addChild(pair.first); numeratorChain.push_back(pPower); } } else { if (fabs(dynamic_cast<CEvaluationNodeNumber*>(pair.first)->getValue() + 1.0) < ZERO) { delete pair.first; denominatorChain.push_back(pair.second); } else { CEvaluationNode* pPower = new CEvaluationNodeOperator(CEvaluationNodeOperator::POWER, "^"); pPower->addChild(pair.second); std::ostringstream os; os.precision(18); os << fabs(dynamic_cast<const CEvaluationNodeNumber*>(pair.first)->getValue()); pPower->addChild(new CEvaluationNodeNumber((CEvaluationNodeNumber::SubType)CEvaluationNode::subType(pair.first->getType()), os.str().c_str())); delete pair.first; denominatorChain.push_back(pPower); } } } else { CEvaluationNode* pPower = new CEvaluationNodeOperator(CEvaluationNodeOperator::POWER, "^");
check if the node is -1.0 * SOMETHING if (CEvaluationNode::type(pair.first->getType()) == CEvaluationNode::OPERATOR && (CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pair.first->getType()) == CEvaluationNodeOperator::MULTIPLY && CEvaluationNode::type(dynamic_cast<const CEvaluationNode*>(pair.first->getChild())->getType()) == CEvaluationNode::NUMBER) { if (fabs(static_cast<const CEvaluationNodeNumber*>(pair.first->getChild())->getValue() + 1.0) < ZERO) { pPower->addChild(pair.second); pPower->addChild(dynamic_cast<const CEvaluationNode*>(pair.first->getChild()->getSibling())->copyBranch()); delete pair.first; denominatorChain.push_back(pPower); } else if (fabs(static_cast<const CEvaluationNodeNumber*>(pair.first->getChild())->getValue()) < ZERO) { delete the power node and add delete pPower; delete pair.first; numeratorChain.push_back(pair.second); } else if (static_cast<const CEvaluationNodeNumber*>(pair.first->getChild())->getValue() < 0.0) { pPower->addChild(pair.second); pPower->addChild(pair.first); denominatorChain.push_back(pPower); } else { pPower->addChild(pair.second); pPower->addChild(pair.first); numeratorChain.push_back(pPower); } } else { pPower->addChild(pair.second); pPower->addChild(pair.first); numeratorChain.push_back(pPower); } } }
if there are only divisions, we have an empty numerator chain if (numeratorChain.empty()) { pResult = CNormalTranslation::ONE_NODE.copyBranch(); } else { pResult = CNormalTranslation::createChain(&CNormalTranslation::TIMES_NODE, &CNormalTranslation::ONE_NODE, numeratorChain); assert(pResult != NULL); }
if (!denominatorChain.empty()) { CEvaluationNode* pTmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::DIVIDE, "/"); pTmpNode->addChild(pResult); pResult = pTmpNode; pTmpNode = CNormalTranslation::createChain(&CNormalTranslation::TIMES_NODE, &CNormalTranslation::ONE_NODE, denominatorChain); assert(pTmpNode != NULL); pResult->addChild(pTmpNode); } } else { const CEvaluationNode* pChild = dynamic_cast<const CEvaluationNode*>(pOrig->getChild());
while (pChild != NULL) { children.push_back(CNormalTranslation::cancel(pChild)); pChild = dynamic_cast<const CEvaluationNode*>(pChild->getSibling()); }
assert(children.size() == 2); } } else { const CEvaluationNode* pChild = dynamic_cast<const CEvaluationNode*>(pOrig->getChild());
while (pChild != NULL) { children.push_back(CNormalTranslation::cancel(pChild)); pChild = dynamic_cast<const CEvaluationNode*>(pChild->getSibling()); } }
if (pResult == NULL) { pResult = pOrig->copyNode(children); }
if(pOrig->buildInfix() == pResult->buildInfix()) { std::cout << "Nothing Canceled." << std::endl; } else { std::cout << "Canceled: " << pResult->buildInfix() << std::endl; } return pResult; } This method eliminates directly nested fractions. A/B/C -> A/(B*C)
The caller is responsible for deleting the returned object.
Definition at line 5121 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), CEvaluationNode::copyBranch(), CEvaluationNode::copyNode(), CEvaluationNodeOperator::DIVIDE, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::OPERATOR, pResult, CCopasiNode< _Data >::removeChild(), CEvaluationNode::subType(), and CEvaluationNode::type().
Referenced by eliminate().
|
staticprotected |
This method removes nested power nodes, e.g. (a^b)^c -> a^(b*c)
This method removes nested power nodes, e.g. (a^b)^c -> a^(b*c)
The caller is responsible for freeing the memory of the returned object.
Definition at line 2286 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), CEvaluationNode::copyBranch(), CEvaluationNode::copyNode(), CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::OPERATOR, CEvaluationNodeOperator::POWER, pResult, CCopasiNode< _Data >::removeChild(), CEvaluationNode::subType(), and CEvaluationNode::type().
Referenced by eliminate().
|
staticprotected |
This method gets rid of fractions within a power construct. (a/b)^3 -> a^3 / b^3
This method replaces a power of a fraction by the fraction of two power nodes. (A/B)^x -> A^x / B^x
The caller is responsible for deleting the returned object.
Definition at line 5263 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), CEvaluationNode::copyBranch(), CEvaluationNode::copyNode(), CEvaluationNodeOperator::DIVIDE, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNode::OPERATOR, CEvaluationNodeOperator::POWER, pResult, CCopasiNode< _Data >::removeChild(), CEvaluationNode::subType(), and CEvaluationNode::type().
Referenced by eliminate().
|
static |
Given a root node, this method traverses the tree and expands products in power bases to multiplications of power items. It is the responsibility of the caller to delete the returned node.
Given a root node, this method traverses the tree and expands produtcs in power bases to multiplications of power items.
(A*B)^x -> A^x * B^x
It is the responsibility of the caller to delete the returned node if it is not NULL.
Definition at line 5444 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), CEvaluationNode::copyBranch(), CEvaluationNode::copyNode(), createChain(), CEvaluationNodeOperator::DIVIDE, factorize(), CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNodeOperator::MINUS, CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::OPERATOR, CEvaluationNodeOperator::PLUS, CEvaluationNodeOperator::POWER, pResult, CCopasiNode< _Data >::removeChild(), splitProduct(), splitSum(), CEvaluationNode::subType(), swapNegativeNumbers(), and CEvaluationNode::type().
Referenced by simplify().
|
static |
Given a root node, this method traverses the tree and expands sums in power exponents to multiplications of power items. It is the responsibility of the caller to delete the returned node.
Takes a node and expands expressions like x^(n+m) to x^n * x^m If some of the exponent summands are negative numbers, the expression is divided by the positive exponent expression (x^(n-5) -> x^n / x^5
Definition at line 197 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), CEvaluationNode::create(), createChain(), CEvaluationNodeOperator::DIVIDE, CEvaluationNodeNumber::DOUBLE, findSummands(), CEvaluationNode::FUNCTION, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getData(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNodeFunction::MINUS, CEvaluationNode::NUMBER, CEvaluationNode::OPERATOR, CEvaluationNodeOperator::POWER, pResult, CEvaluationNode::subType(), and CEvaluationNode::type().
Referenced by normAndSimplify().
|
staticprotected |
This method expands the exponents of power nodes, e.g. A^(x+y) -> A^x * A^y
This method expands the exponents of power nodes, e.g. A^(x+y) -> A^x * A^y
The caller is responsible for freeing the memory of the returned object if it is not NULL.
Definition at line 2766 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), CEvaluationNode::copyBranch(), CEvaluationNode::copyNode(), createChain(), CEvaluationNodeOperator::DIVIDE, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNode::NUMBER, CEvaluationNode::OPERATOR, CEvaluationNodeOperator::POWER, pResult, splitSum(), CEvaluationNode::subType(), swapNegativeNumbers(), and CEvaluationNode::type().
Referenced by simplify().
|
static |
This method expands products. (A+B)*(C+D) -> (A*C)+(A*D)+(B*C)+(B*D) This method should be replaced by the one below pretty soon.
This method expands products. (A+B)*(C+D) -> (A*C)+(A*D)+(B*C)+(B*D)
Definition at line 3835 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), CEvaluationNode::copyNode(), CEvaluationNodeOperator::DIVIDE, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNodeOperator::MULTIPLY, multiply(), CEvaluationNode::OPERATOR, pResult, splitProduct(), CEvaluationNode::subType(), and CEvaluationNode::type().
Referenced by createNormalRepresentation(), and simplify().
|
staticprotected |
This method takes two vectors. One with a list of nodes that are added and one with nodes that are subtracted. It tries to find common factors and divisors in those nodes and returns two result nodes. The first is the multiplication of all common factors and divisors, the other is the sum of the remaining additions and subtractions after removing the common factors and divisors. e.g. (A*B*D+A*C*D) -> returns (A*D) and (B+C)
This method takes two vectors and checks if the elements in the two vectors can be split into multiplications and divisions and if there a common factors in all resulting subgroups.
Definition at line 5632 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), createChain(), createOperatorChain(), CEvaluationNodeOperator::DIVIDE, CEvaluationNode::getType(), CEvaluationNodeOperator::MINUS, CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::OPERATOR, splitProduct(), CEvaluationNode::subType(), and CEvaluationNode::type().
Referenced by expandPowerBases().
|
staticprotected |
This routine finds all negative numbers in vector v1 and adds a copy with a positive number to v2
Definition at line 6216 of file CNormalTranslation.cpp.
References CEvaluationNode::copyBranch(), CEvaluationNode::copyNode(), CEvaluationNodeNumber::DOUBLE, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNode::getValue(), CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::NUMBER, CEvaluationNode::OPERATOR, CEvaluationNode::subType(), and CEvaluationNode::type().
Referenced by newCancel().
|
static |
Given a node, the method check if the node is a PLUS node, if so, it calls itself recursively on the children. This way all summands of a summation chain are gathered. All items in the vector are children of pRoot.
This method takes a node and if the node is the node is an addition operator, the method goes through the children of the node and check for more addition operators. All children of addition operators are added to the given summands vector. If the given node is not an addition operator, the methods adds the node itself to the vector of summands. The nodes that are added to the vector are the original nodes and not copies.
Definition at line 347 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNode::OPERATOR, CEvaluationNodeOperator::PLUS, CEvaluationNode::subType(), and CEvaluationNode::type().
Referenced by expandPowerExponents().
|
static |
Definition at line 6407 of file CNormalTranslation.cpp.
References CEvaluationNodeDepthFirstIterator::isValid().
|
staticprotected |
The methods get a vector of multiplication elements and a vector of division elements and tries to find elements with the same power base in those two vectors.
The methods get a vector of multiplication elements and a vector of division elements and tries to find elements with the same power base in those two vectors. e.g. A^3 and A^x would have the same power base A.
The nodes in the match are copies of the original nodes
Definition at line 2923 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), summ_match::addition_indices, CEvaluationNode::buildInfix(), CEvaluationNode::copyBranch(), createNormalRepresentation(), CEvaluationNodeNumber::DOUBLE, summ_match::factor, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNode::getValue(), CEvaluationNodeOperator::MINUS, CEvaluationNodeOperator::MULTIPLY, newEvaluateNumbers(), CEvaluationNode::NUMBER, CEvaluationNode::OPERATOR, product_match::pExponentNode, CEvaluationNodeOperator::PLUS, summ_match::pNode, CEvaluationNodeOperator::POWER, summ_match::subtraction_indices, CEvaluationNode::subType(), CNormalFraction::toString(), and CEvaluationNode::type().
Referenced by newCancel().
|
staticprotected |
The methods get a vector of addition elements and a vector of subtractions elements and tries to find equal elements in those two vectors.
The methods get a vector of multiplication elements and a vector of division elements and tries to find elements with the same power base in those two vectors.
std::vector<std::pair<CEvaluationNode*, CEvaluationNode*> > CNormalTranslation::matchPowerBases(const std::vector<const CEvaluationNode*>& multiplications, const std::vector<const CEvaluationNode*>& divisions) { std::vector<std::pair<std::pair<const CEvaluationNode*, std::string>, std::vector<CEvaluationNode*> > > matchMap; std::vector<const CEvaluationNode*>::const_iterator vit = multiplications.begin(), vendit = multiplications.end();
while (vit != vendit) { const CEvaluationNode* pBase = (vit); CEvaluationNode pExponent = NULL;
if (CEvaluationNode::type(pBase->getType()) == CEvaluationNode::OPERATOR && ((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pBase->getType())) == CEvaluationNodeOperator::POWER) { pBase = dynamic_cast<const CEvaluationNode*>(pBase->getChild()); pExponent = dynamic_cast<const CEvaluationNode*>(pBase->getSibling())->copyBranch(); } else { pExponent = new CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, "1.0"); }
check if a base with the same infix is already in the map. if not, add the base if yes, add the exponent to the vector associated with the base std::vector<std::pair<std::pair<const CEvaluationNode*, std::string>, std::vector<CEvaluationNode*> > >::iterator mapIt = matchMap.begin(), mapEndit = matchMap.end(); CNormalFraction* pBase2 = createNormalRepresentation(pBase); std::string base2String = pBase2->toString(); delete pBase2;
while (mapIt != mapEndit) { if (mapIt->first.second == base2String) { mapIt->second.push_back(pExponent); break; }
++mapIt; }
if (mapIt == mapEndit) { std::vector<CEvaluationNode*> v; v.push_back(pExponent); matchMap.push_back(std::make_pair(std::pair<const CEvaluationNode*, std::string>(pBase, base2String), v)); }
++vit; }
std::vector<std::pair<std::pair<const CEvaluationNode*, std::string>, std::vector<CEvaluationNode*> > > matchMap2; vit = divisions.begin(), vendit = divisions.end();
while (vit != vendit) { const CEvaluationNode* pBase = (vit); CEvaluationNode pExponent = NULL;
if (CEvaluationNode::type(pBase->getType()) == CEvaluationNode::OPERATOR && ((CEvaluationNodeOperator::SubType)CEvaluationNode::subType(pBase->getType())) == CEvaluationNodeOperator::POWER) { pBase = dynamic_cast<const CEvaluationNode*>(pBase->getChild()); pExponent = dynamic_cast<const CEvaluationNode*>(pBase->getSibling())->copyBranch(); } else { pExponent = new CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, "1.0"); }
check if a base with the same infix is already in the map. if not, add the base if yes, add the exponent to the vector associated with the base std::vector<std::pair<std::pair<const CEvaluationNode*, std::string>, std::vector<CEvaluationNode*> > >::iterator mapIt = matchMap2.begin(), mapEndit = matchMap2.end(); CNormalFraction* pBase2 = createNormalRepresentation(pBase); std::string base2String = pBase2->toString(); delete pBase2;
while (mapIt != mapEndit) { if (mapIt->first.second == base2String) { mapIt->second.push_back(pExponent); break; }
++mapIt; }
if (mapIt == mapEndit) { std::vector<CEvaluationNode*> v; v.push_back(pExponent); matchMap2.push_back(std::make_pair(std::pair<const CEvaluationNode*, std::string>(pBase, base2String), v)); }
++vit; }
now combine the two maps std::vector<std::pair<CEvaluationNode*, std::pair<CEvaluationNode*, std::string> > > result; std::vector<std::pair<std::pair<const CEvaluationNode*, std::string>, std::vector<CEvaluationNode*> > >::iterator mapIt = matchMap.begin(), mapEndit = matchMap.end();
while (mapIt != mapEndit) { CEvaluationNode* pNode = CNormalTranslation::createChain(&CNormalTranslation::PLUS_NODE, &CNormalTranslation::ZERO_NODE, mapIt->second); assert(pNode != NULL); result.push_back(std::make_pair(pNode, std::pair<CEvaluationNode*, std::string>(mapIt->first.first->copyBranch(), mapIt->first.second))); ++mapIt; }
mapIt = matchMap2.begin(), mapEndit = matchMap2.end();
while (mapIt != mapEndit) { std::vector<CEvaluationNode*> constVect; constVect.insert(constVect.begin(), mapIt->second.begin(), mapIt->second.end()); CEvaluationNode* pNode = CNormalTranslation::createOperatorChain(CEvaluationNodeOperator::PLUS, "+", constVect); now check if we already have a base with the same infix in the results unsigned int i, iMax = result.size();
for (i = 0; i < iMax; ++i) { if (result[i].second.second == mapIt->first.second) { CEvaluationNode* pTmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MINUS, "-"); pTmpNode->addChild(result[i].first); pTmpNode->addChild(pNode); result[i] = std::make_pair(pTmpNode, result[i].second); break; } }
if (i == iMax) { if (CEvaluationNode::type(pNode->getType()) == CEvaluationNode::NUMBER) { std::ostringstream os; os.precision(18); os << static_cast<CEvaluationNodeNumber*>(pNode)->getValue() * -1.0; CEvaluationNode* pTmpNumber = new CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, os.str().c_str()); delete pNode; result.push_back(std::make_pair(pTmpNumber, std::pair<CEvaluationNode*, std::string>(mapIt->first.first->copyBranch(), mapIt->first.second))); } else { CEvaluationNode* pTmpNode = new CEvaluationNodeOperator(CEvaluationNodeOperator::MULTIPLY, "*"); pTmpNode->addChild(new CEvaluationNodeNumber(CEvaluationNodeNumber::DOUBLE, "-1.0")); pTmpNode->addChild(pNode); result.push_back(std::make_pair(pTmpNode, std::pair<CEvaluationNode*, std::string>(mapIt->first.first->copyBranch(), mapIt->first.second))); } }
delete the obsolete nodes iMax = mapIt->second.size();
for (i = 0; i < iMax; ++i) { delete mapIt->second[i]; }
++mapIt; }
copy the result vector into the return data structure std::vector<std::pair<CEvaluationNode*, CEvaluationNode*> > tmp; unsigned int i, iMax = result.size(); since we know how many elements will end up in tmp, we can already reserve the space tmp.reserve(iMax);
for (i = 0; i < iMax; ++i) { tmp.push_back(std::pair<CEvaluationNode*, CEvaluationNode*>(result[i].first, result[i].second.first)); }
return tmp; } The methods get a vector of addition elements and a vector of subtractions elements and tries to find equal elements in those two vectors.
Definition at line 3587 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), CEvaluationNode::buildInfix(), CEvaluationNode::copyBranch(), createChain(), createNormalRepresentation(), createOperatorChain(), CEvaluationNodeNumber::DOUBLE, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNodeOperator::MINUS, CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::NUMBER, CEvaluationNode::OPERATOR, CEvaluationNodeOperator::PLUS, CEvaluationNode::subType(), CNormalFraction::toString(), and CEvaluationNode::type().
Referenced by newCancel().
|
staticprotected |
The methods get a vector of addition elements and a vector of subtractions elements and tries to find equal elements in those two vectors.
Definition at line 3210 of file CNormalTranslation.cpp.
References summ_match::addition_indices, CEvaluationNode::buildInfix(), CEvaluationNode::copyBranch(), createNormalRepresentation(), summ_match::factor, CCopasiNode< _Data >::getChild(), CEvaluationNode::getType(), CEvaluationNode::getValue(), CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::NUMBER, CEvaluationNode::OPERATOR, summ_match::pNode, summ_match::subtraction_indices, CEvaluationNode::subType(), CNormalFraction::toString(), and CEvaluationNode::type().
|
staticprotected |
Multiplies the two given nodes and returns the result.
Definition at line 3928 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), createChain(), CEvaluationNodeNumber::DOUBLE, CEvaluationNodeOperator::MINUS, CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::NUMBER, pResult, splitSum(), and CEvaluationNode::type().
Referenced by expandProducts().
|
staticprotected |
This method does all the canceling on a given node and its children. New non-recursive cancel method. This method does all the canceling on a given node and its children. If no canceling was done, NULL is returned.
New non-recursive cancel method. This method does all the canceling on a given node and its children. If no canceling was done, NULL is returned.
Definition at line 4050 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), CEvaluationNode::copyBranch(), createChain(), CEvaluationNodeOperator::DIVIDE, CEvaluationNodeNumber::DOUBLE, summ_match::factor, findNegativeNumbers(), CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getParent(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNodeDepthFirstIterator::isValid(), matchPowerBases(), matchSummands(), CEvaluationNodeOperator::MINUS, CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::OPERATOR, product_match::pExponentNode, CEvaluationNodeOperator::PLUS, summ_match::pNode, CEvaluationNodeOperator::POWER, pResult, splitProduct(), splitSum(), CEvaluationNode::subType(), CEvaluationNode::type(), and ZERO.
Referenced by eliminate(), and simplify().
|
static |
This method evaluates operators acting on two numbers This method evaluates operators acting on two numbers
This method replaces operations on two (or more) number nodes by the resulting number node. The returned node is either NULL, or a new node. If the returned node is not NULL, the caller is responsible for freeing the memory of the object.
Obsolete recursive version This method replaces operations on two (or more) number nodes by the resulting number node. The returned node is either NULL, or a new node. If the returned node is not NULL, the caller is responsible for freeing the memory of the object.
Definition at line 1755 of file CNormalTranslation.cpp.
References CCopasiNode< _Data >::addChild(), CEvaluationNode::copyBranch(), createChain(), CEvaluationNodeOperator::DIVIDE, CEvaluationNodeNumber::DOUBLE, CCopasiNode< _Data >::getChild(), CCopasiNode< _Data >::getParent(), CCopasiNode< _Data >::getSibling(), CEvaluationNode::getType(), CEvaluationNode::getValue(), CEvaluationNodeOperator::INVALID, CEvaluationNodeDepthFirstIterator::isValid(), CEvaluationNodeOperator::MINUS, CEvaluationNodeFunction::MINUS, CEvaluationNodeOperator::MODULUS, CEvaluationNodeOperator::MULTIPLY, CEvaluationNode::NUMBER, CEvaluationNode::OPERATOR, CEvaluationNodeOperator::PLUS, CEvaluationNodeOperator::POWER, pResult, splitProduct(), splitSum(), CEvaluationNode::subType(), swapNegativeNumbers(), CEvaluationNode::type(), and ZERO.
Referenced by createNormalRepresentation(), matchPowerBases(), and simplify().