根据题目给出的定义,写出平滑函数 smooth :
;;; 44-smooth.scm
(define dx 0.00001)
(define (smooth f)
(lambda (x)
(/ (+ (f (- x dx))
(f x)
(f (+ x dx)))
3)))
测试:
1 ]=> ((smooth square) 5)
;Value: 25.000000000066663
题目还要求我们写出一个可以连续进行 n 次平滑的函数(叫它 smooth-n-times 好了)。
根据描述,表达式 (smooth-n-times f 3) 的展开式应该为:
(smooth-n-times f 3)
(smooth (smooth-n-times f 2))
(smooth (smooth (smooth-n-times f 1)))
(smooth (smooth (smooth f)))
根据这个展开式,最简单直观的 smooth-n-times 可以这样定义:
;;; 44-smooth-n-times.scm
(load "44-smooth.scm")
(define (smooth-n-times f n)
(if (= n 0)
f
(smooth (smooth-n-times f (- n 1)))))
上面的 smooth-n-times 是一个递归计算过程, smooth-n-times 的迭代计算过程定义如下:
;;; 44-iter-smooth-n-times.scm
(load "44-smooth.scm")
(define (smooth-n-times f n)
(define (iter i smoothed-f)
(if (= i 0)
smoothed-f
(iter (- i 1)
(smooth smoothed-f))))
(iter n f))
事实上,在前面的 smooth-n-times 定义里,我们做了重复的工作,因为在 练习 1.43 里,我们就写过生成连续调用序列的函数 repeated ,而 smooth-n-times 里对 smooth 的连续调用完全可以使用 repeated 来完成,从而避免显式的递归,以及 off-by-one 错误:
(repeated smooth 3)
(lambda (f)
(smooth (repeated smooth 2)))
(lambda (f)
(smooth (smooth (repeated smooth 1))))
(lambda (f)
(smooth (smooth (smooth f))))
以下是使用 repeated 实现的 smooth-n-times 的定义:
;;; 44-smooth-n-times-using-repeated.scm
(load "44-smooth.scm")
(load "43-repeated.scm")
(define (smooth-n-times f n)
(let ((n-times-smooth (repeated smooth n)))
(n-times-smooth f)))
无 repeated ,递归计算的 smooth-n-times :
1 ]=> (load "44-smooth-n-times.scm")
;Loading "44-smooth-n-times.scm"...
; Loading "44-smooth.scm"... done
;... done
;Value: smooth-n-times
1 ]=> ((smooth-n-times square 10) 5)
;Value: 25.000000000666663
无 repeated ,迭代计算的 smooth-n-times :
1 ]=> (load "44-iter-smooth-n-times.scm")
;Loading "44-iter-smooth-n-times.scm"...
; Loading "44-smooth.scm"... done
;... done
;Value: smooth-n-times
1 ]=> ((smooth-n-times square 10) 5)
;Value: 25.000000000666663
带 repeated 的 smooth-n-times (是递归计算还是迭代计算取决于所使用的 repeated 函数):
1 ]=> (load "44-smooth-n-times-using-repeated.scm")
;Loading "44-smooth-n-times-using-repeated.scm"...
; Loading "44-smooth.scm"... done
; Loading "43-repeated.scm"... done
;... done
;Value: smooth-n-times
1 ]=> ((smooth-n-times square 10) 5)
;Value: 25.000000000666663