Programming Praxis – Calculating Logarithms

In today’s Programming Praxis problem we have to implement Euler’s method for calculating logarithms (using Newton’s method for calculating square roots). Let’s get started.

First we define our desired accuracy.

eps :: Double
eps = 1e-7

Newton’s method is just repeating the same function until it’s close enough.

sqrt' :: Double -> Double
sqrt' n = head . filter (\x -> abs (x^2 - n) < eps) $
    iterate (\x -> x - (x^2 - n) / (2*x)) 1

In Euler’s algorithm we first find the smallest power of the base higher than n, and then keep calculating the geometric mean between the low and the high number, repeating for whichever of the two resulting intervals holds n until we’re close enough.

log' :: Double -> Double -> Double
log' b n = f 0 0 where
    f lo hi | b ** hi < n             = f lo (hi + 1)
            | abs (lo / hi - 1) < eps = arit
            | geom < n                = f arit hi
            | otherwise               = f lo arit
            where geom = sqrt' (b ** lo * b ** hi)
                  arit = (lo + hi) / 2

A quick test shows that everything is working correctly:

main = do print $ sqrt' 2
          print $ log' 10 612
About these ads

Tags: , , , , , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

Join 35 other followers

%d bloggers like this: