(ラジアンで表す)角度の正弦は, xが十分小さい時, sin x ≒ xの近似と, 正弦の引数の値を小さくするための三角関係式
sin(x) = 3sin(x/3) - 4sin3(x/3)
を使って計算出来る. (この問題のためには, 角度の大きさが0.1ラジアンより大きくなければ「十分小さい」と考える.) この方法は次の手続きに採用してある:
(define (cube x) (* x x x)) (define (p x) (- (* 3 x) (* 4 (cube x)))) (define (sine angle) (if (not (> (abs angle) 0.1)) angle (p (sine (/ angle 3.0)))))
a. (sine 12.15)の評価で, 手続きpは何回作用させられたか.
b. (sine a)の評価で, 手続きsineの生成するプロセスが使うスペースとステップ数の増加の程度は(aの関数として)何か.
問題文の手続きを定義します.
手続きpを作用させた回数を調べるためにトレースを使います.
(require (lib "racket/trace.ss")) (define (cube x) (* x x x)) (define (p x) (- (* 3 x) (* 4 (cube x)))) (define (sine angle) (if (not (> (abs angle) 0.1)) angle (p (sine (/ angle 3.0))))) (trace p)
計算結果は次のとおりです.
ようこそ DrRacket, バージョン 6.1 [3m]. 言語: Pretty Big; memory limit: 2048 MB. > (sin 12.5) -0.06632189735120068 > (sine 12.5) >(p 0.051440329218107005) <0.153776521096694 >(p 0.153776521096694) <0.4467840153484446 >(p 0.4467840153484446) <0.9836111719853284 >(p 0.9836111719853284) <-0.8557060643295382 >(p -0.8557060643295382) <-0.060813768577286265 -0.060813768577286265 >
トレースの結果から, pを作用させた回数は5回です.
手続きの定義から, aの値が0.1より大きい時は手続きを再帰的に呼び出し,
次のaの値は1/3になっています.
「十分小さい」と判断する値をe, ステップ数をnとすると次の関係が成り立ちます.
(a/3)n | < | e |
a/e | < | 3n |
log3(a/e) | < | n |
このことから, ステップ数の増加の程度はlog aであるといえます.
また, 手続きは末尾再帰になっていないため, スペースの増加の程度もステップの増加の程度と同じです.
0 件のコメント:
コメントを投稿