I'm attempting to calculate all real X-values, at a certain Y-value, of a 20-degree polynomial provided in a coefficent list of ascending powers. I'm using Python 3.10 as well as the roots function of the NumPy library.
(I previously posted a simillar question here on StackOverflow, attempting to solve this issue by producing a much simpler example with a far smaller polynomial. However, while the solution to that posting did solve the issue for small polynomials, it did not solve the issue for when I use large polynomials.)
Here is my example code:
import numpy as np
import matplotlib.pyplot as plt
def main():
# Declare 20-degree polynomial
coeffs = np.array([0.028582380269090664, -11.07209382330515, 81.98886137780704, -231.55726577581814, 344.8963540923082, -312.0774305574022, 185.36300988588312, -75.58767327080196, 21.660357329823697, -4.380346453954649, 0.6125779086029393, -0.05524029639869697, 0.002489646479713822, 4.159253423505381e-05, -9.927184104751197e-06, 8.634292922740336e-08, 3.278890552085848e-08, -3.350925351280405e-10, -1.1510786631391544e-10, -2.3053456641329463e-13, 3.9927010006271344e-13, 8.499990550259627e-15, -1.2514130885401332e-15, -5.653183054629818e-17, 3.5580325101956145e-18, 2.634844330077943e-19, -1.2086461102288157e-20, -9.772155900613053e-22, 8.336597931160041e-23, -2.286862805703104e-24, 2.2638043801338818e-26], dtype = float)
y = -5
# Create polynomial data on interval (0, 17)
polyDataX = np.linspace(0, 17)
polyDataY = np.empty(shape = len(polyDataX), dtype = float)
for i in range(len(polyDataX)):
polyDataY[i] = 0
for j in range(len(coeffs)):
polyDataY[i] += coeffs[j] * pow(polyDataX[i], j)
# Solve for all real solutions
coeffs[-1] -= y
sols = np.roots(coeffs).tolist()
i = 0
while (i < len(sols)):
if (sols[i].imag != 0) or (sols[i].real < 0) or (sols[i].real > 17):
del sols[i]
i -= 1
else:
sols[i] = round(sols[i].real, 2)
i += 1
# Plot polynomial & solutions
plt.xlim([0, 17])
plt.ylim([-30, 30])
plt.plot(polyDataX, polyDataY, color = "gray")
plt.axhline(y, color = "blue")
for sol in sols:
plt.axvline(sol, color = "red")
plt.title("Sols: " + str(sols))
plt.show()
plt.close()
plt.clf()
if (__name__ == "__main__"):
main()
First I generate a 20-degree polynomial (stored in coeffs
), and use the roots
function in order to acquire all X-values (stored in sols
), at a certain Y-value (stored in y
). I subsequently filter out all the imaginary solutions, leaving only the real ones at the desired interval of [0, 17]
, and I plot the plolynomial, alongside the desired Y-value and found real X-values. I colored the polynomial in gray
, the desired Y-value in blue
and all the filtered X-values in red
.
In the above example, I attempt to acquire all real X-values at a the Y-value of -5
. The X-values are listed as [3.92, 1.34, 1.13]
, which is clearly incorrect according to the generated plot:
According to the plot, the actual X-values for a Y-value of -5
should be ~11.2
and ~16
.
What am I doing wrong here? Why are the listed solutions from the roots
function incorrect here?
Thanks for reading my post, any guidance is appreciated.