Programming Praxis – Calculating Sines

In today’s Programming Praxis exercise we have to implement two ways of calculating sines. Let’s get started.

A quick import:

import Data.Fixed

The only real trick we use for the Taylor sine function is to not calculate the factorial for each number, but to keep reusing the previous result so that each new entry only requires two multiplications instead of n.

taylorSin :: Double -> Double
taylorSin x = sum . useful $ zipWith (/)
    (map (\k -> (mod' x (2*pi)) ** (2*k + 1) * (-1) ** k) [0..])
    (scanl (\a k -> a * k * (k - 1)) 1 [3,5..]) where
    useful ~(a:b:c) = a : if abs (a-b) > 1e-7 then useful (b:c) else []

For the recursive solution we use the fact that lim(x -> 0) sin x = x

recSin :: Double -> Double
recSin = f . flip mod' (2 * pi) where
    f x = if abs x < 1e-7 then x else
          let s = f (x / 3) in 3 * s - 4 * s**3

A quick test shows that everything is working correctly.

main = do mapM_ (print . taylorSin) [1, pi / 2, 10]
          mapM_ (print . recSin)    [1, pi / 2, 10]
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: