[Math] User defined sine function in python using series expansion

computer sciencetaylor expansion

Applying a Maclaurin expansion to the sine function gives

$$\sin\left(x\right)=\frac{x}{1!}-\frac{x^{3}}{3!}+\frac{x^{5}}{5!}-\frac{x^{7}}{7!}\;+…+\sum_{n=1}^{\infty}\frac{\left(-1\right)^{n+1}}{\left(2n-1\right)!}x^{2n-1}$$

with the ratio between successive terms being

$$\frac{-x^{2}}{\left(2n-1\right)\left(2n-2\right)}$$

I've written a program to approximate the sine function using a fixed number of terms from the expansion, for example the first 10 terms.

Here is my code:

from numpy import *

def mac(x, nmax):
    sigma = x
    term = x
    n = 2
    while (n <= nmax):
        term *= -x**2 / ((2*n - 1) * (2*n - 2))
        sigma += term
        n += 1
    return sigma

file = open('task13.txt', 'w')
x = 0.0
xmax = 14.0
dx = 0.1
nmax = 10
file.write('nmax = ' + str(nmax) + '\n')
file.write('x' + '\t' + 'series expansion' + '\t' + 'sin(x)' + '\n')
while (x <= xmax):
    file.write(str(x) + '\t' + str(mac(x, nmax)) + '\t' + str(sin(x)) + '\n')
    x += dx

file.close()
exit()

Here is a plot of the data:

enter image description here

Why does the approximation rapidly deviate from the actual value of $\sin(x)$ ? Is it because of an error in the code or is there a better way of calculating $\sin(x)$ using a user defined function?

Best Answer

Your code is working fine - look how well it approximates the function for a few period. However, ultimately, you are plotting a polynomial function. You seem to be stopping at the coefficient of $x^{21}$, so your function calculates: $$f(x)=\frac{-x^{21}}{21!}+\text{lower coefficients.}$$ I omit the coefficients of $x^{19}$ and lower because, for large enough $x$, the value of $x^{21}$ will be far greater than every other term. Thus, the function must, if we zoom out, look like $-x^{21}$ - that is, it tends to $-\infty$ as $x$ grows and $+\infty$ as $x$ becomes negative. A polynomial can never be periodic.

Maclaurin series are good for approximating something locally, not globally. However, you can improve the function - in particular, you can use the following algorithm:

  • If $x$ is in $[-\pi,\pi]$, use the Maclaurin series; it will be pretty accurate in that range.

  • Otherwise, add a multiple of $2\pi$ to move $x$ into that range - since $\sin$ is supposed to periodic, we can shift $x$ in that way.

This will make your function work pretty well. You could also use the symmetry that $\sin(x)=\sin(\pi-x)$ to only use the series in $[-\frac{\pi}2,\frac{\pi}2]$, where the series is even more accurate. You could even use double-angle identities and the like to further restrict the range you need the series in (though this becomes less efficient the more you do it, and may not be numerically stable) - the point being that the series is a good local approximation, but if you want it to work on a more global scale, you need to restrict the range in which the series is actually being used.

Related Question