[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