[Haskell-beginners] Mathematical Blundering

Andrew Sackville-West andrew at swclan.homelinux.org
Fri Oct 17 19:52:28 EDT 2008


On Thu, Oct 16, 2008 at 09:57:39AM +0100, Paul Johnston wrote:
> Bit of basic maths.
> You are using a power series to approximate sine
> This works by taking an expansion about a fixed point, usually zero.
> It only works well around that point.
> If you get far away it works badly.
> You need to exploit the cyclic nature of the trignometrical functions i.e.
> Sin x = sin ((2 * pi) + x) = sin ((4 * pi) + x)
> Essentially consider the shift in multiples of 2 * pi and calculate the value of x nearest to zero.
> 
> See
> http://en.wikipedia.org/wiki/Taylor_series
> The diagram on the top right is very instructive.

how appropriate. We're doing this in math right now ;)

ISTM that OP should take x modulo pi and (per the wiki diagram) a
seven term series to get a nice usable sine function. (and don't
forget to watch for the sign (nopun) of the result)

fact 1 = 1
fact x = x * (fact $ x - 1)

term n x = (-1)**n * (theta**(2*n + 1) / fact(2*n + 1))
    where theta = pi * ((x / pi) - xTrunc) * sign
          xTrunc = fromIntegral $ truncate (x/pi)
          sign = (-1)**xTrunc


sine x = sum $ take 7 [term n x | n<-[0..]]

Wow, that took me a lot longer to figure out because of all the mixing
of numeric types. The critical part was fromIntegral in the poorly
name xTrunc function. 

but it looks pretty accurate.

*Main> maximum [sine x - sin x | x<-[1..100]]
1.2652798913048713e-5

and it's easy to boost the accuracy by taking more terms in the
series.

taking 9:

*Main> maximum [sine x - sin x | x<-[1..100]]
1.1683279538265978e-8

taking 11:
*Main> maximum [sine x - sin x | x<-[1..100]]
4.694897248747054e-12


I'm sure there must be a better way to get x modulo pi, but I don't
know enough...

I'd love some feedback on my solution both from a math and a haskell perspective.

A


> 
> Paul
> 
> -----Original Message-----
> From: beginners-bounces at haskell.org [mailto:beginners-bounces at haskell.org] On Behalf Of Jeffrey Drake
> Sent: Thursday, October 16, 2008 9:47 AM
> To: Haskell Beginners
> Subject: [Haskell-beginners] Mathematical Blundering
> 
> 
> I have defined myself a set of functions to test:
> 
> fact 1 = 1
> fact n = n * (fact $ n - 1)
> 
> sine x = x - (x^3/(fact 3)) + (x^5/(fact 5)) - (x^7/(fact 7))
> 
> Where my code is 'sine' and the prelude's is sin:
> *Main> sine 1
> 0.841468253968254
> *Main> sin 1
> 0.8414709848078965
> 
> *Main> sine 2
> 0.9079365079365079
> *Main> sin 2
> 0.9092974268256817
> 
> *Main> sine 3
> 9.107142857142847e-2
> *Main> sin 3
> 0.1411200080598672
> 
> *Main> sine 4
> -1.3841269841269837
> *Main> sin 4
> -0.7568024953079282
> 
> After 2 they seem to diverge rather rapidly, and I am not sure why. Any ideas?
> 
> I would have thought that 4 terms would have been enough.
> 
> - Jeff.
> 
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
> 

-- 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
Url : http://www.haskell.org/pipermail/beginners/attachments/20081017/5147ce12/attachment.bin


More information about the Beginners mailing list