λ1.3節
問題 1.29
問題 1.30
問題 1.31
問題 1.32
問題 1.33
問題 1.34
問題 1.35
問題 1.36
問題 1.37
問題 1.38
問題 1.39
問題 1.40
問題 1.41
問題 1.42
問題 1.43
問題 1.44
問題 1.45
問題 1.46
問題 1.29
(define (simpson f a b n)
(define h (/ (- b a) n))
(define (simpson-term x) (+ (f x)
(* 4 (f (+ x h)))
(f (+ x h h))))
(define (simpson-next x) (+ x h h))
(/ (* h (sum simpson-term a simpson-next (- b h)))
3.0))
(define (cube x) (* x x x))
(define (sum term a next b)
(if (> a b)
0
(+ (term a)
(sum term (next a) next b))))
(simpson cube 0 1.0 100) ==> .2500000000000005
(simpson cube 0 1.0 1000) ==> .2500000000000006
問題 1.30
(define (sum term a next b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (+ (term a) result))))
(iter a 0))
(define (inc n) (+ n 1))
(define (cube x) (* x x x))
(sum cube 1 inc 10) ==> 3025
問題 1.31
(define (product factor a next b)
(if (> a b)
1
(* (factor a)
(product factor (next a) next b))))
(define (inc n) (+ n 1))
(define (identity x) x)
(define (factorial n)
(product identity 1 inc n))
(display (factorial 10)) (newline)
(define (pi-factor n) (/ (* (- n 1) (+ n 1)) (* n n)))
(define (pi-next n) (+ n 2))
(* (product pi-factor 3.0 pi-next 1000) 4) ==> 3.143163842419204
問題 1.32
(define (accumulate combiner null-value term a next b)
(if (> a b)
null-value
(combiner (term a)
(accumulate combiner null-value term (next a) next b))))
(define (sum term a next b)
(accumulate + 0 term a next b))
(define (product factor a next b)
(accumulate * 1 factor a next b))
反復的
(define (accumulate combiner null-value term a next b)
(define (accumulate-iter a result)
(if (> a b)
result
(accumulate-iter (next a) (combiner (term a) result))))
(accumulate-iter a null-value))
問題 1.33
(define (filtered-accumulate pred combiner null-value term a next b)
(cond ((> a b) null-value)
((pred a)
(combiner (term a)
(filtered-accumulate pred combiner null-value
term (next a) next b)))
(else (filtered-accumulate pred combiner null-value
term (next a) next b))))
(define (prime-square-sum a b)
(filtered-accumulate prime? + 0 square a inc b))
(define (prime? n)
(let ((l
'(1 2 2 4 2 4 2 4 6 2 6 4 2 4 6 6 2 6 4 2 6 4 6 8 4 2 4 2 4 14 4 6 2
10 2 6 6 4 2 4 6 2 10 2 4 2 12 10 2 4 2 4 6 2 6 4 6 6 6 2 6 4 2 6 4 6
8 4 2 4 6 8 6 10 2 4 6 2 6 6 4 2 4 6 2 6 4 2 6 10 2 10 2 4 2 4 6 8 4 2
4 12 2 6 4 2 6 4 6 12 2 4 2 4 8 6 4 6 2 4 6 2 6 10 2 4 6 2 6 4 2 4 2
10 2 10 2 4 6 6 2 6 6 4 6 6 2 6 4 2 6 4 6 8 4 2 6 4 8 6 4 6 2 4 6 8 6
4 2 10 2 6 4 2 4 2 10 2 10 2 4 2 4 8 6 4 2 4 6 6 2 6 4 8 4 6 8 4 2 4 2
4 8 6 4 6 6 6 2 6 6 4 2 4 6 2 6 4 2 4 2 10 2 10 2 6 4 6 2 6 4 2 4 6 6
8 4 2 6 10 8 4 2 4 2 4 8 10 6 2 4 8 6 6 4 2 4 6 2 6 4 6 2 10 2 10 2 4
2 4 6 2 6 4 2 4 6 6 2 6 6 6 4 6 8 4 2 4 2 4 8 6 4 8 4 6 2 6 6 4 2 4 6
8 4 2 4 2 10 2 10 2 4 2 4 6 2 10 2 4 6 8 6 4 2 6 4 6 8 4 6 2 4 8 6 4 6
2 4 6 2 6 6 4 6 6 2 6 6 4 2 10 2 10 2 4 2 4 6 2 6 4 2 10 6 2 6 4 2 6 4
6 8 4 2 4 2 12 6 4 6 2 4 6 2 12 4 2 4 8 6 4 2 4 2 10 2 10 6 2 4 6 2 6
4 2 4 6 6 2 6 4 2 10 6 8 6 4 2 4 8 6 4 6 2 4 6 2 6 6 6 4 6 2 6 4 2 4 2
10 12 2 4 2 10 2 6 4 2 4 6 6 2 10 2 6 4 14 4 2 4 2 4 8 6 4 6 2 4 6 2 6
6 4 2 4 6 2 6 4 2 4 12 2 12)))
(define (test d)
(let ((s (car l)))
(cond ((< (/ n d) d) #t)
((= (remainder n d) 0) #f)
(else (set! l (cdr l)) (test (+ d s))))))
(set-cdr! (list-tail l 484) (list-tail l 5))
(test 2)))
(define (square x) (* x x))
(define (inc n) (+ n 1))
(define (mutual-prime-product n)
(filtered-accumulate (lambda (i) (= (gcd i n) 1)) * 1 id 1 inc n))
(define (id x) x)
(define (gcd a b)
(if (= b 0)
a
(gcd b (remainder a b))))
問題 1.34
(define (f g)
(g 2))
だから
(f f)
=(f 2)
=(2 2)
2は演算子ではないから, これは評価出来ない.
問題 1.35
(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))
(fixed-point (lambda (x) (+ 1.0 (/ 1.0 x))) 1.0)
問題 1.36
(define tolerance 0.00001)
(define (fixed-point f first-guess)
(define (close-enough? v1 v2)
(< (abs (- v1 v2)) tolerance))
(define (try guess)
(display guess) (newline)
(let ((next (f guess)))
(if (close-enough? guess next)
next
(try next))))
(try first-guess))
(fixed-point (lambda (x) (/ (log 1000) (log x))) 2.0)
(fixed-point
(lambda (x)
(/ (+ x (/ (log 1000) (log x))) 2.0)) 2.0)
問題 1.37
(define (cont-frac n d k)
(define (cf i)
(if (= i k)
(/ (n i) (d i))
(/ (n i) (+ (d i) (cf (+ i 1))))))
(cf 1))
(cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 12)
(define (cont-frac-iter n d k)
(define (cf res i)
(if (= i 0)
res
(cf (/ (n i) (+ (d i) res)) (- i 1))))
(cf (/ (n k) (d k)) (- k 1)))
(cont-frac-iter (lambda (i) 1.0) (lambda (i) 1.0) 12)
問題 1.38
(define (cont-frac n d k)
(define (cf res i)
(if (= i 0)
res
(cf (/ (n i) (+ (d i) res)) (- i 1))))
(cf (/ (n k) (d k)) (- k 1)))
(+ 2.0
(cont-frac (lambda (i) 1.0)
(lambda (i) (if (= (remainder i 3) 2)
(/ (+ i i 2.0) 3.0)
1.0))
20))
問題 1.39
(define (cont-frac n d k)
(define (cf res i)
(if (= i 0)
res
(cf (/ (n i) (+ (d i) res)) (- i 1))))
(cf (/ (n k) (d k)) (- k 1)))
(define (tan-cf x k)
(cont-frac (lambda (i) (if (= i 1) x (- (* x x))))
(lambda (i) (+ i i -1.0)) k))
(tan-cf (/ 3.14159 4) 10)
問題 1.40
(define dx 0.00001)
(define (deriv g)
(lambda (x)
(/ (- (g (+ x dx)) (g x))
dx)))
(define (newton-transform g)
(lambda (x)
(- x (/ (g x) ((deriv g) x)))))
(define (newtons-method g guess)
(fixed-point (newton-transform g) guess))
(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 (cubic a b c)
(lambda (x) (+ (* (+ (* (+ x a) x) b) x) c)))
(newtons-method (cubic 3 3 1) 1)
問題 1.41
(define (double f)
(lambda (x) (f (f x))))
(define (inc x) (+ x 1))
(newline)
(display (((double (double double)) inc) 5)) → 21
説明 置換えモデルで評価してみる. doubleをDと書こう. 赤字が評価部分
(((D (D D)) inc) 5)
=(((λ(x) ((D D) ((D D) x))) inc) 5)
=(((D D) ((D D) inc)) 5)
=(((λ(x) (D (D x))) ((λ(x) (D (D x))) inc)) 5) (* 0)
(* 0)の赤字部分(2箇所)を取り出し, 別に評価する.
(λ(x) (D (D x)))
=(λ(x) (λ(y) ((D x) ((D x) y))))
=(λ(x) (λ(y) ((λ(z) (x (x z))) ((λ(z) (x (x z))) y))))
=(λ(x) (λ(y) (x (x ((λ(z) (x (x z))) y))) ))
=(λ(x) (λ(y) (x (x (x (x y)) )) ))
これを(* 0)の赤字部分(2箇所)に置き戻す.
=(( (λ(x) (λ(y) (x (x (x (x y)) )) ))
( (λ(x) (λ(y) (x (x (x (x y)) )) )) inc)) 5)
=(( (λ(x) (λ(y) (x (x (x (x y)) )) ))
(λ(y) (inc (inc (inc (inc y)) )) )) 5)
=((λ(y) ((λ(y) (inc (inc (inc (inc y)) )) )
((λ(y) (inc (inc (inc (inc y)) )) )
((λ(y) (inc (inc (inc (inc y)) )) )
((λ(y) (inc (inc (inc (inc y)) )) ) y)))))
5)
=((λ(y) ((λ(y) (inc (inc (inc (inc y)) )) )
((λ(y) (inc (inc (inc (inc y)) )) )
((λ(y) (inc (inc (inc (inc y)) )) )
(inc (inc (inc (inc y)))) )))) 5)
=((λ(y) ((λ(y) (inc (inc (inc (inc y)) )) )
((λ(y) (inc (inc (inc (inc y)) )) )
(inc (inc (inc (inc
(inc (inc (inc (inc y)))) )))) ))) 5)
=((λ(y) ((λ(y) (inc (inc (inc (inc y)) ))
(inc (inc (inc (inc
(inc (inc (inc (inc
(inc (inc (inc (inc y)))))))) )))) )) 5)
=((λ(y) (inc (inc (inc (inc
(inc (inc (inc (inc
(inc (inc (inc (inc
(inc (inc (inc (inc y)))) )))) )))) )))) ) 5)
=21
問題 1.42
(define (compose f g)
(lambda (x) (f (g x))))
(define (square x) (* x x))
(compose square inc) 6)) ==> 49
問題 1.43
(define (repeated f n)
(if (= n 0)
(lambda (x) x)
(compose f (repeated f (- n 1)))))
(repeated square 2) 5) ==> 625
(repeated square 1) 5) ==> 25
(repeated square 0) 5) ==> 5
問題 1.44
(define (oddp x)
(= (remainder x 2) 1))
(define (compose f g)
(lambda (x) (f (g x))))
(define (repeated f n)
(if (= n 0)
(lambda (x) x)
(compose f (repeated f (- n 1)))))
(define dx 0.1)
(define (smooth f)
(lambda (x) (/ (+ (f x) (f (- x dx)) (f (+ x dx))) 3)))
(define (n-fold-smooth f n)
((repeated smooth n) f))
(define (f x)
(let ((ix (floor x)))
(if (oddp ix) (+ (- ix x) 1) (- x ix))))
(do ((x 5 (+ x 1))) ((= x 25))
(display (list (/ x 10) (f (/ x 10)))) (newline))
;実行例
(do ((x 5 (+ x 1))) ((= x 25))
(display (list (/ x 10) ((n-fold-smooth f 3) (/ x 10)))) (newline))
;(1/2 .5)
;(3/5 .6)
;(7/10 .6999999999999998)
;(4/5 .7925925925925926)
;(9/10 .8629629629629628)
;(1 .8888888888888888)
;(11/10 .8629629629629628)
;(6/5 .7925925925925924)
;(13/10 .6999999999999998)
;(7/5 .6000000000000001)
;(3/2 .5)
;(8/5 .3999999999999999)
;(17/10 .30000000000000004)
;(9/5 .2074074074074074)
;(19/10 .13703703703703715)
;(2 .11111111111111122)
;(21/10 .13703703703703715)
;(11/5 .20740740740740757)
;(23/10 .2999999999999999)
;(12/5 .3999999999999999)
問題 1.45
(define k 1)
(define (compose f g)
(lambda (x) (f (g x))))
(define (repeated f n)
(if (= n 0)
(lambda (x) x)
(compose f (repeated f (- n 1)))))
(define tolerance 0.00001)
(define (average x y)
(/ (+ x y) 2))
(define (average-damp f)
(lambda (x) (average x (f x))))
(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 (n-th-root n x)
(fixed-point ((repeated average-damp k)
(lambda (y) (/ x (expt y (- n 1))))) 1.0))
;実験してみると
;n=2,3 はk=1で出来る.
;n=4,5,..,7 はk=2で出来る.
;n=8,9,...,15はn=3で出来る.
;n=16,... はn=4でないと出来ないらしい.
;したがって完成版のn-th-rootは
(define (n-th-root n x)
(let ((k (floor (/ (log n) (log 2)))))
(fixed-point ((repeated average-damp k)
(lambda (y) (/ x (expt y (- n 1))))) 1.0)))
;やってみよう.
(do ((n 1 (+ n 1))) ((= n 32))
(display (n-th-root n 2)) (newline))
;2.
;1.4142135623746899
;1.259923236422975
;1.189207115002721
;1.1486967244204176
;1.1224648393618204
;1.1040857488809648
;1.090507732665258
;1.0800601441048037
;1.0717742428174573
;1.065039586617723
;1.059461368044972
;1.0547695373814245
;1.050752520212518
;1.0472983541977885
;1.0442737824274142
;1.0416156614885945
;1.0392595425499167
;1.0371561253194534
;1.0352662146623808
;1.0335586312466867
;1.0320056593867177
;1.0305933664724618
;1.02929997968937
;1.0281108225009543
;1.0270212252548725
;1.0260079614009368
;1.0250678862254134
;1.0241933227655466
;1.0233696479018326
;1.0226067502327343
問題 1.46
(define (iterative-improve test improve)
(lambda (g)
(define (iter g)
(if (test g) g
(iter (improve g))))
(iter g)))
(define (sqrt x)
(define (good-enough? g)
(define (square x) (* x x))
(< (abs (- (square g) x)) 0.0001))
(define (improve g)
(define (average x y) (/ (+ x y) 2))
(average g (/ x g)))
((iterative-improve good-enough? improve) 1.0))
(sqrt 2) ==> 1.4142156862745097
(define (fixed-point f)
(define (close-enough? g)
(< (abs (- g (f g))) 0.00001))
((iterative-improve close-enough? f) 1.0))
(fixed-point cos) ==> .7390893414033927