-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathaberthMethod.py
76 lines (58 loc) · 1.95 KB
/
aberthMethod.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
"""
aberthMethod module
###############################################################################
This module works with the Function class from function module.
It computes all the roots for a given polynomial.
"""
import math
import random
def getUpperLowerBounds(f):
"""
Give the roots' boundaries of a polynomial.
Parameters
----------
f: a Function objet that represent a polynomial.
"""
degree = f.degree
coef = f.coef
upper = 1 + 1 / abs(coef[-1]) * max(abs(coef[x]) for x in range(degree))
lower = abs(coef[0]) / (abs(coef[0]) + max(abs(coef[x]) for x in range(1, degree + 1)))
return upper, lower
def initRoots(f):
"""
Initialize the roots of a polynomial using the roots' boundaries.
Parameters
----------
f: a Function objet that represent a polynomial
"""
degree = f.degree
upper, lower = getUpperLowerBounds(f)
roots = []
for i in range(degree):
radius = random.uniform(lower, upper)
angle = random.uniform(0, math.pi*2)
root = complex(radius * math.cos(angle), radius * math.sin(angle))
roots.append(root)
return roots
def aberthMethod(f):
"""
Compute the roots of a given polynomial using the Aberth Method.
Parameters
----------
f: a Function objet that represent a polynomial.
"""
roots = initRoots(f)
iteration = 0
while True:
valid = 0
for k, r in enumerate(roots):
ratio = f.image(r) / f.derivative(r)
offset = ratio / (1 - (ratio * sum(1/(r - x)
for j, x in enumerate(roots) if j != k)))
if round(offset.real, 14) == 0 and round(offset.imag, 14) == 0:
valid += 1
roots[k] -= offset
if valid == len(roots):
break
iteration += 1
return iteration, [complex(round(r.real, 12), round(r.imag, 12)) for r in roots]