Reputation: 11
I am having a hard time using Machine Epsilon which is 2.220446049250313e-16,I then need to use abs error to determine if my abs value of my sine term is less than the Machine Epsilon.
Write a sine function using Taylor's Series to calculate the value of sin(x) where is the angle in radian. The angle must be between -(pi/2) and pi/2. Use Machine Epsilon to determine the number of terms that are required to calculate the value of sine.
I need to output the angle, my calculation of sine, the absolute error, and number of terms used. Here is what I have already:
def machineEpsilon(e):
e = 1.0
while(1.0 + e/2.0) > 1.0:
e = e/2.0
return e
def sine(x, n):
sign = 1
sine = 0.0
half_pi = math.pi/2
#converts anything greater than pi/2 to something in between -pi/2 and pi/2
while x > half_pi:
x -= half_pi
#converts anything less than -pi/2 to something in between -pi/2 and pi/2
while x < -(half_pi):
x += half_pi
if x > math.pi:
x -= math.pi
sign = -1
swap_sign = 1
#loops through taylor series for sine
for i in range(1, n * 2, 2):
sine += swap_sign * (x ** i) / math.factorial(i)
swap_sign *= -1
return sign * sine
def main():
numTerms = 0
pie = math.pi
angle1 = round(sine(-20, 50), 9)
abbsErr1 = (abs(angle1 - math.sin(-20)))
angle2 = round(sine((-pie), 10), 9)
abbsErr2 = abs(angle2 - math.sin(-pie))
angle3 = round(sine((-pie/2), 10), 9)
abbsErr3 = abs(angle3 - math.sin((-pie/2)))
angle4 = round(sine(-0.5, 10), 9)
abbsErr4 = abs(angle4 - math.sin(-0.05))
angle5 = round(sine(0.0000, 10), 9)
abbsErr5 = abs(angle5 - math.sin(0))
angle6 = round(sine(0.05, 10), 9)
abbsErr6 = abs(angle6 - math.sin(0.0500))
angle7 = round(sine(100, 5), 9)
abbsErr7 = abs(angle7 - math.sin(100))
print("\n")
print("Name: Name")
print("Machine epsilon = ", machineEpsilon(1))
print("{:<12} {:<15} {:<25} {:<3}".format('Angle(rad)', '(my sine)', 'AbsErr',
'# of Terms'))
print("{:<12} {:<15} {:<25} {:<3}".format('-20.0000', angle1, abbsErr1, numTerms))
#print(math.sin(-20))
print("{:<12} {:<15} {:<25} {:<3}".format('-3.1416', angle2, abbsErr2, numTerms))
#print(math.sin(-(pie)))
print("{:<12} {:<15} {:<25} {:<3}".format('-1.5708', angle3, abbsErr3, numTerms))
#print(math.sin(-(pie/2)))
print("{:<12} {:<15} {:<25} {:<3}".format('-0.5000', angle4, abbsErr4, numTerms))
#print(math.sin(-0.5))
print("{:<12} {:<15} {:<25} {:<3}".format('0.0000', angle5, abbsErr5, numTerms))
#print(math.sin(0))
print("{:<12} {:<15} {:<25} {:<3}".format('0.0500', angle6, abbsErr6, numTerms))
#print(math.sin(0.0500))
print("{:<12} {:<15} {:<25} {:<3}".format('100.0000', angle7, abbsErr7, numTerms))
#print(math.sin(100))
print("\n")
Upvotes: 1
Views: 389
Reputation: 114
Your sine function doesn't seem quite right - and it should also return the number of iterations required. I have taken your code and modified it to stop calculating when the current value of the series is the same as the previous one. (I also took the liberty of putting the values to calculate into an array and looping through them).
import math
def machineEpsilon(e):
e = 1.0
while(1.0 + e/2.0) > 1.0:
e = e/2.0
return e
def sine(x):
sign = 1
half_pi = math.pi/2
#converts everything into range 0..2*pi
while x >= 2*math.pi:
x -= 2*math.pi
while x < 0.0:
x += 2*math.pi
if x > math.pi:
x -= math.pi
sign = -1
swap_sign = 1
#loops through taylor series for sine
i = 1
sine = 0.0
oldsine = 1
iterations = 0
while sine!=oldsine:
oldsine = sine
sine += swap_sign * (x ** i) / math.factorial(i)
swap_sign *= -1
i += 2
iterations += 1
return (sign * sine, iterations) # value, number of iterations
def main():
print("\n")
print("Name: Name")
print("Machine epsilon = ", machineEpsilon(1))
print("{:<12} {:<22} {:<27} {:<3}".format('Angle(rad)', '(my sine)', 'AbsErr', '# of Terms'))
pie = math.pi
values = [-20,-pie,-pie/2,-0.5,0.0,0.05,100]
for v in values:
s,numTerms = sine(v)
abbsErr = abs(s - math.sin(v))
print("{:<12} {:<22} {:<27} {:<3}".format(round(v,9), s, abbsErr, numTerms))
print("\n")
if __name__=="__main__":
main()
Upvotes: 0