Calculate sine by Taylor series expansion

Asked

Viewed 2,037 times

-2

Write a program that calculates an approximation for the sine according to the equation below:

seno(x) = x - x^3/3! + x^5/5! - x^7/7! + ... + x^n/n!

Whereas x and n are integer numbers informed by the user. If n for par the program must report "invalid n".

I managed to write that:

x=int(input(">"))
n=int(input(">"))
fat=1
n00=1
n0=1
n01=1
d=0
s=0

if n%2==0:
    print("n inválido")
else:
    while n0<=n:
        while n01<=n0:
            fat=fat*n01
            n01=n01+1
        d=(x**n0)/fat
        s=d-s
        n0=n0+2
    print(s)

The calculation works, but in module. I know there are simpler ways, but I’d like to fix it without much change.

  • The names of their variables are not intuitive at all. I could describe what each one is and what their function is in the code?

  • x and n are the variables of the equation, fat is factorial, d to calculate each fraction individually, and sine s will receive everything, the problem is this, because the results work, but in module

1 answer

5

I really could not understand your code, I found quite confusing the names of the variables, making it very difficult to understand what is each thing within the code.

If you notice, the given sequence is the calculation of the sine function from the expansion by the Taylor series, given by the form:

inserir a descrição da imagem aqui

Obviously computationally it will be impossible (or impractical) to sum infinite terms, so we take a finite amount that is sufficiently close to the desired result. This amount shall be denoted by n:

inserir a descrição da imagem aqui

The value within the sum is what we call the general term of the series and only depends on x and i, then we can define it in Python:

from math import factorial

def termo_geral(x, i):
    return ((-1)**i / factorial(2*i+1)) * (x**(2*i+1))

However, we must calculate the value from the general term for each value of i from 0 to n-1, then we can assemble the sequence:

def termos(x, n):
    for i in range(n):
        yield termo_geral(x, i)

And finally, the sine calculation will be the sum of all the terms of the series:

seno = sum(termos(x, n))

So we can generalize the calculation to just one function:

from math import factorial, radians

def seno(x, n=7):
    x = radians(x)

    def termo_geral(x, i):
        return ((-1)**i / factorial(2*i+1)) * (x**(2*i+1))

    def termos(x, n):
        for i in range(n):
            yield termo_geral(x, i)

    return sum(termos(x, n))

The function input should be the angle in degrees, just do seno(30) to obtain the sine of 30°. A test that the code correctly calculates the series is shown below, where the calculated value is compared by the defined function and by the package’s native function math with an error less than 0.00001:

from math import radians, isclose, sin

for angle in {0, 30, 45, 60, 90, 120, 180, 230, 270, 320, 360}:
    assert isclose(
        seno(angle, 21), 
        sin(radians(angle)), 
        abs_tol=1e-5
    )

See working on Repl.it | Ideone | Github GIST

The absence of exit indicates that all asserts passed by.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.