newton-method-widget


Implementation of a Newton's Method for finding the roots of a function Widget Factory

Created By Alexander Fairley

This is just a simple little widget factory to produce objects which find the zeroes of a function using newton's method. If you want to read about newton's method try:  http://mathworld.wolfram.com/NewtonsMethod.html My implementation just uses local linear approximations rather than full-fledged taylor polynomials.

Usage

(make-newton-method-approximator)

Takes the arguments <Starting Guess> <function> <derivative of function> <"optional string description of function"> Which will return a widget that responds to the following messages.

(widget 'info)

Which will return the current iteration, the starting guess and the function description.

(widget 'update)

Generates the next approximation and displays it. If you get stuck at a relative extremum, this lets you know it. Also stops calculating at a zero and let's you know. Should be pretty easy to add a machine readable version of this if you want one.

(widget 'reset)

Returns a function of one parameter that will reset the widget to a use a new starting guess.

Example Usage

Here's a sample widget you can play with as long as you have trig functions and PI defined Uncomment and stick at the end of the file...

 (define (fprime x) (- (cos x) (/ 1.0 5.0))) 
 (define (f x) (- (sin x) (/ x 5.0))) 
 (define myApprox  
   (make-newton-method-approximator  (* (/ 3 4.0) PI) f fprime "Sin(x) - 0.2x")) 

Implementation

 (define (make-newton-method-approximator 
          x-naught func deriv . quoted-func) 
   (let ((iter 0)(current-approx x-naught)) 
      
     (define (Dispatch message) 
       (cond ((equal? message 'info) 
                  (display "Iteration      x-naught                  Function") 
              (newline) 
              (display iter) 
              (display "              ") 
              (display x-naught) 
              (display "                  ") 
              (if (not (null? quoted-func)) (display quoted-func)) 
              (newline)) 
             ((equal? message 'update) 
              (let ((deriv-cur (deriv current-approx)))  
                ;Calc this now for efficiency 
                (if (= 0 deriv-cur) 
                    (begin 
                      (display "Currently, f'(x) is equal to zero") 
                      (display "--We've reached a relative extremum.") 
                      (newline) 
                      (display "Try a new x-naught--" 
                              " (<this> 'reset new-value")) 
                    (begin 
                      (let ((func-cur (func current-approx))) 
                        (if (= 0 func-cur) 
                            (begin (Display "Reached a zero") (newline)) 
                            (begin 
                              (set! iter (+ iter 1)) 
                              (set! current-approx 
                                    (- current-approx  
                                       (/ (func current-approx) 
                                          deriv-cur)))))))) 
                    (Dispatch 'display))) 
             ((equal? message 'display) 
              (newline) 
              (display "Iteration ") 
              (display iter) 
              (newline) 
              (display "Current Approximation ") 
              (display current-approx) 
              (newline) 
              ) 
             ((equal? message 'reset) 
              (lambda (x) (set! current-approx x) (set! x-naught x) (set! iter 0))))) 
  
     Dispatch))