(* Newton-Raphson function from Kennedy (p. 11).
*)
;
(* This file does not compile as unrefined SML.
The "let val dx = f x / f' x" in the body of `newton' will cause SML
to infer `int' instead of `real' (because its operator overloading is
pastede on yay). The fix under SML is simpler than a full signature
type: change (f, f', x, xacc) to (f : real -> real, f', x, xacc), but
Stardust doesn't support that syntax -- and even if it did, it would
inject `real -> real' to `real(NODIM) -> real(NODIM)'!
*)
(*[ val newton : -all d1,d2:dim-
(* f, a function *) (real(d1) -> real(d2))
(* f', its derivative *) * (real(d1) -> real((d1 ^ ~1) * d2))
(* x, the initial guess *) * real(d1)
(* xacc, relative accuracy *) * real
-> real(d1)
]*)
fun newton (f, f', x, xacc) =
let val dx = f x / f' x
val x' = x - dx
in
if abs dx / x' < xacc
then x'
else newton (f, f', x', xacc)
end