Math 为什么这些略有不同的寻根方法会产生不同的结果?
考虑计算第五根的这两种稍有不同的方法:Math 为什么这些略有不同的寻根方法会产生不同的结果?,math,lisp,scheme,numerical-methods,Math,Lisp,Scheme,Numerical Methods,考虑计算第五根的这两种稍有不同的方法: (define (fifth-root-right x) (fixed-point-of-transform (lambda (y) (/ x (expt y 4))) (repeated average-damp 2) 1.0)) (define (fifth-root-wrong x) (fixed-point (repeated
(define (fifth-root-right x)
(fixed-point-of-transform (lambda (y) (/ x (expt y 4)))
(repeated average-damp 2)
1.0))
(define (fifth-root-wrong x)
(fixed-point (repeated
(average-damp (lambda (y) (/ x (expt y 4))))
2)
1.0))
由于x的第五根是映射y->x/(y^4)的一个固定点,所以两者都试图通过对固定点的平均阻尼搜索来计算第五根。我已经定义了
(define (average-damp f)
(lambda (x) (average x (f x))))
(define tolerance 0.00001)
(define (fixed-point f first-guess)
(define (close-enough? v1 v2)
(< (abs (- v1 v2)) tolerance))
(define (try guess)
(let ((next (f guess)))
(if (close-enough? guess next)
next
(try next))))
(try first-guess))
(define (fixed-point-of-transform g transform guess)
(fixed-point (transform g) guess))
(define (repeated f n)
(if (= n 1)
f
(compose f (repeated f (- n 1)))))
(define (compose f g) (lambda (x) (f (g x))))
为什么第二种方法无法正确计算第五根?更奇怪的是,如果我们在第四根或第三根上尝试这种错误的方法,它会正确工作:
(define (fourth-root x)
(fixed-point (repeated
(average-damp (lambda (y) (/ x (expt y 3))))
2)
1.0))
(define (cube-root x)
(fixed-point (repeated
(average-damp (lambda (y) (/ x (expt y 2))))
2)
1.0))
> (fourth-root 16)
1.982985155172348
> (cube-root 8)
2.0000009087630515
作为参考,本代码试图解决计算机程序的结构和解释问题。现在我有了正确的方法,我的代码可以工作了,但我不明白为什么我的错误方法是错误的。本质的区别在于什么函数被重复了两次。在正确的方法中,
平均阻尼
应用了两次,产生了更大阻尼的净效果((重复平均阻尼2)f)
从数学上减少到(lambda(x)(+(*0.75x)(*0.25(fx)))
(如果我的语法不正确,我的lisp非常非常生锈,我深表歉意)。这使得算法不易受到变换的剧烈波动的影响
但是,第二种方法应用了两次
(平均阻尼(lambda(y)(/x(expt y 2)))
——也就是说,它阻尼转换一次,然后重复生成的函数。一次应用平均阻尼
仅足以防止序列发散,但不足以实际使其收敛。它实际上收敛到振荡状态,在1.672645084943273
和2.8804350135298153
之间来回反弹。但是,阻尼变换在每一步都应用两次,因此定点
只会看到序列的每一个其他元素-该子序列收敛到后者,即使整个序列无法收敛。您的三阶和四阶示例似乎是正确方法的副本,而不是错误方法。谢谢,修正了现在对与错的标签。另外,我怀疑它对低阶有效的原因仅仅是因为低阶需要较少的阻尼,因此应用较少阻尼的另一个版本仍然能够通过。如果你进一步增加阶数,你可能会发现需要更多的阻尼来抵消增加的向无穷远发射的趋势。这是正确的。当我做同样的问题时,我发现当n加倍时,你需要将平均阻尼的数量增加1@蜥蜴比尔♦: 好帖子。我很确定它是这样工作的,因为这个方法的步骤是一个非常迂回的近似牛顿-拉斐逊步骤的方法。重复平均阻尼m次与计算f(y)=(1-1/2^m)y+x/(2^m y^(n-1))相同。设m为log2(n)使阶跃函数f(y)=(1-1/n)y+x/(ny^(n-1)),这正是牛顿·拉弗森将使用的函数。使用这一层使它成为一个(足够好的)近似值,所以我认为你在文章中的直觉是正确的。
(define (fourth-root x)
(fixed-point (repeated
(average-damp (lambda (y) (/ x (expt y 3))))
2)
1.0))
(define (cube-root x)
(fixed-point (repeated
(average-damp (lambda (y) (/ x (expt y 2))))
2)
1.0))
> (fourth-root 16)
1.982985155172348
> (cube-root 8)
2.0000009087630515