SICP問題3.77
元のintegral(教科書で定義)
(define int (cons-stream initial-value (add-streams (scale-stream integrand dt) int)))
出力ストリームの第一要素より先を生成するよう要求された時だけ、被積分値を評価すべくforceするように再定義したintegral(教科書で定義)
(define (integral delayed-integrand initial-value dt) (define int (cons-stream initial-value (let ((integrand (force delayed-integrand))) (add-streams (scale-stream integrand dt) int)))) int)
dy/dt = f(y)を解くsolveの定義(教科書で定義)
(define (solve f y0 dt) (define y (integral (delay dy) y0 dt)) (define dy (stream-map f y)) y)
integers-starting-fromに良く似たintegralの定義(教科書で定義)
(define (integral integrand initial-value dt) (cons-stream initial-value (if (stream-null? integrand) the-empty-stream (integral (stream-cdr integrand) (+ (* dt (stream-car integrand)) initial-value) dt))))
ループのあるシステムで使うために、integrandを遅延引数としてとり、上のsolve手続きで使えるようにしたintegral手続き
※ integrand を delay しなければならない
(define (integral delayed-integrand initial-value dt) (cons-stream initial-value (let ((integrand (force delayed-integrand))) (if (stream-null? integrand) the-empty-stream (integral (delay (stream-cdr integrand)) (+ (* dt (stream-car integrand)) initial-value) dt)))))
テスト
y(0) = 1, dy/dt=y の解 y=1での値を計算し の近似を得ることでsolve手続きが実証出来る
(stream-ref (solve (lambda (y) y) 1 0.001) 1000) ; 2.716923932235896
OK