Programming Praxis – Interval Arithmetic

In today’s Programming Praxis exercise, our goal is to implement some functions to do interval arithmetic. Let’s get started, shall we?

The plus and minus functions are trivial.

plus :: (Num a, Num b) => (a, b) -> (a, b) -> (a, b)
plus (a,b) (c,d) = (a+c, b+d)

minus :: (Num a, Num b) => (a, b) -> (b, a) -> (a, b)
minus (a,b) (c,d) = (a-d, b-c)

As Chun Kin Lee pointed out, my initial attempt at removing duplication doesn’t work for ranges with negative numbers, so I had to go back to way mentioned in the original algorithm.

times :: (Num a, Ord a) => (a, a) -> (a, a) -> (a, a)
times (a,b) (c,d) = let x = [a*c,a*d,b*c,b*d] in (minimum x, maximum x)

divide :: (Fractional a, Ord a) => (a, a) -> (a, a) -> (a, a)
divide (a,b) (c,d) = if c < 0 && d > 0 then error "divide by 0"
    else let x = [a/c,a/d,b/c,b/d] in (minimum x, maximum x)

Converting between bounded and centered intervals is also trivial.

toCenter :: Fractional a => (a, a) -> (a, a)
toCenter (a,b) = ((a+b) / 2, (b-a) / 2)

fromCenter :: Num a => (a, a) -> (a, a)
fromCenter (a,b) = (a-b, a+b)

Some tests to see if everything is working properly:

main :: IO ()
main = do let x = (1,2)
              y = (3,4)
          print $ plus x y == (4,6)
          print $ minus x y == (-3,-1)
          print $ times x y == (3,8)
          print $ divide x y == (1/4,2/3)
          print $ divide x x == (1/2, 2)
          print $ toCenter x == (3/2,1/2)
          print $ fromCenter (3/2,1/2) == x

Everything seems to be working fine.

About these ads

Tags: , , , , , , ,

2 Responses to “Programming Praxis – Interval Arithmetic”

  1. LEE, Chun Kin Says:

    times (a,b) (c,d) = (min a b * min c d, max a b * max c d)

    It doesn’t work for negative numbers.
    For example, (times (-1, 10) (-10, 1)) should be (-100, 10), but your function returns (10, 10).

  2. Remco Niemeijer Says:

    Thanks for the bug report. I’ve updated the algorithm.

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: