-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcomplex_polynomial_roots_fractal.py
More file actions
72 lines (60 loc) · 2.01 KB
/
Copy pathcomplex_polynomial_roots_fractal.py
File metadata and controls
72 lines (60 loc) · 2.01 KB
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
import math
import random
import time
from PIL import Image
imgx, imgy = 512, 512
image = Image.new("RGB", (imgx, imgy))
xa, xb = -2.0, 2.0
ya, yb = -2.0, 2.0
nmax = 18
pmax = 20000
maxIt = 1000
eps = 1e-7
def polynomial(z, coefficients):
t = complex(0, 0)
for c in coefficients:
t = t * z + c
return t
def durand_kerner(coefficients):
n = len(coefficients) - 1
roots = [complex(random.random(), random.random()) for _ in range(n)]
roots_new = roots[:]
it = 0
while it < maxIt:
converged = True
for k in range(n):
denominator = complex(1, 0)
for j in range(n):
if j != k:
diff = roots[k] - roots[j]
if diff == 0:
diff = complex(1e-8, 1e-8) # Prevent division by zero
denominator *= diff
correction = polynomial(roots[k], coefficients) / denominator
roots_new[k] = roots[k] - correction
if abs(correction) > eps:
converged = False
roots = roots_new[:]
it += 1
if converged:
break
return roots, it
start_time = time.time()
for _ in range(pmax):
pd = random.randint(2, nmax)
coefficients = [complex(random.choice([-1, 1]), 0) for _ in range(pd)] + [complex(1, 0)]
roots, iterations = durand_kerner(coefficients)
for root in roots:
if math.isnan(root.real) or math.isnan(root.imag) or math.isinf(root.real) or math.isinf(root.imag):
continue # Skip bad roots
kx = int((imgx - 1) * (root.real - xa) / (xb - xa))
ky = int((imgy - 1) * (root.imag - ya) / (yb - ya))
if 0 <= kx < imgx and 0 <= ky < imgy:
color = (
(iterations % 8) * 32,
(iterations % 4) * 64,
(iterations % 16) * 16
)
image.putpixel((kx, ky), color)
image.save("ComplexPolynomialRootsFractal.png", "PNG")
print("Duration in seconds:", int(time.time() - start_time))