From 54d91dc6cf58e3289b8d62c1d549bfb6fe51a1ea Mon Sep 17 00:00:00 2001 From: Julin S Date: Fri, 18 Aug 2023 17:23:57 +0530 Subject: [PATCH] [haskell] add newton-raphson square root program --- haskell/newton-raphson.hs | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 haskell/newton-raphson.hs diff --git a/haskell/newton-raphson.hs b/haskell/newton-raphson.hs new file mode 100644 index 0000000..7fd2f1c --- /dev/null +++ b/haskell/newton-raphson.hs @@ -0,0 +1,58 @@ +-- | Newton-Raphson algorithm to approximate square root of a number +-- From 'Why functional programming matter' (1989) by John Hughes + +{- +rtᵢ₊₁ = [ rtᵢ + n/rtᵢ] / 2 +-} + +-- | Given an approximation, find a better one +next + -- :: (Num a, Ord a, Fractional a) + :: Fractional a + => a -- ^ Number whose square root is to be found + -> a -- ^ Old approximation of square root + -> a -- ^ New approximation of square root +next n rt = (rt + (n/rt))/2 + +-- | Starting from initial guess, keep finding better approximations +rts + :: Fractional a + => a -- ^ Number whose square root is to be found + -> a -- ^ Initial guess of square root + -> [a] -- ^ List of approximations that keeps getting better +rts n rt0 = rt0 : rts n (next n rt0) + +-- | Given a series of approximations, stop when error goes below `eps' +within + :: (Ord a, Fractional a) + => a -- ^ Error tolerance + -> [a] -- ^ List of ascending values + -> a -- ^ Value when error is toleratable +within eps l = case l of + a0 : a1 : l' -> + if a1-a0 < eps then a1 + else within eps (a1:l') + +nrSqrt + :: Float -- ^ Number whose square root is to be found + -> Float -- ^ Initial guess of square root + -> Float -- ^ Error tolerance + -> Float -- ^ Square root value +nrSqrt n rt0 eps = within eps $ rts n rt0 + + +{- +λ> sqrt 2 +1.4142135623730951 + +λ> nrSqrt 2 1.5 0.0001 +1.4166666666666665 +λ> nrSqrt 2 1.5 0.000001 +1.4166666666666665 + +λ> sqrt 3 +1.7320508075688772 + +λ> nrSqrt 3 2 0.0001 +1.75 +-}