Abakus::Number BinaryOperator::derivative() const { if(!leftNode() || !rightNode()) { qWarning() << "Can't evaluate binary operator!\n"; return Abakus::Number(0); } Abakus::Number f = leftNode()->value(); Abakus::Number fPrime = leftNode()->derivative(); Abakus::Number g = rightNode()->value(); Abakus::Number gPrime = rightNode()->derivative(); switch(type()) { case Addition: return fPrime + gPrime; case Subtraction: return fPrime - gPrime; case Multiplication: return f * gPrime + fPrime * g; case Division: return (g * fPrime - f * gPrime) / (g * g); case Exponentiation: return f.pow(g) * ((g / f) * fPrime + gPrime * f.ln()); default: qWarning() << "Impossible case encountered evaluating binary operator!\n"; return Abakus::Number(0); } }
QString BinaryOperator::infixString() const { QString op; switch(type()) { case Addition: op = "+"; break; case Subtraction: op = "-"; break; case Multiplication: op = "*"; break; case Division: op = "/"; break; case Exponentiation: op = "^"; break; default: op = "Error"; } QString left = QString(isSimpleNode(leftNode()) ? "%1" : "(%1)").arg(leftNode()->infixString()); QString right = QString(isSimpleNode(rightNode()) ? "%1" : "(%1)").arg(rightNode()->infixString()); return QString("%1 %2 %3").arg(left, op, right); }
int AvlTree::nextNode(int node) const { const int right = rightNode(node); if(right != NIL) { return first(right); } else { int parent = parentNode(node); while(parent != NIL && node == rightNode(parent)) { node = parent; parent = parentNode(parent); } return parent; } }
void AvlTree::rebalance(int node) { for(int n = node; n != NIL; ) { const int p = parentNode(n); updateAggregates(n); switch(balanceFactor(n)) { case -2: { const int right = rightNode(n); if(balanceFactor(right) == 1) { rotateRight(right); } rotateLeft(n); break; } case 2: { const int left = leftNode(n); if(balanceFactor(left) == -1) { rotateLeft(left); } rotateRight(n); break; } case -1: case 1: case 0: break; default: // We should throw an error assert(true == false); } n = p; } }
bool rightNode(TreeNode* right, int min){ if(!right) return true; if(right->val <= min) return false; if(!rightNode(right->right, right->val)) return false; if(!midNode(right->left, min, right->val)) return false; return true; }
int AvlTree::last(int node) const { while(true) { const int right = rightNode(node); if(right == NIL) { break; } node = right; } return node; }
long AvlTree::ceilSum(int node) const { const int left = leftNode(node); long sum = aggregatedCount(left); int n = node; for(int p = parentNode(node); p != NIL; p = parentNode(n)) { if(n == rightNode(p)) { const int leftP = leftNode(p); sum += count(p) + aggregatedCount(leftP); } n = p; } return sum; }
int AvlTree::find(double x) const { for(int node = _root; node != NIL;) { const int cmp = compare(node, x); if(cmp < 0) { node = leftNode(node); } else if(cmp > 0) { node = rightNode(node); } else { return node; } } return NIL; }
int AvlTree::floor(double x) const { int f = NIL; for(int node = _root; node != NIL; ) { const int cmp = compare(node, x); if(cmp <= 0) { node = leftNode(node); } else { f = node; node = rightNode(node); } } return f; }
Abakus::Number BinaryOperator::value() const { if(!leftNode() || !rightNode()) { qWarning() << "Can't evaluate binary operator!\n"; return Abakus::Number(0); } Abakus::Number lValue = leftNode()->value(); Abakus::Number rValue = rightNode()->value(); switch(type()) { case Addition: return lValue + rValue; case Subtraction: return lValue - rValue; case Multiplication: return lValue * rValue; case Division: return lValue / rValue; case Exponentiation: return lValue.pow(rValue); case LogicalShiftLeft: return lValue * Abakus::Number(2).pow(rValue); case LogicalShiftRight: return Abakus::Number(lValue / Abakus::Number(2).pow(rValue)).trunc(); default: qWarning() << "Impossible case encountered evaluating binary operator!\n"; return Abakus::Number(0); } }
void AvlTree::rotateRight(int node) { const int l = leftNode(node); const int rl = rightNode(l); _left[node] = rl; if(rl != NIL) { _parent[rl] = node; } const int p = parentNode(node); _parent[l] = p; if(p == NIL) { _root = l; } else if(rightNode(p) == node) { _right[p] = l; } else { assert(leftNode(p) == node); _left[p] = l; } _right[l] = node; _parent[node] = l; updateAggregates(node); updateAggregates(parentNode(node)); }
void AvlTree::rotateLeft(int node) { const int r = rightNode(node); const int lr = leftNode(r); _right[node] = lr; if(lr != NIL) { _parent[lr] = node; } const int p = parentNode(node); _parent[r] = p; if(p == NIL) { _root = r; } else if(leftNode(p) == node) { _left[p] = r; } else { assert(rightNode(p) == node); _right[p] = r; } _left[r] = node; _parent[node] = r; updateAggregates(node); updateAggregates(parentNode(node)); }
int AvlTree::floorSum(long sum) const { int f = NIL; for(int node = _root; node != NIL; ) { const int left = leftNode(node); const long leftCount = aggregatedCount(left); if(leftCount <= sum) { f = node; sum -= leftCount + count(node); node = rightNode(node); } else { node = leftNode(node); } } return f; }
void TripleMultiNetwork::onNodeStateChange(const node_id_t n) { TypedNetwork<NodeType, LinkType>::onNodeStateChange(n); NeighborLinkIteratorRange iters = neighborLinks(n); for (NeighborLinkIterator& it = iters.first; it != iters.second; ++it) { NeighborTripleIteratorRange niters = neighborTriples(*it); for (NeighborTripleIterator& nit = niters.first; nit != niters.second; ++nit) { tripleStore_->setCategory(*nit, (*tsCalc_)( nodeState(leftNode(*nit)), nodeState(centerNode(*nit)), nodeState(rightNode(*nit)))); } } }
bool AvlTree::add(double x, int w) { if(_root == NIL) { _root = ++_n; _values[_root] = x; _count[_root] = w; _left[_root] = NIL; _right[_root] = NIL; _parent[_root] = NIL; // Update depth and aggregates updateAggregates(_root); } else { int node = _root; int parent = NIL; int cmp; do { cmp = compare(node, x); if(cmp < 0) { parent = node; node = leftNode(node); } else if (cmp > 0) { parent = node; node = rightNode(node); } else { // we merge the node merge(node, x, w); return false; } } while(node != NIL); node = ++_n; _values[node] = x; _count[node] = w; _left[node] = NIL; _right[node] = NIL; _parent[node] = parent; if(cmp < 0) { _left[parent] = node; } else { assert(cmp > 0); _right[parent] = node; } rebalance(node); return true; } }
bool isValidBST(TreeNode* root) { if(!root) return true; return leftNode(root->left, root->val)&&rightNode(root->right, root->val); }
void BinaryOperator::applyMap(NodeFunctor &fn) const { fn(leftNode()); fn(rightNode()); fn(this); }