(define (f x) (exact->inexact (/ 1 (+ 1 (expt x 2)))))
(define a -1)
(define b 1)
; int [-1, 1] 1 / (1+x**2) dx
;
; report.scm の (solve1 N) (solve2 N) (solve3 k j) が、それぞれ、
; N点複合台数則、N点Gauss則、Romberg積分をするもの.
;
; 例えば
; (display (solve1 40))(newline)
; (display (solve2 6))(newline)
; (display (solve3 4 3))(newline)
; とすると
; 1.5705879934770641
; 1.570731707317072
; 1.5707928918809373
; と出力された.
;
; 真値は
; (* 2 (atan 1)))
; によって
; 1.5707963267948966
; と計算される.
; 手で計算したところ、真の値は pi/2 であった
(define truth
(* 2 (atan 1)))
; Trapezoidal rule
(define (solve1 N) ; integral from a to b by N splits
(let ((h (/ (- b a) N)))
(define (solve1-sub i ac)
(let ((x (+ a (* i h))))
(cond ((= i 0) (solve1-sub (+ i 1) (+ ac (/ (f x) 2))))
((= i N) (* h (+ ac (/ (f x) 2))))
(else (solve1-sub (+ i 1) (+ ac (f x)))))))
(solve1-sub 0 0)))
; Gauss-Legendre
(define (solve2 N)
(define pi 3.14159265358979323846264338)
(define (P n x)
(cond ((= n 0) 1)
((= n 1) x)
(else (/ (- (* (- (* 2 n) 1) x (P (- n 1) x)) (* (- n 1) (P (- n 2) x))) n)) ))
(define (newton x c)
(if (<= c 0) x
(newton
(- x [/ (- 1 (* x x)) N (- (/ (P (- N 1) x) (P N x)) x)])
(- c 1))))
(define (x i)
(newton
(cos (* (+ i 0.75) pi (/ 1 (+ N 0.5))))
10))
(define (w i)
(let ((x_i (x i)))
(* 2 [- 1 (* x_i x_i)] [/ 1 (expt (* N (P (- N 1) x_i)) 2)])))
(define (solve2-sub i ac)
(if (= i N) ac
(solve2-sub (+ i 1) (+ ac (* (f (x i)) (w i))))))
(solve2-sub 0 0))
; Romberg
(define (solve3 k j)
(if (= j 0) (solve1 (expt 2 k))
(let ((r (expt 4 j)))
(/ (- (* r (solve3 k (- j 1))) (solve3 (- k 1) (- j 1)))
(- r 1)) )))
(define (err x) (abs (/ (- x truth) truth )))
(define (plot n)
(if (< n 11)
(begin
(display n)(display " ")
(display (err (solve3 n 2)))(newline)
(plot (+ n 1)))
(newline)))
(plot 2)