
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@haskell.org [mailto:beginners-bounces@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@haskell.org http://www.haskell.org/mailman/listinfo/beginners _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
--