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 ]

Share this: Twitter

Facebook

Like this: Like Loading... Related

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