0

I have to implement the cosine function in python by using its Taylor series. I have to print its values and the absolute and relative errors for all the values in listt from below. Here is what I tried:

import math

def expression(x, k):
   return (-1)**k/(math.factorial(2*k))*(x**(2*k))
pi=math.pi
listt=[0, pi/6, pi/4, pi/3, pi/2, (2*pi)/3, (3*pi)/4, (5*pi)/6, pi]
sum=0
for x in listt:
   k=0
   relative_error=1
   while relative_error>10**(-15):
       sum+=expression(x, k)
       absolute_error=abs(math.cos(x)-sum)
       relative_error=absolute_error/abs(math.cos(x))
       k+=1
    print("%.20f"%x, '\t', "%.20f"%sum, '\t', "%.20f"%math.cos(x), '\t', "%.20f"%absolute_error, '\t', "%.20f"%relative_error )

This, however, produces a huge error. The cause is probably that I perform all those subtractions. However, I don't know how to avoid them. I ran into the same problem when computing e^x for negative x, but there I just computed e^(-x) if x was negative and I could then just write that e^x=1/e^(-x). Is there some similar trick here?
Also, note that my while is infinite, because the relative error is always huge.

Math Guy
  • 101
  • 1
  • 1
    You don’t specify what error you are getting. Can you edit your post and add the traceback? – AwesomeCronk Mar 13 '21 at 17:12
  • @AwesomeCronk By huge error I mean a huge computation error i.e. a huge error between my function and math.cos(x). – Math Guy Mar 13 '21 at 17:18
  • Bug apart, using the relative error might not be the best idea because the cosine goes through 0 and makes the relative error explode in this neighborhood. –  Mar 15 '21 at 13:41
  • @YvesDaoust Yes, when x=pi/2 the code just went nuts. I resorted to setting a number of iterations (something like 100) and using a for loop. I couldn't find a better approach. – Math Guy Mar 15 '21 at 21:35
  • 1
    It would be smarter to observe the magnitude of the errors as a function of the number of iterations (100 is complete overkill). –  Mar 16 '21 at 21:30

1 Answers1

2

Fatal error: You set sum=0 outside the loop over the test points. You need to reset it for every test point. This error could be easily avoided if you made the approximate cosine computation a separate function.


It is always a better idea to compute the terms of the series by multiplying with the quotient to the previous term. This avoids the computation of the factorial and all the difficulties that its growth may produce.

That said, the growth of terms is the same as those for the exponential series, so the largest term is where 2*k is about |x|. For the given points that should not be prohibitively large.

To be a little more precise, the error of a cosine partial sum is smaller than the next term, as the series is alternating. The term of degree 2*k for |x|<=4 has the approximate bound, using Stirling's formula for the factorial,

4^(4*k)/(4*k/e)^(4*k) = (e/k)^(4*k) < (3/k)^(4*k)

which for k=6 gives an upper bound of 2^(-24) ~ 10^(-7). Thus there should be no catastrophic errors for the test values.

See also Calculate maclaurin series for sin using C, Issue with program to approximate sin and cosine values, Sine calculation with Taylor series not working

Lutz Lehmann
  • 25,219
  • 2
  • 22
  • 51