全部学习汇总: https://github.com/GreyZhang/g_SICP
这是半区间法寻找函数零点的方法介绍,比较容易理解。函数连续且取值范围内找到了两个一正一负的输入,那么零点在两个数值之间,通过不断逼近的方式能够找到一个近似零点。
(define (search f neg-point pos-point)
(let ((midpoint (average neg-point pos-point)))
(if (close-enough? neg-point pos-point)
midpoint
(let ((test-value (f midpoint)))
(cond ((positive? test-value)
(search f neg-point midpoint))
((negative? test-value)
(search f midpoint pos-point))
(else midpoint))))))
这是一个函数设计的实现,也是简单明了。其中,else的分支理解应该是正好为0的时候,这时候找到了一个完美解。
(define (close-enough? x y) (< (abs (- x y)) 0.001))
这是关于close-enough?的设计,与之前做平方根求解时候的good-enough?的方式一样。
(define (average x y)
(/ (+ x y) 2))
这是平均值求解的实现,很简单的数学计算表达。
(define (half-interval-method f a b)
(let ((a-value (f a))
(b-value (f b)))
(cond ((and (negative? a-value) (positive? b-value))
(search f a b))
((and (negative? b-value) (positive? a-value))
(search f b a))
(else
(error "Values are not of opposite sign" a b)))))
这是最后抽象设计出来的函数,加了一部分数值输入的判断。因为有些输入可能不满足半区间求解的条件,会导致最终的求解失败。这样加了一个输入的检测判断,整个软件实现看上去的确是透气多了。
这是对上面的设计进行了一点测试,这种输入以及求解的方式让我想到了之前用过的MATLAB。
这是对于方程固定点的一个描述,其实就是f(x) = 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))
这是对这个求解过程的一个软件实现。最终,求解成功的判断方式是收敛的结果带入到方程之后数值不变。
这是对这个函数实现的2个测试。
借由这个不动点的概念,可以求解平方根。
但是,这个不动点的求解过程并不是百分百收敛过程。因为这个不动点位于y和x/y之间,因此用两者的平均值来取代x/y作为下一次的计算值就可以保证这个过程的收敛。如此,求解的过程变成了求解y在(y + x/y)/2上的不动点。
之后,做一个简单的测试可以看得出来工作基本OK了。
这一章节的练习题跳过了,做第一个,或许是最简单的。感觉相应的处理方法基本上理解到了,点到即止吧!