# 07 Numbers and Errors: Sine Series Problem 

* *Computational Physics*: Ch 2.5


## Set up


Pull changes in PHY494-resources
```
cd ~/PHY494-resources
git pull
```
Copy the the problem notebook with the whole directory as your work dir:
```
cd
cp -r ~/PHY494-resources/07_numbers ~/PHY494
```
Work on the `07-problem-sine-series.ipynb` notebook:
```
~/PHY494
jupyter notebook
```

## Problem: Summing Series: sin(x)

Evaluate the $\sin$ function from its series representation
$$
\sin x = x - \frac{x^3}{3!} + \frac{x^5}{5!} - \frac{x^7}{7!} + \dots
$$

A naive algorithm is to sum the series up to the $N$th term:
$$
\sin x \approx \sum_{n=1}^N \frac{(-1)^{n-1} x^{2n-1}}{(2n - 1)!}
$$

Problems:

- How to decide when to stop summing?
- Division of large terms (overflows!)
- Powers and factorials are very expensive to compute.

Better approach: Build up series terms $a_n$ using previous term $a_{n-1}$ through a recursion:

\begin{align}
a_n &= a_{n-1} \times q_n\\
a_n &= \frac{(-1)^{n-1} x^{2n-1}}{(2n - 1)!} = \frac{(-1)^{n-2} x^{2n-3}}{(2n - 3)!} \frac{-x^2}{(2n - 1)(2n - 2)}\\
a_n & = a_{n-1} \frac{-x^2}{(2n - 1)(2n - 2)}
\end{align}

Accuracy of this approach? Not clear in absolute terms but we can make the assumption that the error is approximately the last term in the sum, $a_N$. Hence we can strive to make the relative error smaller than the machine precision
$$
\left| \frac{a_N}{\sum_{n=1}^N a_n} \right| < \epsilon_m
$$




```python
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
```


```python
def sin_series(x, eps=1e-16):
    """Calculate sin(x) to precision eps.
    
    Arguments
    ---------
    x : float
        argument of sin(x)
    eps : float, optional
        desired precision
        
    Returns
    -------
    func_value, N
    
    where func_value = sin(x) and N is the number
    of terms included in the approximation.
    """
    # ....
    # add your code here
    return sumN, n-1
```

Test the implementation against the "exact" numpy function `np.sin()`.

Report
1. `x`
2. maximum `n`
3. `sin_series(x)`
4. relative error `abs(sin_series(x) - sin(x))/abs(sin(x))`

Plot against `x` the quantities above and also `sin(x)`.
* `x` - `sin_series(x)`
* `x` - `sin(x)`
* `x` - max `n`
* `x` - relative error (semilogy plot!)

For a range of numbers look at `Xsmall` and `Xlarge`:


```python
Xsmall = np.pi*np.arange(-2, 2.05, 0.05)
Xlarge = np.pi*np.arange(-50, 50.05, 0.1)
```

Implementation of the test:


```python
def test_sin(x):
    y, nmax = sin_series(x)
    y0 = np.sin(x)
    delta = y - y0
    if y0 != 0:
        relative_error = delta/y0
    else:
        relative_error = 0
    # print(x, y, y0, delta, relative_error)
    #return x, y, y0, delta, relative_error
    return x, nmax, y, relative_error 
```


```python
def test_plot_sine(X, filename="sine_error.pdf"):
    results = np.array([test_sin(x) for x in X])
    
    fig = plt.figure(figsize=(8, 10))
    
    ax1 = fig.add_subplot(3,1,1)
    ax1.plot(results[:, 0], results[:, 2], 'k-', lw=1, label="series")
    ax1.plot(results[:, 0], np.sin(results[:, 0]), 'g--', lw=2, label="sin x")
    ax1.legend(loc="best")

    ax2 = fig.add_subplot(3,1,2)
    ax2.plot(results[:, 0], results[:, 1], label="max n")
    ax2.legend(loc="best")

    ax3 = fig.add_subplot(3,1,3)
    ax3.semilogy(results[:, 0], results[:, 3], label="rel.error")
    ax3.legend(loc="best")
    
    fig.suptitle("sine series approximation")
    
    fig.savefig(filename)
    print("saved to file {0}".format(filename))
```

Now test the two ranges of numbers and write to different files:


```python
test_plot_sine(Xsmall, filename="sine_error_Xsmall.pdf")
```


```python
# ...
```


```python

```

54c1f32466dfa4395eeae453833764af8dfd6785
ipynb
Jupyter Notebook
07_numbers/07-problem-sine-series.ipynb
nachrisman/PHY494
bac0dd5a7fe6f59f9e2ccaee56ebafcb7d97e2e7
CC-BY-4.0
07_numbers/07-problem-sine-series.ipynb
nachrisman/PHY494
bac0dd5a7fe6f59f9e2ccaee56ebafcb7d97e2e7
CC-BY-4.0
07_numbers/07-problem-sine-series.ipynb
nachrisman/PHY494
bac0dd5a7fe6f59f9e2ccaee56ebafcb7d97e2e7
CC-BY-4.0
Qwen/Qwen-72B
1. YES
2. YES