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
103
104
105
106
107
|
#!/usr/bin/env python3
import numpy as np
import matplotlib.pyplot as plt
import time
import multiprocessing as mp
from multiprocessing import RawArray
# c-mesh limits
limitre = ( -2, 1 )
limitim = ( -1.5, 1.5 )
def worker(gridchunk, s, step, T, l):
global rs
# Preallocate z array
rschunk = rs[s : s + step]
z = np.zeros(rschunk.shape)
print(f"rschunk.shape: {rschunk.shape}, gridchunk.shape: {gridchunk.shape}, T: {T}, l: {l}")
# Calculate ι for all complex numbers
for i in range(l):
# This will generate warnings for some of the values rising above T.
# Because these values are above T they are not used, thus the warnings
# can be ignored
z = z*z + gridchunk
# This will generate 1 in all the places
# where z < T and zeros elsewhere
below = (np.abs(z) < T)
# Add this to the result
# Because the ones that pass T are 0
# they will stop counting.
#
# If a specific z never reaches >= T its value in rs will
# be l
rschunk += below
np.divide(rschunk, l, out=rschunk)
def mangel(pre, pim, T, l, workers):
"""
Calculate the mangelbrot image with multiple processes
(pre, pim) discribes the image size. Use T and l to tune the mangelbrot
This will split the image in horizontal parts and distribute it
between the workers.
Because the result array is row major, data will be nicely together if
the workers work with rows not columns.
Pre must be devisible by workers.
The result is saved in rs. Sorry couln't get numpy references through to the process as arguments
:param pre: Number of real numbers used
:param pim: Number of imaginary numbers
:param T: Mangelbrot threshold
:param l: Iterations
:param workers: Number of workers.
"""
# Used to calculate c-mesh
re = np.linspace(limitre[0], limitre[1], pre)
im = np.linspace(limitim[0], limitim[1], pim)
# Calculate c-mesh
grid = np.add.outer(re, 1j * im)
# Calculate the partition variables
step = int(pre / workers)
# Loop chunks and start the workers
wl = []
for s in range(0, pre, step):
gridchunk = grid[s : s + step]
p = mp.Process(target=worker, args=(gridchunk, s, step, T, l))
wl.append(p)
p.start()
# Wait for them to be done
for p in wl:
p.join()
return rs
rs = np.full((500, 500), 0.5)
start = time.time()
arr = mangel(500, 500, 2, 100, 1)
end = time.time()
plt.imshow(arr, cmap=plt.cm.hot, vmin=0, vmax=1)
plt.savefig("mult.png")
print(f"Took {end - start} seconds")
"""
p = mp.Process(target=worker, args=(rs[s:s + step], grid[s:s + step], T, l))
wl.append(p)
p.start()
# Wait for them to be done
for p in wl:
p.join()
"""
|