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 件のコメント:
コメントを投稿