-
Notifications
You must be signed in to change notification settings - Fork 5
/
fractals.py
102 lines (81 loc) · 3.69 KB
/
fractals.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/usr/bin/env python3
import argparse
import numpy as np
from numba import jit
import matplotlib.pyplot as plt
import time
DPI = 300
tolerance = 0.000001
@jit(nopython=True, parallel=True, nogil=True)
def quadratic(z, c):
return z**2 + c
@jit(nopython=True, parallel=True, nogil=True)
def burningShip(z, c):
return quadratic(np.abs(z.real) + 1j*np.abs(z.imag), c)
@jit(nopython=True, parallel=True, nogil=True)
def newton(z):
if z == 0:
return 0
return z - (z**3 - 1) / (3*z**2)
@jit(nopython=True, parallel=True, nogil=True)
def iterateFractal(algorithm, c, z0, iterationsNumber):
#Roots (solutions) of the Newton equation
roots = [1 + 0j, -.5 + 1j * np.sqrt(3)/2, -.5 - 1j * np.sqrt(3)/2]
z = 0
if algorithm == "julia" or algorithm == "newton":
z = z0
for n in range(iterationsNumber):
if algorithm != "newton" and z.real**2 + z.imag**2 > 4:
return n
if algorithm == "mandelbrot":
z = quadratic(z, z0)
elif algorithm == "julia":
z = quadratic(z, c)
elif algorithm == "burningShip":
z = burningShip(z, z0)
elif algorithm == "newton":
z = newton(z)
for i in range(3):
difference = z - roots[i]
if (np.abs(difference.real) < tolerance and np.abs(difference.imag) < tolerance):
return (i + 1)*20
else:
raise ValueError("Bad algorithm value")
return 0
@jit(nopython=True, parallel=True, nogil=True)
def buildFractal(algorithm, c, xmin,xmax,ymin,ymax,width,height,iterationsNumber):
r1 = np.linspace(xmin, xmax, width)
r2 = np.linspace(ymin, ymax, height)
n3 = np.empty((width,height))
for i in range(width):
for k in range(height):
n3[i,k] = iterateFractal(algorithm, c, r1[i] + 1j*r2[k], iterationsNumber)
return (r1,r2,n3)
def drawPlot(algorithm, colormap, c, xmin,xmax,ymin,ymax,width=10,height=10,iterationsNumber=256, filename = "fractal.png"):
img_width = DPI * width
img_height = DPI * height
x,y,z = buildFractal(algorithm, c, xmin,xmax,ymin,ymax,img_width,img_height,iterationsNumber)
fig, ax = plt.subplots(figsize=(width, height), dpi=DPI)
plt.xticks([])
plt.yticks([])
ax.imshow(z.T, cmap = colormap, origin='lower')
fig.savefig(filename)
fig.clear()
def parseArgs():
parser = argparse.ArgumentParser()
parser.add_argument('--algorithm', nargs='?', choices=['mandelbrot', 'burningShip', 'julia', 'newton'],
default='mandelbrot', help='Fractal algorithm')
parser.add_argument("--colormap", nargs='?', default='hot', help='Plot colormap')
parser.add_argument('--c', nargs='?', type=complex, default = -0.8j, help = 'Complex argument for Julia set')
parser.add_argument('--xmin',nargs='?', type=float, default = -1.5, help = 'Minimal value on x axis')
parser.add_argument('--xmax', nargs='?', type=float, default = 1.5, help = 'Maximum value on x axis')
parser.add_argument('--ymin', nargs='?', type=float, default = -1.5, help = 'Minimal value on y axis')
parser.add_argument('--ymax', nargs='?', type=float, default = 1.5, help = 'Maximum value on y axis')
parser.add_argument('--output', nargs='?', default = "fractal.png", help = 'Output filename')
return parser.parse_args()
def main():
args = parseArgs()
start_time = time.time()
drawPlot(args.algorithm, args.colormap, args.c, args.xmin, args.xmax, args.ymin, args.ymax, filename = args.output)
print("--- %.2f seconds ---" % (time.time() - start_time))
main()