x三次方-23x二次方+122x-160=0,迭代初值分别为1.5 8 20,误差0.00001
我用固定步长的牛顿迭代解决你的问题,请注意,下面代码没有类型检查
# -*- coding= utf-8 -*-
def f(x):
# f的方程
return x**3.0 - 2.0*x + 1.0
def f_first_order(x):
# f的一阶导数
return 3.0 * x ** 2 -2.0
def get_root(x0, max_iter=50, tol = 1e-5):
# 将初始值浮点化
p0 = x0 * 1.0
for i in range(max_iter):
# f的一阶导数不能为0,最普遍的说法是不能非正定
p = p0 - f(p0)/ f_first_order(p0)
# 如果小于精度值则退出迭代
if abs(p - p0) < tol:
return u'经过%s次的迭代,我们估计的参数值是%s' % (i, p)
p0 = p
print u'已达到最大迭代次数, 但是仍然无法收敛'
好了,现在我们开始计算方程的根,由于牛顿迭代方法是局部最优解,所以你会发现,不同的初始值有不同的结果
print get_root(2)
print get_root(0)
print get_root(-2)
当然,除了牛顿迭代,我们还能运用比较蛋疼的梯度下降,用梯度下降,我把梯度下降的步长设为0.1,代码如下
# -*- coding= utf-8 -*-
def raw_f(x):
# 忽略常数项
return 0.25 * x ** 4 - x**2 + x
def f(x):
# f的方程,raw_f的一阶导数
return x**3.0 - 2.0*x + 1.0
def get_root(x0, max_iter=500, tol=1e-10, step=0.1):
# 初始参数浮点化
p0 = x0 * 1.0
for i in range(max_iter):
p = p0 - step * f(p0)
# 如果小于精度值则退出迭代
if abs(raw_f(p0) - raw_f(p)) < tol:
return u'经过%s次的迭代,我们估计的参数值是%s' % (i+1, p)
p0 = p
print u'已达到最大迭代次数, 但是仍然无法收敛'