#lang racket (require "3-5-streams.rkt") ;; We use the Racket built-in force and delay with the book stream implementation. ;; (delay e) produces a 'promise'. (delay e) does not evaluate e. ;; (force (delay e)) evaluates e and caches its value. ;; For example: (define prms (delay (begin (displayln 'hello) (* 2 3)))) prms ;; # (force prms) ;; hello ;; 6 (force prms) ; subsequent force's return the cached value ;; 6 ;;;;;;;;;; ;; 3.77 ;; ;;;;;;;;;; (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))))) (define (solve f y0 dt) (define y (integral (delay dy) y0 dt)) (define dy (my-stream-map f y)) y) (my-stream-ref (solve (lambda (y) y) 1 0.001) 1000) ;; 2.716923932235896 ;;;;;;;;;; ;; 3.78 ;; ;;;;;;;;;; (define (solve-2nd a b dt y0 dy0) (define y (integral (delay dy) y0 dt)) (define dy (integral (delay ddy) dy0 dt)) (define ddy (add-streams (scale-stream dy a) (scale-stream y b))) y) ;; y'' - 2 * y' + y = 0 with y(0) = 1 and y'(0) = 1 ;; has solution y = e ^ t so y(1) = e (exp 1) ;; 2.718281828459045 (my-stream-ref (solve-2nd 2 -1 0.001 1 1) 1000) ;; 2.716923932235896 ;;;;;;;;;; ;; 3.79 ;; ;;;;;;;;;; (define (generalized-solve-2nd f dt y0 dy0) (define y (integral (delay dy) y0 dt)) (define dy (integral (delay ddy) dy0 dt)) (define ddy (my-stream-map f dy y)) y) ;; Same example as above: (my-stream-ref (generalized-solve-2nd (lambda (u v) (+ (* 2 u) (- v))) 0.001 1 1) 1000) ;; 2.716923932235896 ;;;;;;;;;; ;; 3.80 ;; ;;;;;;;;;; (define (RLC R L C dt) (lambda (vC0 iL0) (define vC (integral (delay (scale-stream iL (/ -1.0 C))) vC0 dt)) (define iL (integral (delay (add-streams (scale-stream vC (/ 1.0 L)) (scale-stream iL (/ (* -1.0 R) L)))) iL0 dt)) (my-stream-map cons vC iL))) (display-this-many 10 ((RLC 1 1 0.2 0.1) 10 0) 'vert) ;; (10 . 0) ;; (10 . 1.0) ;; (9.5 . 1.9) ;; (8.55 . 2.66) ;; (7.220000000000001 . 3.249) ;; (5.5955 . 3.6461) ;; (3.77245 . 3.84104) ;; (1.8519299999999999 . 3.834181) ;; (-0.0651605000000004 . 3.6359559) ;; (-1.8831384500000004 . 3.2658442599999997) ;; 'done