計算機プログラムの構造と解釈 第二版 P204 問題3.73
RC回路というと、回路とかもう忘れてしまったのでびっくりする。
だがよく問題を読む。回路の知識は特にいらない。
やらなければ行けない事は二つ
1.
教科書にある以下の式を表現する手続きRCを教科書の定義通り作る。
2.
1でつくったRCを利用して
(define RC1 (RC 5 1 0.5))
を作ってみる。
まず「1」から。
そもそも積分の部分はP203で定義されていた(integral itegrand initial-value dt)を使えばよいんだから、後は上手い事考えればよい。
手続きの入力インターフェースは文章を読んでてもわかりずらいんだけど、
RC1の手続きの定義をみて考えると
(RC R C dt)
みたいな感じ。
RCでアウトプットされるのは、
ということなので
(lambda (i v0)みたいなのは確実にでてくるでしょう。
ということで、v0がinitial-valueになる事v0って名前からも確実。
itegrand(被積分関数)がどこまでかってことで、1/cは積分の中に入れちゃう。
そうすると、積分の部分は
(integral (scale-stream (scale-stream i (/ 1 C)) v0 dt)
って感じになる。
あとは、
(scale-stream i R)
を足せば良いので
(define (RC R C dt) (lambda (i v0) (add-streams (integral (scale-stream i (/ 1 C)) v0 dt) (scale-stream i R))))
か。
「2」はそのままなので省略
#!/usr/local/bin/gosh ;; -*- coding: utf-8 -*- (load "./modules/stream.scm") (define ones (cons-stream 1 ones)) (define seconds (cons-stream 2 seconds)) (define (scale-stream stream factor) (stream-map (lambda (x) (* x factor)) stream)) (define (add-streams s1 s2) (stream-map + s1 s2)) (define integers (cons-stream 1 (add-streams ones integers))) (define (integral integrand initial-value dt) (define int (cons-stream initial-value (add-streams (scale-stream integrand dt) int))) int) (define (RC R C dt) (lambda (i v0) (add-streams (integral (scale-stream i (/ 1 C)) v0 dt) (scale-stream i R)))) (define RC1 (RC 5 1 0.5)) (RC1 ones 1) ;; main (define (main args) (print (RC1 ones 0)) (print (stream-car (stream-cdr (RC1 ones 0)))) (print (stream-car (stream-cdr (stream-cdr (RC1 ones 0))))) (print (stream-car (stream-cdr (stream-cdr (stream-cdr (RC1 ones 0)))))) (print (stream-car (stream-cdr (stream-cdr (stream-cdr (stream-cdr (RC1 ones 0))))))) 0)
./modules/stream.scmは
http://d.hatena.ne.jp/rucifer_hacker/20090127/1233037207
から引用
;; stream.scm (define (memo-proc proc) (let ((already-run? #f) (result #f)) (lambda () (if (not already-run?) (begin (set! result (proc)) (set! already-run? #t) result) result)))) ;;非メモ化 delay (define-macro (delay exp) `(lambda () ,exp)) ;;メモ化 delay (define-macro (delay exp) `(memo-proc (lambda () ,exp))) (define (force exp) (exp)) (define the-empty-stream '()) (define stream-null? null?) (define-macro (cons-stream a b) `(cons ,a (delay ,b))) (define (stream-car stream) (car stream)) (define (stream-cdr stream) (force (cdr stream))) ;;;; (define (stream-ref s n) (if (= n 0) (stream-car s) (stream-ref (stream-cdr s) (- n 1)))) ;; (define (stream-map proc s) ;; (if (stream-null? s) ;; the-empty-stream ;; (cons-stream (proc (stream-car s)) ;; (stream-map proc (stream-cdr s))))) ;; 問題3.50で作成した一般化された stream-map (define (stream-map proc . argstreams) (if (stream-null? (car argstreams)) the-empty-stream (cons-stream (apply proc (map stream-car argstreams)) (apply stream-map (cons proc (map stream-cdr argstreams)))))) (define (stream-for-each proc s) (if (stream-null? s) 'done (begin (proc (stream-car s)) (stream-for-each proc (stream-cdr s))))) (define (display-stream s) (stream-for-each display-line s)) (define (display-line x) (newline) (display x)) ;;;; (define (stream-enumerate-interval low high) (if (> low high) the-empty-stream (cons-stream low (stream-enumerate-interval (+ low 1) high)))) (define (stream-filter pred stream) (cond ((stream-null? stream) the-empty-stream) ((pred (stream-car stream)) (cons-stream (stream-car stream) (stream-filter pred (stream-cdr stream)))) (else (stream-filter pred (stream-cdr stream))))) (define (show-stream s n) (if (= n 0) (newline) (begin (display " ") (display (stream-car s)) (show-stream (stream-cdr s) (- n 1)))))
こんな感じで実行してみる。
(5 . #<closure (memo-proc memo-proc)>) 5.5 6.0 6.5 7.0
多分できていると思う。