Here is a simple code for Newton equation solving meant to find complex roots.
The code meant to work like this:
Importing Libraries: The code imports the sympy library to handle symbolic mathematics.
Defining the Polynomial: It defines the polynomial equation p(x)=x5+11x4−21x3−10x2−21x−5 using the sympy library.
Newton's Method Function: The newton_method function implements Newton's method to find roots of a function within a given tolerance.
Finding Real Roots: It uses a loop to apply Newton's method with different initial guesses to find real roots of the polynomial equation.
Reducing Polynomial: The reduce_polynomial function divides the polynomial by (x−root) to reduce the degree of the polynomial.
Finding Complex Roots: It utilizes the obtained real roots to reduce the polynomial and find any complex roots by solving the reduced polynomials.
Output: Finally, it prints the real roots and complex roots found using the Newton's method and the reduction technique.
This code utilizes Newton's method to find real roots and subsequently reduces the polynomial to find any complex roots based on the obtained real roots. Adjusting the tolerance and initial guesses can affect the accuracy and convergence of the method for different polynomials.
import sympy as sp
# Define the variable
x = sp.symbols('x')
# Define the polynomial
p = x**5 + 11*x**4 - 21*x**3 - 10*x**2 - 21*x - 5
# Find the real roots using Newton's method
tolerance = 1e-5 # Tolerance for approximation
roots = []
# Function for Newton's method
def newton_method(f, x0, tol, max_iter=100):
x = x0
iteration = 0
while iteration < max_iter:
x_next = x - f.subs(x, x) / f.diff(x).subs(x, x)
if abs(x - x_next) < tol:
return x_next
x = x_next
iteration += 1
return None
# Find real roots
for i in range(5):
root = newton_method(p, i, tolerance)
if root is not None:
roots.append(root)
print("Real roots:", roots)
# Reduce the polynomial to a lower degree
# This reduces the polynomial by dividing it by (x - root)
def reduce_polynomial(poly, root):
return sp.simplify(poly / (x - root))
# Find complex roots
complex_roots = []
for root in roots:
reduced_poly = reduce_polynomial(p, root)
complex_root = sp.solve(reduced_poly, x)
complex_roots.extend(complex_root)
print("Complex roots:", complex_roots)
**However, I got this common error: **
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-beb367549ec5> in <cell line: 27>()
26 # Find real roots
27 for i in range(5):
---> 28 root = newton_method(p, i, tolerance)
29 if root is not None:
30 roots.append(root)
3 frames
<ipython-input-3-beb367549ec5> in newton_method(f, x0, tol, max_iter)
17 iteration = 0
18 while iteration < max_iter:
---> 19 x_next = x - f.subs(x, x) / f.diff(x).subs(x, x)
20 if abs(x - x_next) < tol:
21 return x_next
/usr/local/lib/python3.10/dist-packages/sympy/core/expr.py in diff(self, *symbols, **assumptions)
3584 def diff(self, *symbols, **assumptions):
3585 assumptions.setdefault("evaluate", True)
-> 3586 return _derivative_dispatch(self, *symbols, **assumptions)
3587
3588 ###########################################################################
/usr/local/lib/python3.10/dist-packages/sympy/core/function.py in _derivative_dispatch(expr, *variables, **kwargs)
1907 from sympy.tensor.array.array_derivatives import ArrayDerivative
1908 return ArrayDerivative(expr, *variables, **kwargs)
-> 1909 return Derivative(expr, *variables, **kwargs)
1910
1911
/usr/local/lib/python3.10/dist-packages/sympy/core/function.py in __new__(cls, expr, *variables, **kwargs)
1294 if isinstance(v, Integer):
1295 if i == 0:
-> 1296 raise ValueError("First variable cannot be a number: %i" % v)
1297 count = v
1298 prev, prevcount = variable_count[-1]
ValueError: First variable cannot be a number: 0```
I searched for value error in other post but problem unsolved.
x is a top level variable containig
sympy.symbol, but insidenewton_methodx is redeclared as local variable containing float valuex = x0, so it's not a symbol anymore, sof.subs(x, x)can not possibly work andf.diff(x).subs(x, x)cannot also.Here's correct version of this function (assuming everything else is correct):