#lang sicp ; here, I will prove an upper bound on the number of average ; dampings needed for a given n while calculating nth-root ; in other words, you might need fewer damps than what i prove ; but you definitely have enough damps with this method. ; with n, we need the transform y -> x/y^(n-1) ; one thing which will guarrantee convergence is that the ; derivative of the transform is 0 < d < 1 AFTER the point of ; convergence we're looking for, for example ; derivative of this transform is for SQUARE ROOT is: ; transf: y -> x/y ; deriv: -(x/y^2), which for y>=sqrt(x) will give us a number: ; -1 <= N <= 0, so we can't guarrantee divergence. ; when we average damp, the deriv becomes: ; ( -(x/y^2) + 1 ) / 2, now it lands between 0 and 1. ; for cube root, transform is y->x/y^2, deriv is: ; -2(x/y^3), this lands in the range -2 < d < 0 ; if we damp it once, we get the range -0.5 < d < 0.5, so we ; need to damp again to get the range 0.25 < d < 0.75 ; in general for calculating the nth-root, we need the ; transform y -> x/y^(n-1), which will have the derivative: ; -(n-1)(x/y^n), the derivative will for y>(nth-root x) ; fall in the range -(n-1) < d < 0. ; Note that when we average damp the function, this range ; becomes -((n-1+1)/2) = -n/2 < d < 0.5, then ; ((-n/2)+1) / 2 < d < 0.75 ; when we play around we see that for n-1 = 1, we only need ; one damp, for n-1 = 2 or 3 we need two damps ; for n-1 = 4 or 5 or 6 or 7, we need three, in general ; for n >= 2, we need ceil(log2(n)), average damps ; again, note, we might actually need fewer damps, this is ; just and upper-bound, however, luckily, we can never ; over-damp with this function when coming from the right ; because the upper bound for the derivative values will ; always be 0.5,0.75,0.875,.... < 1. ; so with enought damping we can always get a range of derivs ; in 0 < d < 1. (define (log2 x) (/ (log x) (log 2))) (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)) (define (identity x) x) (define (compose f g) (lambda (x) (f (g x)))) (define (repeated f n) (if (= n 0) identity (compose f (repeated f (- n 1))))) (define (average a b) (/ (+ a b) 2)) (define (average-damp f) (lambda (x) (average x (f x)))) ; returns a procedure (define (nth-root n) (let* ((damp-number (ceiling (log2 n))) (damps (repeated average-damp damp-number))) (lambda (x) (fixed-point (damps (lambda (y) (/ x (expt y (- n 1))))) (exact->inexact x)))))