a. sumと(問題1.31の)productは, 一般的なアキュムレーションの関数:
accumulateは引数としてsumや productと同様, 項と範囲指定と, 先行する項のアキュムレーションと現在の項をどう組み合せるかを指定する(二引数の)combiner手続き, 項がなくなった時に使う値を指定するnull-valueをとる. accumulateを書き, sumやproductがaccumulateの単なる呼出しで定義出来ることを示せ.
b. 上のaccumulateが再帰的プロセスを生成するなら, 反復的プロセスを生成するものを書け. 反復的プロセスを生成するなら, 再帰的プロセスを生成するものを書け.
(accumulate combiner null-value term a next b)を使い, 項の集りを組み合せるaccumulateという更に一般的なものの特殊な場合であることを示せ.
accumulateは引数としてsumや productと同様, 項と範囲指定と, 先行する項のアキュムレーションと現在の項をどう組み合せるかを指定する(二引数の)combiner手続き, 項がなくなった時に使う値を指定するnull-valueをとる. accumulateを書き, sumやproductがaccumulateの単なる呼出しで定義出来ることを示せ.
b. 上のaccumulateが再帰的プロセスを生成するなら, 反復的プロセスを生成するものを書け. 反復的プロセスを生成するなら, 再帰的プロセスを生成するものを書け.
手続きsumとproductを比較すると,
「+」と「*」がcombiner, 「0」と「1」がnull-valueに対応します.
手続きを定義すると次のようになります.
(require (lib "racket/trace.ss"))
(define (square x) (* x x))
(define (cube x) (* x x x))
;; 再帰的プロセスを生成する.
(define (accumulate-r combiner null-value term a next b)
(if (> a b)
null-value
(combiner (term a)
(accumulate-r combiner null-value term (next a) next b))))
;; 反復的プロセスを生成する.
(define (accumulate-i combiner null-value term a next b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (combiner (term a) result))))
(iter a null-value))
;; 総和の定義
(define (sum term a next b)
(accumulate-r + 0 term a next b))
;; 定積分を求める.
(define (integral f a b dx)
(define (add-dx x) (+ x dx))
(* (sum f (+ a (/ dx 2.0)) add-dx b)
dx))
;; 指定した範囲の関数値の積を求める.
(define (product term a next b)
(accumulate-i * 1 term a next b))
;; 円周率を求める.
(define (my-pi n)
(define (term x)
(/ (* x (+ x 2)) (square (+ x 1))))
(define (next x)
(+ x 2))
(* 4.0 (product term 2 next n)))
実行してみます.
ようこそ DrRacket, バージョン 6.1 [3m]. 言語: Pretty Big; memory limit: 2048 MB. > (integral cube 0 1 0.01) 0.24998750000000042 > (integral cube 0 1 0.001) 0.249999875000001 > (my-pi 10000) 3.141749705738071 > (my-pi 100000) 3.141608361278168 >
これまでの問題と同様に計算できています.
0 件のコメント:
コメントを投稿