The Tip of The Iceberg: 1 Before You Start
The Tip of The Iceberg: 1 Before You Start
The Tip of The Iceberg: 1 Before You Start
Abstract
Because computers have finite memory, numerical errors must always be
taken into account when doing calculations, especially when working with
floating-point numbers [2]. In the first parts of this project we investigate
round-off errors and truncation errors using the Python programming
language, and we discuss how different implementation strategies affect
code efficiency and code clarity. In particular, we show how coding with
classes can simplify the implementation of numerical algorithms. Finally,
we highlight the power of available Python libraries to quickly visualize
and manipulate large data sets. To this end, we look at how ice melting
in Antarctica could affect sea level rise [1].
It probably goes without saying, but this command updates the conda package.
The rockhound library and cmocean library are not in the default channel so
you need to add conda-forge
conda create -n project1 python matplotlib numpy pandas rockhound cmocean pip spyder jupyter
Entering all the package names when creating the new environment forces conda
to check for dependencies, and makes sure that there are no conflicts. Do
Now you can do e.g. jupyter notebook and continue to work on the project.
Later you can add packages using conda install <package-name>.
pip or conda.
Always try conda install <package-name> first, even if you find on
the web that people have done pip install <package-name>. If conda
install fails you can try pip install.
import sys
sys.float_info
• Explain the meaning of the printed-out numbers using the IEEE Standard
for floating-point arithmetic.
Part 2.
• Derive the following values yourself: max, min, epsilon.
2
Part 3. In Python, typing 0.1+0.2 does not (typically) produce the same
output as 0.3.
• Why not?
Part 4.
• Should you use the ==-operator to test whether two floating-point numbers
are equal?
• Why / why not?
Vectorized functions.
Using NumPy arrays allows you to create vectorized functions; functions
that operate on a whole array at once, rather than looping over the elements
one-by-one inside a custom written loop.
The way vectorization works behind the scenes is still via loops (opti-
mized, pre-compiled C code), but as Python programmer you do not need
to worry about the details.
x = np.linspace(0, 1, 10)
fx = np.exp(-x) # apply f(t)=exp(-t) to each element in the array x
Notice the usage of np.exp instead of using the exponential function provided
in the built-in math library; this is an example of a universal function.
• What happens if you change x to be a list?
• If x is a list, how can you modify the second line above to calculate fx?
Tip: Use either a custom loop, or a list comprehension.
Part 2. As already hinted at, the NumPy library comes with a plethora of
useful features and functions. The code snippets below show some examples:
3
np.zeros(20)
np.ones(20)
vector = np.arange(5) + 1
2*vector
• How would you produce the same output using native Python lists?
Part 3. Frequently you will want to extract a subset of values from an array
based on some kind of criterion. For example, you might want to count the
number of non-zero numbers, or identify all values exceeding a certain threshold.
With NumPy, suchs tasks are easily achieved using boolean masking, e.g.:
• Why not?
Part 4. The function np.where can also be used to select elements from an
array.
4
np.where(array_of_numbers > 17)[0]
We will exploit this property of Python several times during this project.
5
Figure 1: A plot of f (x).
Part 3. Next, we are going to write a Python function that calculates the
numerical derivative of an arbitrary single-variable function f at a point x
using finite differences. If f only depends on x, this is extremely easy: we can
simply take f, x, and h (step-size) as input arguments to our derivative function.
Assuming it is called calc_derivative, it could work something like this:
6
def g(x):
"""
The function g(x) = sin(10x) * exp(-0.1x^2).
"""
return f(x, 0.1, 10.0)
Another possibility is to use the the args mechanism, which lets you pass
around a variable number of parameters to a function. An example of how this
works is:
Part 4.
• Write another Python function that calculates f 0 (x) with the central
difference method (see section 1.4 in [3]).
• Make a figure in which you plot the absolute error versus step size, h.
• Vary the step size logarithmically between 10−16 and 1.
• The figure should include one error curve for the forward difference method,
and another for the central difference methods.
Part 6.
• Comment on what you observe in the figure you made. When is the
numerical error smallest, and why? Is it what you expect from a theoretical
analysis using Taylor’s formula?
7
5 Exercise 3, Part II: FD with Classes
Implementing numerical algorithms with free functions, as we did in the previous
exercise, is perfectly fine, and you can complete MOD510 by only coding in this
way. However, experience has taught us that it is easy to introduce unnecessary
errors when using this approach. In many cases you are better off by also using
classes, and maybe object-oriented design. In this exercise, you will get some
practice in coding with classes. This knowledge will come in handy in later
projects, and in any case it is a good tool to have in your programming toolkit.
Previously, we worked with a function having two input parameters, a
and b. Implementing numerical algorithms using free functions was then simple.
However, in a more complicated situation there could be dozens, or even hundreds,
of parameters to keep track of. Most of these parameters might have fixed values,
but frequently you will want to re-run a model with slightly different parameters
than before. If you are not using classes, it is very easy to use the wrong
parameters. This is especially true when working in a Jupyter notebook, since
you might run code blocks in any order; if you forget to excute a cell that is
responsible for updating one of your variables, your subsqeuent calculations will
be wrong!
class WavePacket:
"""
A class representation of a wave packet-function.
"""
def __init__(self, a, b):
self.a = a
self.b = b
def f(self, x):
return np.sin(self.b*x)*np.exp(-self.a*x*x)
8
def plot(self, min=-10, max=10, dx=0.01):
"""
A simple plotting routine for plotting f(x) in some range.
"""
x = np.arange(min, max, dx)
y = self.f(x)
fig = plt.figure()
plt.plot(x, y)
plt.grid()
Besides the initialization method and a function that calculates f (x) from
equation (1), the class includes a simple plotting routine. A major difference
from before is the following: when our function f (x) is defined inside a class, we
do not have to pass around a and b as arguments to the function f. Instead, we
simply access a and b from inside the class itself (using the self-prefix).
Below is an example of how to use the class:
Although we had to write slightly more code, we hope you appreciate how
easy this makes running parallel simulations with different parameters!
Part 1.
• Add another function (instance method) to the class above called df_fe.
This function should return the forward difference approximation to the
derivative of the function f at a point x given as input. Include the step-size
h as input argument (i.e., from the outside the class).
• Add a second function, df_cd, which calculates the central difference
approximation.
Part 2.
• Make a third function inside the class that plots the absolute error versus
step size for the two finite difference approximations. Use step sizes in the
range from 10−16 to 1 (with logarithmic spacing).
Hint: You should re-use the first two functions when making the third one.
9
6 Exercise 4: A song of ice and fire?
There is currently a great deal of concern about global warming. Some critical
issues are whether we are more likely to observe extreme local temperatures,
increased frequencies of natural disasters like forest fires and droughts, and if
there are "tipping points" in the climate system that are, at least on the human
timescale, irreversible [4]. One particular question to ask is: How much ice is
likely to melt? And, what would be the consequence of ice melting for sea level
rise (SLR)?
Since most of the ice on Planet Earth is located in Antarctica, substantial
effort has been spent in mapping the ice and the bedrock of this continent.
Most of the data is freely available, and we can use them to investigate different
scenarios.
6.1 Theory
To calculate SLR, we need to know not only how thick the ice is, but also its
elevation above the bedrock. In this exercise you will see how we can use Python,
together with available data and libraries, to do quite advanced calculations.
Melting of an iceberg. Let us start by deriving a result that you may have
seen before. We shall consider an iceberg that is floating and which is not
impacted by any other forces than gravity. The total volume of ice in figure 2 is
disp disp
Vf + VH2O , where Vf is the ice volume floating above the sea, and VH2O is the
volume of displaced sea water (submerged ice). According to Newton’s 2nd law,
the total weight of ice is therefore
10
expression for the same weight is
W = ρw VHdisp
2O
g, (4)
where ρw is the density of the surrounding sea-water. As the ice melts, it must
be turned into an equal mass of liquid ice-water:
mice = mice water
ρice Vice = ρice water Vice water . (5)
By combining the above equations, we therefore get:
ρice water
VHdisp
2O
= Vice water . (6)
ρw
Therefore, the net contribution to SLR is captured by the volume change
disp ρice water
∆V ≡ Vice water − VH2 O = 1 − Vice water . (7)
ρw
If the melted ice has the same density as seawater, it follows that there is
no increase in sea level. On the other hand, if the density is lower than that of
seawater, there is a contribution. Typically, the melting of ice dilutes the salinity
of the ocean, which leads to a small increase in sea level [5].
11
For the bedmap2 dataset, the freeboard level can be computed from (figure 3)
ρw
h = −(surface − thickness) · −1 (9)
ρice
Note that this formula assumes that the bedrock is below sea-level.
Part 1. The code below is taken from the rockound library documentation:
bedmap = rh.fetch_bedmap2(datasets=["thickness","surface","bed"])
plt.figure(figsize=(8, 7))
ax = plt.subplot(111)
bedmap.surface.plot.pcolormesh(ax=ax,cmap=cmocean.cm.ice,
cbar_kwargs=dict(pad=0.01, aspect=30))
plt.title("Bedmap2 Antarctica")
plt.tight_layout()
plt.show()
This may take quite some time, so it is recommended that you do not execute
the cell generating the plot more often than you have to.
It is now possible to plot the values in the bed1d data array by simply typing
bed1d.surface.plot(x=’x2’)
12
Figure 3: Visualization of the ice thickness in Antarctica.
the data you are interested in. This can easily be done as in the following
example: surface_elevation_values = bed1d[’surface’].values.
• Explain what you see. Is the shape of the bedrock important for sea level
rise?
Part 3.
• Use the whole data set to estimate the total SLR if all the ice of Antarctica
melts.
13
Figure 4: (left) How to calculate the freeboard level. (right) Cross section plot
of Thwaites glacier.
1. Start by calculating, for each grid cell in the dataset, the height of ice that
can contribute to SLR.
2. Multiply the height with the area of each cell (1000 × 1000 meters) in order
to estimate the volume of ice.
Part 4.
• How can we use the bedmap data to improve decision making?
• What are some limitations in your estimated calculation of sea level rise?
14
official user guide, as well as cheat sheets with an overview of the most frequently
used commands.
Assuming that you have conda installed and available to you from the
terminal, typing the following command should report back the version number
of conda on your system:
conda --version
conda 4.10.3
conda list
As you might have guessed, we just created an environment with the name
MyExampleEnv, along the way installing version 3.9 of python.exe into it, as
well as several libraries we wish to use. This will require you to answer a query
on the command line, after which the installation should commence.
We can activate the environment as follows:
Additional packages can be installed later as needed, you just have to remember
to activate the environment first (if it has not been done already), e.g.:
You can verify that pandas and jupyter have been installed by again typing
conda list in the terminal.
Many packages will be possible to install exactly as above; or possibly
by adding a few additional steps. For example, the cmocean and rockhound.
packages can be installed as follows:
15
conda activate MyExampleEnv
conda install -c conda-forge cmocean
conda install rockhound --channel conda-forge
class WavePacket:
"""
An updated class representation of a wave packet-function.
"""
def __init__(self, a, b):
self.a = a
self.b = b
def __call__(self, x):
return np.sin(self.b*x)*np.exp(-self.a*x*x)
def plot(self, min=-10, max=10, dx=0.01):
"""
A simple plotting routine for plotting f(x) in some range.
"""
x = np.arange(min, max, dx)
y = self.__call__(x)
fig = plt.figure()
plt.plot(x, y)
plt.grid()
16
We have simply replaced the original function f with __call__. This allows
us to treat objects of the class WavePacket as if they are ordinary functions:
WP1 = WavePacket(0.1, 2)
WP1(1.0) # Evaluates the function at x=1.0
class WavePacket:
...
def __str__(self):
"""
:return: A string representation of the function
(NB: uses LaTeX).
"""
return f’sin({self.b}x)’ + r’$\cdot$’ \
+ f’exp(-{self.a}’+ r’$x^2$)’
17
• In some cases it may suffice to explain your work via comments in the
code itself, but other times you might want to include a more elaborate
explanation in terms of, e.g., mathematics and/or pseudocode.
• In general, it is a good habit to comment your code (though it can be
overdone).
• When working with approximate solutions to equations, it is very useful
to check your results against known exact (analytical) solutions, should
they be available.
• It is also a good test of a model implementation to study what happens at
known ’edge cases’.
• Any figures you include should be easily understandable. You should label
axes appropriately, and depending on the problem, include other legends
etc. Also, you should discuss your figures in the main text.
• It is always good if you can reflect a little bit around why you see what
you see.
References
[1] Peter Fretwell, Hamish D. Pritchard, David G. Vaughan, Jonathan L. Bam-
ber, Nicholas E. Barrand, R. Bell, C. Bianchi, RG Bingham, Donald D.
Blankenship, and G. Casassa. Bedmap2: Improved ice bed, surface and
thickness datasets for antarctica. The Cryosphere, 7(1):375–393, 2013.
[2] David Goldberg. What every computer scientist should know about floating-
point arithmetic. ACM computing surveys (CSUR), 23(1):5–48, 1991.
[3] Aksel Hiorth. Computational Engineering and Modeling.
https://github.com/ahiorth/CompEngineering, 2021.
[4] V. Masson-Delmotte, P. Zhai, A. Pirani, S. L. Connors, C. Pean, S. Berger,
N. Caud, Y. Chen, L. Goldfarb, M. I. Gomis, M. Huang, K. Leitzell, E. Lon-
noy, J. B. R. Matthews, T. K. Maycock, T. Waterfield, O. Yelekci, R. Yu,
and B. Zhou (eds.). Climate Change 2021: the Physical Science Basis.
Contribution of Working Group I to the Sixth Assessment Report of the
Intergovernmental Panel on Climate Change. Technical report, Cambridge
University Press. In Press., August 2021.
[5] Peter D. Noerdlinger and Kay R. Brower. The melting of floating ice raises
the ocean level. Geophysical Journal International, 170(1):145–150, 2007.
[6] Kristen M. Thyng, Chad A. Greene, Robert D. Hetland, Heather M. Zimmerle,
and Steven F. DiMarco. True colors of oceanography: Guidelines for effective
and accurate colormap selection. Oceanography, 29(3):9–13, 2016.
18