Last active
October 10, 2025 13:29
-
-
Save vrbadev/ef8d561f692b431e858d82fdc7c094e2 to your computer and use it in GitHub Desktop.
Fast and simple quartic polynomial roots calculation implemented in plain C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| template<typename T=double> | |
| std::array<std::complex<T>, 4> solve_quartic_roots(std::complex<T> c4, std::complex<T> c3, std::complex<T> c2, std::complex<T> c1, std::complex<T> c0) const { | |
| c3 /= c4; c2 /= c4; c1 /= c4; c0 /= c4; | |
| const T eps = std::numeric_limits<T>::epsilon(); | |
| const T inv2 = 0.5, inv3 = 1.0/3.0, inv27 = 1.0/27.0; | |
| auto a4q = 0.25 * c3; | |
| auto a4q2 = a4q * a4q; | |
| auto a4q4 = a4q2 * a4q2; | |
| auto p = 3.0 * a4q2 - inv2 * c2; | |
| auto q = c3 * a4q2 - c2 * a4q + inv2 * c1; | |
| auto r = 3.0 * a4q4 - c2 * a4q2 + c1 * a4q - c0; | |
| auto o = p * r - inv2 * q * q; | |
| auto p_sq = p * p; | |
| auto p_cu = p_sq * p; | |
| auto p2 = (3.0 * r - p_sq) * inv3; | |
| auto q2 = (2.0 * p_cu - 9.0 * p * r + 27.0 * o) * inv27; | |
| auto q2h = -inv2 * q2; | |
| auto p2_third = p2 * inv3; | |
| auto d = std::sqrt(q2h * q2h + p2_third * p2_third * p2_third); | |
| auto w = q2h + d; | |
| auto w_mag = std::abs(w); | |
| auto w_ang = std::arg(w); | |
| auto u = std::polar(std::pow(w_mag, inv3), w_ang * inv3); | |
| if (std::abs(u) < eps) { | |
| auto w2 = q2h - d; | |
| u = std::polar(std::pow(std::abs(w2), inv3), std::arg(w2) * inv3); | |
| } | |
| auto v = -p2 / (3.0 * u); | |
| auto z0 = u + v - p * inv3; | |
| auto s = std::sqrt(2.0 * (p + z0)); | |
| auto t = (std::abs(s) < eps) ? (z0 * z0 + r) : (-q / s); | |
| auto sh = 0.5 * s; | |
| auto base = sh * sh - z0; | |
| auto d1 = std::sqrt(base - t); | |
| auto d2 = std::sqrt(base + t); | |
| return {-sh - d1 - a4q, -sh + d1 - a4q, sh - d2 - a4q, sh + d2 - a4q}; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment