Advertisement
Guest User

Untitled

a guest
Jan 28th, 2017
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (* Ciaran Dunne
  2.    Newton's method in SML, for polynomials.
  3.  
  4.    In Newton's method, whilst being more efficient, is more difficult as it
  5.    contains the problem of differentating the function f
  6.  
  7.    To avoid some hefty lexical analysis of functions (to split them up           into terms, then differentiate based on specific rules), we will use polynomials, and our notation of them will be in the form of a list of coefficients. For example:
  8.  [1.0, 2.0, 3.0] <=> 1 + 2x + 3x^2  
  9.  
  10.  First, we create a function /poly/ to create an actual function for our list of
  11.  coefficients, that we can input a value in and get the corresponding value for
  12.  f(x). *)
  13.  
  14. fun poly [] x = 0.0
  15.   | poly (hd::tl) x = hd + x*(poly tl x);
  16.  
  17. (* For efficiency and to avoid using powers of x, I have used
  18.    Horner's method to write the polynomial. So:
  19.    1 + 2x + 3x^2 = 1 + x(2 + x(3))
  20.                      
  21.    If polynomials exists solely as a list of coefficients,
  22.    then to differentiate, we must multiply each element in the list by it's
  23.    corresponding x's power, then shift the list along by one.
  24.  
  25.    Why do we need the shift?
  26.    [1.0, 2.0, 3.0] => 1 + 2x + 3x^2
  27.    bad_diff [1.0, 2.0, 3.0] => [0.0, 2.0, 6.0] => 2x + 6x^2
  28.    Which is quite obviously not the differentiation of our original function. *)
  29.  
  30. fun diff L = let fun mult n [] = []
  31.                    | mult n (hd::tl) = (n*hd)::mult (n+1.0) tl
  32.                in tl (mult_elements 0.0 L) end;
  33.  
  34. (* Now finally to compose our Newton function.
  35.    We make three local declarations f is the function for L, f' the
  36.    differentiated function of f. x is defined recursively by the definition of
  37.    the newton method. *)
  38.  
  39. fun newton _ x0 0 = x0
  40.   | newton L x0 i = let val x  = newton L x0 (i-1)
  41.             val f  = poly L
  42.                 val f' = poly (diff L)
  43.             in x - (f x)/(f' x) end;  
  44.  
  45.  
  46. newton [~2.0, 0.0, 1.0] 1.6 4;
  47.  
  48. (* val it = 1.414213562 : real
  49.  
  50.    Lovely! It converges to a nice approximation of root 2 in just 4 iterations!
  51.    wowee! *)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement