計算機プログラムの構造と解釈 第二版 P33 問題1.30

この問題、ここまでまじめにやってきた僕にとってボーナス問題に近い。


反復的にっていうのは僕の解釈だと、
「今までの計算結果(状態)を引数で渡してあげちゃって、終了条件で結果を返す」
みたいな方式で、そうすると「立つ鳥後を濁さず」みたく再帰計算ができる。


Erlangをやってたときは、tail recursionって先生が言ってた気がする。


んで、方針としては、
カウンタを回す方法としては

(next a)

こんな感じで増やしていける。


終了条件は

(> a b)

で、この時、最終的な結果を返す。


計算自体は

(term a)


んで、その結果である、resultと足して次の再帰にはいればいいので

(+ result (term a))

としてやればいい。


ということで、1-29でつかってるsumの部分を書き換えてやる感じで。
こんな感じ

#!/usr/local/bin/gosh
;; -*- coding: utf-8 -*-

(use ggc.debug.trace)
(use math.mt-random)

;(define (sum term a next b)
;  (if (> a b)
;    0
;    (+ (term a)
;       (sum term (next a) next b))))

;; 1-30
(define (sum term a next b)
  (define (iter a result)
    (if (> a b)
      result
      (iter (next a) (+ result (term a)))))
  (iter a 0)) 


(define (cube a)
  (* a a a)) 


;;integral
(define (integral f a b dx) 
  (define (add-dx x)
    (+ x dx))
  (* (sum f (+ a (/ dx 2.0)) add-dx b) dx))


;;Simpson
(define (simpson f a b n)
  (define h
    (/ (- b a) n)) 
  (define (yk k)
    (f (+ (* k h) a)))
  (define (next n)
    (+ n 2)) 
  (define (term k)
    (+ (* 2.0 (yk k)) 
       (* 4.0 (yk (+ k 1)))))
  (/ (* h (- (+ (sum term 0 next (- n 2)) (yk n)) (yk 0))) 3.0))


;; main
(define (main args)

  (display "simpsonを利用して0から1までのcubeを、100個に区切って計算 : ")
  (display (simpson cube 0 1 100))(newline)
  (display "simpsonを利用して0から1までのcubeを、1000個に区切って計算 : ")
  (display (simpson cube 0 1 1000))(newline)(newline)


  (display "integralを利用して0から1までのcubeを、100個(0.01刻み)に区切って計算 : ")
  (display (integral cube 0 1 0.01))(newline)
  (display "integralを利用して0から1までのcubeを、1000個(0.001刻み)に区切って計算 : ")
  (display (integral cube 0 1 0.001))(newline)
 0)

たぶんできてるんだが、
前回の実行より、誤差がでかくなってるのが気になる。
うーむ。