SICP 読み (53) 2.4.3 データ主導プログラミングと加法性
問題 2.73 の c を見てて、あの解では例えば
(+ (+ (** x 2) (* x y)) (** y 2))
みたいな式を deriv に吸わせたら (** y 2) も (* 2 y) になるじゃん、と。おそらくは 問題 2.56 の解が違うのではないか、という事で微分な資料を見てみた。
で、テキストに出ている以下の式
なんですが、ようやく意味が理解でけた (恥
例えば (** x 2) を微分したら
(* (* 2 (** x 1)) (deriv 'x 'x))
で、(** y 2) を微分したら
(* (* 2 (** y 1)) (deriv 'y 'x))
になる、と。これなら大丈夫だな。
このエントリ(SICP 読み (39) 2.3.2 例: 記号微分)は誤りがある旨を追記しておきます。とほほほほ。
で、修正した解は以下ですか。(修正分の手続きのみ)
(define (install-deriv-package) (define (sum l var) (define (addend exp) (car exp)) (define (augend exp) (cadr exp)) (make-sum (deriv (addend l) var) (deriv (augend l) var))) (define (product l var) (define (multiplier exp) (car exp)) (define (multiplicand exp) (cadr exp)) (make-sum (make-product (multiplier l) (deriv (multiplicand l) var)) (make-product (deriv (multiplier l) var) (multiplicand l)))) (define (exponential l var) (define (base x) (car x)) (define (exponent x) (cadr x)) (make-product (make-product (exponent l) (make-exponentiation (base l) (- (exponent l) 1))) (deriv (base l) var))) (put 'deriv '+ sum) (put 'deriv '* product) (put 'deriv '** exponential) 'done)
こんな試験も追加。
("deriv test (forth)" (assert-equal '(+ (* 2 x) y) (deriv '(+ (+ (** x 2) (* x y)) (** y 2)) 'x)) )
で、d も実装して試してみたのですが、試験に通った。いいのかなぁ。変更点のみ以下に。
(define (deriv exp var) (cond ((number? exp) 0) ((variable? exp) (if (same-variable? exp var) 1 0)) ; (else ((get 'deriv (operator exp)) (operands exp) var)))) (else ((get (operator exp) 'deriv) (operands exp) var))))
もうひとつ。
(define (install-deriv-package) (define (sum l var) (define (addend exp) (car exp)) (define (augend exp) (cadr exp)) (make-sum (deriv (addend l) var) (deriv (augend l) var))) (define (product l var) (define (multiplier exp) (car exp)) (define (multiplicand exp) (cadr exp)) (make-sum (make-product (multiplier l) (deriv (multiplicand l) var)) (make-product (deriv (multiplier l) var) (multiplicand l)))) (define (exponential l var) (define (base x) (car x)) (define (exponent x) (cadr x)) (make-product (make-product (exponent l) (make-exponentiation (base l) (- (exponent l) 1))) (deriv (base l) var))) ; (put 'deriv '+ sum) ; (put 'deriv '* product) ; (put 'deriv '** exponential) (put '+ 'deriv sum) (put '* 'deriv product) (put '** 'deriv exponential) 'done)
最後の問題 2.74 はスルーしたい。(こら