SICPの1.3.3 Procedures as General MethodsあたりをPythonでやってみた
1.3.3 Procedures as General Methods
(一般的なメソッドの手順)
Finding roots of equations by the half-interval method
(平均化した半分間隔メソッドのルートを探し出す)
(define (average x y) (/ (+ x y) 2)) (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 ((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))))) (half-interval-method sin 2.0 4.0);3.14111328125 (half-interval-method (lambda (x) (- (* x x x) (* 2 x) 3)) 1.0 2.0);1.89306640625
from math import sin def average(x, y): return (x + y) / 2 def search(f, neg_point, pos_point): midpoint = average(neg_point, pos_point) if close_enough(neg_point, pos_point): return midpoint test_value = f(midpoint) if test_value > 0: return search(f, neg_point, midpoint) elif test_value <= 0: return search(f, midpoint, pos_point) else: midpoint def close_enough(x, y): return abs(x - y) < 0.001 def half_interval_method(f, a, b): a_value = f(a) b_value = f(b) if a_value <= 0 and b_value > 0: return search(f, a, b) elif b_value <= 0 and a_value > 0: return search(f, b, a) else: print "Values are not of opposite sign %d %d" %(a, b) print half_interval_method(lambda x:sin(x), 2.0 ,4.0) #3.14111328125 print half_interval_method(lambda x:x*x*x - 2*x - 3, 1.0, 2.0) #1.89306640625
Finding fixed points of functions
(関数の一定の効果を求める)
(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)) (fixed-point cos 1.0);0.7390822985224023
from math import cos def tolerance(): return 0.00001 def fixed_point(f, first_guess): def close_enough(v1, v2): return abs(v1 - v2) < tolerance() def f_try(guess): next = f(guess) if close_enough(guess, next): return next return f_try(next) return f_try(first_guess) print fixed_point(lambda x:cos(x), 1.0) #0.7390822985224023