我正在尝试在Python中实现Newton的方法,但我在概念上理解了支票的位置问题。
重新审视牛顿方法,通过区分重复线性近似来近似根:
我有以下代码:
# x_1 = x_0 - (f(x_0)/f'(x_0))
# x_n+1 - x_n = precision
def newton_method(f, f_p, prec=0.01):
x=1
x_p=1
tmp=0
while(True):
tmp = x
x = x_p - (f(x_p)/float(f_p(x_p)))
if (abs(x-x_p) < prec):
break;
x_p = tmp
return x
这是有效的,但是如果我将循环中的if
语句移动到x_p = tmp
行之后,该函数将停止按预期工作。像这样:
# x_1 = x_0 - (f(x_0)/f'(x_0))
# x_n+1 - x_n = precision
def newton_method(f, f_p, prec=0.01):
x=1
x_p=1
tmp=0
while(True):
tmp = x
x = x_p - (f(x_p)/float(f_p(x_p)))
x_p = tmp
if (abs(x-x_p) < prec):
break;
return x
为了澄清,函数v1(第一段代码)按预期工作,函数v2(第二段)没有。
为什么会这样?
原始版本不是基本上从2个作业中检查当前x
与x
,而不是之前的x
吗?
以下是我正在使用的测试代码:
def f(x):
return x*x - 5
def f_p(x):
return 2*x
newton_method(f,f_p)
修改
我最终使用了这个版本的代码,它放弃了tmp
变量,对我来说更加清晰,概念上:
# x_1 = x_0 - (f(x_0)/f'(x_0))
# x_n+1 - x_n = precision
def newton_method(f, f_p, prec=0.01):
x=1
x_p=1
tmp=0
while(True):
x = x_p - (f(x_p)/float(f_p(x_p)))
if (abs(x-x_p) < prec):
break;
x_p = x
return x
答案 0 :(得分:2)
让x[i]
成为迭代中计算的新值。
声明x = x_p - (f(x_p)/float(f_p(x_p)))
转换为:
x[i] = x[i-2] - f(x[i-2])/f'(x[i-2])
- 1
但根据实际的数学公式,应该是这样的:
x[i] = x[i-1] - f(x[i-1])/f'(x[i-1])
同样,x[i-1] = x[i-2] - f(x[i-2])/f'(x[i-2])
- 2
比较 1 和 2 ,我们可以看到中的x[i]
根据数学公式, 1 实际上是x[i-1]
。
这里要注意的要点是x
和x_p
总是相隔一次。也就是说,x
是x_p
的实际继承者,与看待代码时看起来不同。
因此,它按预期正常工作。
就像上面的情况一样,同样的事情发生在x = x_p - (f(x_p)/float(f_p(x_p)))
陈述中
但是当我们到达if (abs(x-x_p) < prec)
时,x_p
已将其值更改为temp
= x
= x[i-1]
。
但正如版本1中所推断的那样,x
也是x[i-1]
而不是x[i]
。
因此,abs(x - x_p)
转换为abs(x[i-1] - x[i-1])
,结果为0,从而终止迭代。
这里要注意的要点是,x
和x_p
实际上是数字上相同的值,这总是导致算法在1次迭代后终止。
答案 1 :(得分:0)
<强>更新强>
这将保存x
的当前值tmp = x
在此语句中,x的下一个值是从当前值x_p
x = x_p - (f(x_p)/float(f_p(x_p)))
如果收敛(例如下一个值 - 当前值&lt; threshold),则中断
if (abs(x-x_p) < prec):
break;
将x_p设置为下一个迭代的值
x_p = tmp
如果你将x_p = tmp
拉到if语句之上,那么你实际上是在2次迭代之前检查x
vs x`,这不是你想要做的。这实际上会导致奇怪的行为,其中结果的正确性取决于起始值。如果你从x开始得到正确的答案,而如果从1开始,你就不会。
要测试它并查看原因,添加如下的打印声明会很有帮助。
def newton_method(f, f_p, prec=0.01):
x=7
x_p=1
tmp=0
while(True):
tmp = x
x = x_p - (f(x_p)/float(f_p(x_p)))
print (x,x_p,_tmp)
if (abs(x-x_p) < prec):
break;
x_p = tmp
您是否尝试从2次迭代前检查X vs X?或者来自循环的上一次迭代的X?
如果您在if语句之前有x_p=tmp
,if (abs(x-x_p) < prec):
将检查x的当前值与之前版本的x,而不是之前2个分配中的x