defMandNumba(ext, max_steps, Nx, Ny): data = np.ones((Nx, Ny)) * max_steps for i inrange(Nx): for j inrange(Ny): x = ext[0] + (ext[1] - ext[0]) * i / (Nx - 1.) y = ext[2] + (ext[3] - ext[2]) * j / (Ny - 1.) z0 = x + y * 1j z = 0j for itr inrange(max_steps): ifabs(z) > 2.: data[j, i] = itr break z = z * z + z0 return data
@numba.njit(parallel=True) defMandNumba_parallel(ext, max_steps, Nx, Ny): data = np.ones((Ny, Nx), dtype=np.int32) * max_steps for i in numba.prange(Nx): # 并行外层循环 for j inrange(Ny): x = ext[0] + (ext[1] - ext[0]) * i / (Nx - 1) y = ext[2] + (ext[3] - ext[2]) * j / (Ny - 1) z0 = x + y * 1j z = 0j for itr inrange(max_steps): ifabs(z) > 2: data[j, i] = itr break z = z * z + z0 return data
import numpy as np
def compute_row(ext, max_steps, Nx, Ny, row):
result = np.empty(Ny, dtype=np.int64)
for j in range(Ny):
x = ext[0] + (ext[1] - ext[0]) * row / (Nx - 1.)
y = ext[2] + (ext[3] - ext[2]) * j / (Ny - 1.)
z0 = x + y * 1j
z = 0j
for itr in range(max_steps):
if abs(z) > 2.:
result[j] = itr
break
z = z * z + z0
else:
result[j] = max_steps
return result
1 2 3 4 5 6 7 8 9 10 11 12 13
import numpy as np import multiprocessing as mp from compute_one_row import compute_row import time
defMandelMultiProcess(ext, max_steps, Nx, Ny): data = np.ones((Nx, Ny), dtype=np.int64) * max_steps with mp.Pool(processes=mp.cpu_count()) as pool: results = [pool.apply_async(compute_row, (ext, max_steps, Nx, Ny, i)) for i inrange(Nx)] for i inrange(Nx): data[i, :] = results[i].get() return data
defMandNumba_vectorized(ext, max_steps, Nx, Ny): x = np.linspace(ext[0], ext[1], Nx) y = np.linspace(ext[2], ext[3], Ny) X, Y = np.meshgrid(x, y) Z0 = X + Y * 1j Z = np.zeros_like(Z0) data = np.full(Z0.shape, max_steps, dtype=int)
#%matplotlib notebook import numpy as np import pylab as plt import time import numba
@numba.njit(parallel=True) defMandNumba(ext, max_steps, Nx, Ny): data = np.ones((Nx, Ny), dtype=np.int32) * max_steps for i inrange(Nx): for j inrange(Ny): x = ext[0] + (ext[1] - ext[0]) * i / (Nx - 1.) y = ext[2] + (ext[3] - ext[2]) * j / (Ny - 1.) z0 = x + y * 1j z = 0j for itr inrange(max_steps): ifabs(z) > 2.: data[j, i] = itr break z = z * z + z0 return data
defax_update(ax): # actual plotting routine ax.set_autoscale_on(False) # Otherwise, infinite loop # Get the range for the new area xstart, ystart, xdelta, ydelta = ax.viewLim.bounds xend = xstart + xdelta yend = ystart + ydelta ext=np.array([xstart,xend,ystart,yend]) data = MandNumba(ext, max_steps, Nx, Ny) # actually producing new fractal
# Update the image object with our new data and extent im = ax.images[-1] # take the latest object im.set_data(data) # update it with new data im.set_extent(ext) # change the extent ax.figure.canvas.draw_idle() # finally redraw
if __name__ == '__main__': Nx = 1000 Ny = 1000 max_steps = 1000# 50