SICP/ex-1_35-39.scm

203 lines
4.8 KiB
Scheme

(define (average a b) (/ (+ a b) 2.0))
(define (search f neg-point pos-point)
(let ((midpoint (average neg-point pos-point)))
(if (close-enough? neg-point pos-point)
midpoint
(let ((test-value (f midpoint)))
(cond ((positive? test-value)
(search f neg-point midpoint))
((negative? test-value)
(search f midpoint pos-point))
(else midpoint))))))
(define (close-enough? x y)
(< (abs (- x y)) 0.001))
(define (half-interval-method f a b)
(let ((a-value (f a))
(b-value (f b)))
(cond ((and (negative? a-value) (positive? b-value))
(search f a b))
((and (negative? b-value) (positive? a-value))
(search f b a))
(else
(error "Values are not of opposite sign" a b)))))
(display (half-interval-method sin 2.0 4.0)) (newline)
(define tolerance 0.00001)
(define (fixed-point f first-guess)
(define (close-enough? v1 v2)
(< (abs (- v1 v2)) tolerance))
(define (try guess)
(let ((next (f guess)))
(if (close-enough? guess next)
next
(try next))))
(try first-guess))
(display (fixed-point cos 1.0)) (newline)
(define (sqrt x)
(fixed-point (lambda (y) (/ x y))
1.0))
; (display (sqrt 2) (newline)) ; doesn't converge
(define (sqrt x)
(fixed-point (lambda (y) (average y (/ x y)))
1.0))
(display (sqrt 2))
(newline)(newline) (display "ex-1.35") (newline)
; phi^2 = phi + 1
; phi = 1 + 1 / phi
(display (fixed-point (lambda (phi) (+ 1 (/ 1.0 phi))) 1.0)) (newline)
(newline)(newline) (display "ex-1.36") (newline)
(define (x_without_avg_damping x) (/ (log 1000) (log x)))
(define (x_with_avg_damping x)
(average x (/ (log 1000) (log x))))
(define (fixed-point f first-guess)
(define (close-enough? v1 v2)
(< (abs (- v1 v2)) tolerance))
(define (try guess)
(display guess) (newline)
(let ((next (f guess)))
(if (close-enough? guess next)
next
(try next))))
(try first-guess))
(newline)
(display (fixed-point x_without_avg_damping 2.0))(newline)
(display "Finished without average damping.")
(newline)
(newline)
(display (fixed-point x_with_avg_damping 2.0))(newline)
(display "Finished with average damping.")
(newline)(newline) (display "ex-1.37 a)") (newline)
; Recursive
(define (cont-frac n d k)
(define (frac-rec i)
(if (> i k)
0
(/ (n i) (+ (d i) (frac-rec (+ i 1))))))
(frac-rec 1))
(define (phi k)
(/ 1 (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) k)))
(display (phi 100))
(define (approx-phi tolerance)
(define (iteration current-phi i)
(let ((next-phi (phi i)))
(if (< (abs (- next-phi current-phi)) tolerance)
i
(iteration next-phi (+ i 1)))))
(iteration 1.1 1))
; Use approx-phi to calculate value of k to get four digit precisious.
(newline)
(display (approx-phi 0.00009)) ; 12
; Phi is 1.618033 so let's see if we can get many digits right with k = 12
(newline)
(display (phi 11))
(newline)
(display (phi 12))
(newline)
(display (phi 13))
; looks like we have found exactly the right value (:
; Recursive wrong
(define (cont-frac n d k)
(if (= k 1) 0
(/ (n k) (+ (d k) (cont-frac n d (- k 1))))))
(newline)(newline) (display "ex-1.37 b) - implemented iterative version") (newline)
; (phi 100000) ; show that previous version is recursive.
; Iterative
(define (cont-frac n d k)
(define (frac-iter i acc)
(if (= i 0)
acc
(frac-iter (- i 1) (/ (n i) (+ (d i) acc)))))
(frac-iter k 0))
(phi 100000) ; show that this version is iterative
(newline) (display "ex-1.38") (newline)
; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ; Indicies
; 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8 ; Eulers expansion
(define (eulers-expansion k)
(define (n i) 1)
(define (d i)
(if (= (remainder (+ i 1) 3) 0)
(* 2 (/ (+ i 1) 3))
1))
(cont-frac n d k))
(display (+ 2 (/ (eulers-expansion 1000) 1.)))
(newline)(newline) (display "ex-1.39") (newline)
(define (tan-cf x k)
(define (n i)
(if (= i 1)
x
(* x x -1)))
(define (d i) (- (* i 2) 1))
(cont-frac n d k))
(display (tan 1.1)) (newline)
(display (tan-cf 1.1 15)) (newline)
(newline) (display "tests") (newline)
(define (average-damp f)
(lambda (x) (average x (f x))))
(define (sqrt x)
(fixed-point (average-damp (lambda (y) y (/ x y)))
1.0))
(display (sqrt 9)) (newline)
(define dx 0.0000001)
(define (deriv g)
(lambda (x)
(/ (- (g (+ x dx)) (g x))
dx)))
(define (newton-transform g)
(lambda (x)
(- x (/ (g x) ((deriv g) x)))))
(define (newtons-method g guess)
(fixed-point (newton-transform g) guess))
(define (sqrt x)
(newtons-method (lambda (y) (- (* y y) x)) 1.0))
(newline)
(display "example - Newton's Method") (newline)
(display (sqrt 3)) (newline)