Po-Shen Loh’s Quadratic Method
A quadratic equation is one that can be written as
Young math students are taught in an algebra course that they can compute the roots of a quadratic equation by using the quadratic formula, which is
In 2019, Po-Shen Loh, a professor of mathematics at Carnegie Mellon University, published a new method for computing the roots of a quadratic equation. Loh’s method can be expressed with these two formulas:
After reading his paper, I decided to implement both the traditional quadratic formula and Loh’s new method in Python and compare them. Of course, both methods give the same results. As you can see from the code below, Loh’s method is slightly simpler and requires fewer computations.
import math def main(): tests = [ (0, -3, 3), (1, -4, 4), (2, -6, 22.5), (2, -14, 24), (3, 0, -27), (0.5, 5, 12) ] for coeffs in tests: roots = quadratic(*coeffs) print(roots) verify_roots(*coeffs, *roots) roots = poshenloh(*coeffs) print(roots) verify_roots(*coeffs, *roots) def quadratic(a, b, c): """Compute and return the roots of a quadratic equation using the traditional quadratic formula. Parameters a, b, c: The coefficients of a quadratic equation in the form: y = ax**2 + bx + c Return: the roots of the quadratic equation in a tuple """ r1 = None r2 = None if a == 0: r1 = -c / b else: discr = b * b - 4 * a * c b = -b denom = 2 * a if discr > 0: sq = math.sqrt(discr) r1 = (b - sq) / denom r2 = (b + sq) / denom elif discr == 0: r1 = b / denom else: sq = math.sqrt(-discr) real = b / denom imag = sq / denom r1 = complex(real, -imag) r2 = complex(real, imag) return (r1, r2) def poshenloh(a, b, c): """Compute and return the roots of a quadratic equation using the method developed by Po-Shen Loh in 2019. Parameters a, b, c: The coefficients of a quadratic equation in the form: y = ax**2 + bx + c Return: the roots of the quadratic equation in a tuple """ r1 = None r2 = None if a == 0: r1 = -c / b else: avg = -b / (2 * a) discr = avg * avg - c / a if discr > 0: u = math.sqrt(discr) r1 = avg - u r2 = avg + u elif discr == 0: r1 = avg else: u = math.sqrt(-discr) r1 = complex(avg, -u) r2 = complex(avg, u) return (r1, r2) def verify_roots(a, b, c, r1, r2): verify_root(a, b, c, r1) verify_root(a, b, c, r2) def verify_root(a, b, c, x): """Verify that x is a root of y = ax**2 + bx + c. In other words, verify that ax**2 + bx + c is zero. """ if x: y = a * x**2 + b * x + c if abs(y) > 1e-9: print("Error: invalid root " + x) if __name__ == "__main__": main()
To see that Loh’s method requires fewer computations, first count the
number of arithmetic operators in the quadratic
method at
lines 36–42. Counting
the call to the math.sqrt
method at line 40 as one
operator, the traditional quadratic formula requires 11 computations.
Now count the number of arithmetic operators in the
poshenloh
method at lines
70–75. Counting in the
same way as we counted for the quadratic
method, Loh’s
method requires 9 computations, which is fewer than the 11 required by
the traditional quadratic formula.