练习 1.44

根据题目给出的定义,写出平滑函数 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

smooth-n-times

题目还要求我们写出一个可以连续进行 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))

使用 repeated 定义 smooth-n-times

事实上,在前面的 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

repeatedsmooth-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

讨论

blog comments powered by Disqus