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.