[haskell] add newton-raphson square root program

This commit is contained in:
Julin S 2023-08-18 17:23:57 +05:30
parent e7d8161acb
commit 54d91dc6cf
1 changed files with 58 additions and 0 deletions

58
haskell/newton-raphson.hs Normal file
View File

@ -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
-}