/* a * x^2 + b * x + c = 0 */ RootVector SolveEquation2Deg(float a, float b, float c, bool nonNegativeAnswer) { RootVector roots; float det = b * b - 4 * a * c, x1, x2; if (det < -EPSILON) // No real roots return roots; else if (det >= -EPSILON && det < EPSILON) roots.push_back(-b / (2.0f * a)); else { x1 = (-b - sqrt(det)) / (2.0f * a); x2 = (-b + sqrt(det)) / (2.0f * a); if (!nonNegativeAnswer || x1 >= EPSILON) { roots.push_back(x1); } if (!nonNegativeAnswer || x2 >= EPSILON) { roots.push_back(x2); } } return roots; }
/// Creates a merged list of Tries for unique stacks that disregards their /// thread IDs. RootVector mergeAcrossThreads(std::forward_list<StackTrieNode> &NodeStore) { RootVector MergedByThreadRoots; for (auto MapIter : Roots) { const auto &RootNodeVector = MapIter.second; for (auto *Node : RootNodeVector) { auto MaybeFoundIter = find_if(MergedByThreadRoots, [Node](StackTrieNode *elem) { return Node->FuncId == elem->FuncId; }); if (MaybeFoundIter == MergedByThreadRoots.end()) { MergedByThreadRoots.push_back(Node); } else { MergedByThreadRoots.push_back(mergeTrieNodes( **MaybeFoundIter, *Node, nullptr, NodeStore, mergeStackDuration)); MergedByThreadRoots.erase(MaybeFoundIter); } } } return MergedByThreadRoots; }
/// Prints top stacks from looking at all the leaves and ignoring thread IDs. /// Stacks that consist of the same function IDs but were called in different /// thread IDs are not considered unique in this printout. void printIgnoringThreads(raw_ostream &OS, FuncIdConversionHelper &FN) { RootVector RootValues; // Function to pull the values out of a map iterator. using RootsType = decltype(Roots.begin())::value_type; auto MapValueFn = [](const RootsType &Value) { return Value.second; }; for (const auto &RootNodeRange : make_range(map_iterator(Roots.begin(), MapValueFn), map_iterator(Roots.end(), MapValueFn))) { for (auto *RootNode : RootNodeRange) RootValues.push_back(RootNode); } print(OS, FN, RootValues); }
/* a * x^3 + b * x^2 + c * x + d = 0 */ RootVector SolveEquation3Deg(float a, float b, float c, float d, bool nonNegativeAnswer) { RootVector roots; double sub; double A, B, C; double sq_A, p, q; double cb_p, D; /* normal form: x^3 + Ax^2 + Bx + C = 0 */ A = b / a; B = c / a; C = d / a; /* substitute x = y - A/3 to eliminate quadric term: x^3 +px + q = 0 */ sq_A = A * A; p = 1.0/3 * (- 1.0/3 * sq_A + B); q = 1.0/2 * (2.0/27 * A * sq_A - 1.0/3 * A * B + C); /* use Cardano's formula */ cb_p = p * p * p; D = q * q + cb_p; if (D >= -EPSILON && D < EPSILON) { if (q >= -EPSILON && q < EPSILON) /* one triple solution */ { roots.push_back(0); } else /* one single and one double solution */ { double u = cbrt(-q); roots.push_back(2 * (float)u); roots.push_back(-(float)u); } } else if (D < -EPSILON) /* Casus irreducibilis: three real solutions */ { double phi = 1.0/3 * acos(-q / sqrt(-cb_p)); double t = 2 * sqrt(-p); roots.push_back((float)t * cosf((float)phi)); roots.push_back(-(float)t * cosf((float)phi + PI / 3)); roots.push_back(-(float)t * cosf((float)phi - PI / 3)); } else /* one real solution */ { double sqrt_D = sqrt(D); double u = cbrt(sqrt_D - q); double v = - cbrt(sqrt_D + q); roots.push_back((float)(u + v)); } /* resubstitute */ sub = 1.0 / 3 * A; for (unsigned i = 0; i < roots.size(); ++i) roots[i] -= (float)sub; return roots; }