12 KiB
CDS: Numerical Methods Assignments¶
See lecture notes and documentation on Brightspace for Python and Jupyter basics. If you are stuck, try to google or get in touch via Discord.
Solutions must be submitted via the Jupyter Hub.
Make sure you fill in any place that says
YOUR CODE HEREor "YOUR ANSWER HERE".
Submission¶
- Name all team members in the the cell below
- make sure everything runs as expected
- restart the kernel (in the menubar, select Kernel$\rightarrow$Restart)
- run all cells (in the menubar, select Cell$\rightarrow$Run All)
- Check all outputs (Out[*]) for errors and resolve them if necessary
- submit your solutions in time (before the deadline)
Rounding and Truncation Error Analysis¶
Euler's number $e$ can be represented as the infinite series $e = \sum_{n=0}^{\infty} \frac{1}{n!}$. In order to evaluate it in Python we need to truncate the series. Furthermore, we learned that every number representation and floating-point operation introduces a finite error. Thus, let's analyze the truncated series
$$\tilde{e} = \sum_{n=0}^{N} \frac{1}{n!}$$in more detail.
# Import packages here ... # YOUR CODE HERE raise NotImplementedError()
Task 1¶
Calculate $\tilde{e}$ with Python and plot the relative error $ \delta = \left| \frac{\tilde{e} - e}{e} \right|$ as a function of $N$ (use a log-scale for the $y$ axis).
def getEuler(N): """Don't forget to write a docstring ... """ # YOUR CODE HERE raise NotImplementedError() def getEulerErr(eApprox): """Don't forget to write a docstring ... """ # YOUR CODE HERE raise NotImplementedError()
# do your plotting here ... # YOUR CODE HERE raise NotImplementedError()
"""Check that getEuler and getEulerErr return the correct output for several inputs""" assert np.allclose(getEuler(0), 1) assert np.allclose(getEuler(1), 2) assert np.allclose(getEuler(2), 2.5) assert np.allclose(getEuler(10), np.e) assert np.allclose(getEulerErr(0), 1, rtol=1e-16) assert np.allclose(getEulerErr(np.e), 0)
Task 2¶
Compare the relative errors $\delta$ for different floating point precisions as a function of $N$. To this end, we define each element of the series $e_n = \frac{1}{n!}$ and convert it to double-precision (64 bit) and single-precision (32 bit) floating points before adding them up. This can be done by using Numpy's functions $\text{numpy.float64(e_n)}$ and $\text{numpy.float32(e_n)}$, respectively.
def getEulerSinglePrecision(N): # YOUR CODE HERE raise NotImplementedError() def getEulerDoublePrecision(N): # YOUR CODE HERE raise NotImplementedError()
# do your plotting here ... # YOUR CODE HERE raise NotImplementedError()
"""Check that getEulerSinglePrecision and getEulerDoublePrecision return the correct output for several inputs""" assert np.allclose(getEulerSinglePrecision(0), 1) assert np.allclose(getEulerSinglePrecision(1), 2) assert np.allclose(getEulerSinglePrecision(2), 2.5) assert np.allclose(getEulerSinglePrecision(10), np.e) assert np.allclose(getEulerDoublePrecision(0), 1) assert np.allclose(getEulerDoublePrecision(1), 2) assert np.allclose(getEulerDoublePrecision(2), 2.5) assert np.allclose(getEulerDoublePrecision(10), np.e) eeAppr_32bit = getEulerSinglePrecision(50) eeAppr_64bit = getEulerDoublePrecision(50) assert getEulerErr(eeAppr_32bit) > getEulerErr(eeAppr_64bit)
Task 3¶
Compare the relative errors $\delta$ for different rounding accuracies as a function of $N$. Use Python's $\text{round(e_n, d)}$ function, where $d$ is the number of returned digits, to round each $e_n$ element before adding them up. Plot $\delta$ vs. $N$ for $d = 1,2,3,4,5$ and add a corresponding legend.
def getEulerRounding(N, d): # YOUR CODE HERE raise NotImplementedError()
# do your plotting here # YOUR CODE HERE raise NotImplementedError()
"""Check that getEulerRounding returns the correct output for several inputs""" assert np.allclose(getEulerRounding(0,3), 1) assert np.allclose(getEulerRounding(1,5), 2) assert np.allclose(getEulerRounding(2,6), 2.5) assert np.allclose(getEulerRounding(10,2), np.e, rtol=1e-3) assert np.allclose(getEulerRounding(10,6), np.e, rtol=1e-5) eeAppr_4d = getEulerRounding(50, 4) eeAppr_8d = getEulerRounding(50, 8) assert getEulerErr(eeAppr_4d) > getEulerErr(eeAppr_8d)
Some examples¶
import numpy as np # using float32 a = 0.1234 b = np.float32(a) # using round c = round(a, 2)