Reputation: 17
I have to define a function for calculating sin()
, and the program will expand the series until the absolute value of the next term in the series is less than 1.0e-7
using this expression:
This is what I got so far but I know it's way off:
number = input("\n\tEnter X: ")
x_flt = float(number)
x_int = int(x_flt)
x_approx = 0
for i in range(1, x_int+1):
factor = x_flt * i
def approximate_sin(x):
'''Insert docstring here.'''
for a in range():
x_approx = (-1 ** a * x ** (2 * a + 1)) / factor
return x_approx
print("\n\tApproximation: {:.10f}".format(float(approximate_sin(x_flt))))
Upvotes: 1
Views: 1975
Reputation: 3565
Given this is an infinite series, you could create a generator that given x provides the next evaluation by incrementing n each time.
from math import factorial, pow
def sin_gen(x):
n = 0
while True:
result = (pow(-1, n) * pow(x, (2 * n + 1))) / factorial(2 * n + 1)
yield result
n += 1
Now you just need to sum each evaluation until the total is as you want.
g = sin_gen(x)
total = 0
for val in g:
if abs(val) < 1.0e-7:
break
total += val
print(total)
Upvotes: 2
Reputation: 51132
Here's how I would do it, which uses the formula but not directly.
(-1) ** n
is the previous value multiplied by -1
.x ** (2n + 1)
is the previous value multiplied by x * x
.(2n + 1)!
is the previous value multiplied by 2n * (2n + 1)
.This means your loop does no power or factorial calculations, which is a bit more efficient. Here it is in Python:
def approx_sin(x, eps=1e-7):
term = x
two_n = 0
total = 0
while abs(term) >= eps:
total += term
two_n += 2
term *= -x * x / (two_n * (two_n + 1))
return total
Upvotes: 2
Reputation: 61042
Be careful of -1 ** n
, it isn't parsed as you would expect. **
binds more tightly than unary -
(has higher precedence) so this expression is parsed like -(1 ** n)
. Similar to blueteeths solution, I would do something like
from math import factorial, pow
from itertools import takewhile, count
large = lambda y: abs(y) > 1e-7
def sin_gen(x):
for n in count():
yield (pow(-1, n) * pow(x, (2 * n + 1))) / factorial(2 * n + 1)
def sin(x):
return sum(takewhile(large, sin_gen(x)))
print(sin(5)) # -0.9589242932128198
Upvotes: 3
Reputation: 226604
Hints:
+=
instead of =
.Upvotes: 1