How Can I Make This Fractal Render Faster In Zelle Graphics?
Solution 1:
The fastest way in likely with numpy. See "How To Quickly Compute The Mandelbrot Set In Python" for details on this approach.
For plain pure Python, use the native complex numbers to speed-up the loop. Also use the abs() function to quickly compute the magnitude of the complex number:
>>> defmandle(c, boundary=2.0, maxloops=10000):
# https://en.wikipedia.org/wiki/Mandelbrot_set
z = 0.0jfor i inrange(maxloops):
z = z * z + c
ifabs(z) > boundary:
breakreturn i
>>> mandle(0.04 + 0.65j)
21>>> mandle(0.04 + 0.66j)
16>>> mandle(0.04 + 0.67j)
12
The rendering itself isn't likely to be the slow part of your program (the 10,000 loops can dwarf the time to plot a point). That said, if you want to speed the rendering, typically the only choice is to plot multiple points per call to the graphics library.
Lastly, consider whether you really want the maximum number of iterations to be 10,000. You can get good results with a maximum of 200 iterations.
Solution 2:
In addition to the complex numbers suggested by @RaymondHettinger, there are several things we can do Zelle-graphics-wise to speed things up. The first is to not use Point()
, it has too much overhead. The win
instance it self has a plot()
method for bitmap manipulation that doesn't have the overhead of Point()
, i.e. can't undraw it, can't move it.
The second is to turn off autoflush and do our own screen flushes on each column. Finally, simply avoid doing any computation you don't need to -- e.g. ca
can be calculated in the outer loop, not the inner. The color can be calculated outside the innermost loop, etc.
Here's my rework as above -- timing a 70 x 70 image, it's about 7x faster than your original code:
from graphics import *
spacing = 1
zoom = 0.1
xOffset, yOffset = -0.171, 0.61
width, height = 700, 700
win = GraphWin('Mandelbrot', width, height, autoflush=False)
win.setBackground('black')
xzoom, yzoom = zoom / width, zoom / height
for real inrange(0, width, spacing):
ca = real * xzoom - xOffset
for imaginary inrange(0, height, spacing):
c, z = complex(ca, imaginary * yzoom - yOffset), 0j
n = 0while n < 10000:
ifabs(z) > 2000:
break
z = z * z + c
n += 1
color = 'black'if n > 5000:
color = 'grey'elif n > 1000:
color = 'white'if color != 'black':
win.plot(real, imaginary, color=color)
win.flush()
Not the full order of magnitude we might hope for, but seven hours less turn around time is still somthing!
Finally, there's a bug in your code that keeps pixels from ever coming out grey -- I've fixed that.
Post a Comment for "How Can I Make This Fractal Render Faster In Zelle Graphics?"