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]

### Like this:

Like Loading...

*Related*

Tags: bonsai, code, Haskell, kata, praxis, programming, recursive, sine, taylor

This entry was posted on January 12, 2010 at 7:25 pm and is filed under Programming Praxis. You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.

## Leave a Reply