def draw(f, df, size, name, x_min=-2.0, x_max=2., y_min=-2.0, y_max=2.0, eps=1e-6,
max_iter=40):
'''Given function f, its derivative df,
generate its newton fractal with size, save to image with name
f是一个函数,我们需要求解方程 f(x) = 0
df是f的导数
size是图片大小,单位是像素
name是保存图像的名字
x_min, x_max, y_min, y_max定义了迭代初始值的取值范围
eps是判断迭代停止的条件
'''
def newton_method(c):
"c is a complex number"
for i in range(max_iter):
c2 = c - f(c) / df(c)
if abs(f(c)) > 1e10:
return None, None
if abs(c2 - c) < eps:
return c2, i
c = c2
return None, None
roots = [] # 记录所有根
img = Image.new("RGB", (size, size)) # 把绘画结果保存为图片
for x in range(size):
print("%d in %d" % (x, size))
for y in range(size): # 嵌套循环,遍历定义域中每个点,求收敛的根
z_x = x * (x_max - x_min) / (size - 1) + x_min
z_y = y * (y_max - y_min) / (size - 1) + y_min
root, n_converge = newton_method(complex(z_x, z_y))
if root:
cached_root = False
for r in roots:
if abs(r - root) < 1e-4: # 判断是不是已遇到过此根
root = r
cached_root = True
break
if not cached_root:
roots.append(root)
if root:
img.putpixel((x, y), color(roots.index(root), n_converge)) # 上色
print(roots) # 打印所有根
img.save(name, "PNG") # 保存图片
好了,有了这几个函数,我们就可以开始实验了。上面的 的图可以用下面几行代码作出
def f(x):
return x ** 3 - 1
def df(x):
return 3 * x * x
draw(f, df, 1000, "x^3-1.png")