Sunteți pe pagina 1din 94

LAB

ONE

MATLAB the Calculator


1.1 Introduction
Programming is a powerful tool for every scientist, and in an era of data driven science and computational thinking,
being able to solve problems using computational methods is more important that ever.
Some people find programming fun and exciting straight away. Others find it a bit intimidating, and find that
it requires a new way of thinking. Whichever category youre in, the best way of learning and improving is by
actually writing code. You cant learn Computational Physics by reading notes you have to write code, run
code, and experiment.
MATLAB is a great language for beginners but at the same time is a sophisticated programming environment that
is widely used in physics and engineering. In its simplest form, you can think of MATLAB as an extremely good
(and fast) calculator, and thats how were going to start in the first lab session.
MATLAB has excellent built in documentation, so it is easy to look up how to use a particular function if you
cant remember. For example, to get help on the plot function you can run:
1 >> help plot

and the results will look something like this:

MATLAB behaves in the same way whether you run it on Windows, Mac OS X or Linux, so you can practice in
the Access labs or at home, and the code you write will run on the lab computers as well.

1.2 Lab objectives


The aim of this lab is to familiarise yourself with basic mathematical functionality and plotting in MATLAB. By
the end of this lab session you should be able to:

1. Understand what MATLAB is and run the MATLAB interpreter.


2. Perform elementary operations.
3. Calculate expressions using variables.
4. Visualize simple datasets using plot().

If you dont know how to do any of these things once you have completed the lab, please ask your tutor for help.
You should also use these lists of objectives when you are revising for the end of semester exam.
1.3 Walkthrough: Doing maths with MATLAB
1.3.1 Getting started
The main window in the MATLAB interpreter contains the command prompt >> which is where you type com-
mands. MATLAB runs each command you type and displays the result on the screen. You can think of MATLAB
as an extremely powerful calculator. Lets try out some basic commands:
1 >> 1 + 3*5 % you type this
2 ans = 16 % the computer responds

The order of operations is the same as in a regular scientific calculator: multiplication () and division (/) are
evaluated before addition (+) and subtraction ( ). You can use parenthesis to control the order of operations:
1 >> (1 + 3)*5
2 ans = 20

Multiplication and division are evaluated from left to right, so:


1 >> 3*4/6*2
2 ans = 4

gives an answer of 4, not 1 as many people expect. To calculate powers you can use the caret symbol:
1 >> 210
2 ans = 1024

There are a wide range of standard mathematical functions, such as sin, mod, exp, and log. For example:
1 >> cos(2*pi)
2 ans = 1

Note that the variables pi, e and i are built-in: MATLAB already knows the values of these constants:
1 >> pi*2
2 ans = 6.2832

See Section ?? for a list of useful mathematical functions. By default, trigonometric functions like sin take input
in radians not degrees.

1.3.2 MATLAB variables


To write any useful program we need to store information in variables. A variable is a name given to a chunk of
memory that contains a value. Variables allow you to save your results and use them later in the program. Like
mathematical variables, they can be manipulated and operated on. We define variables using the = sign:
1 >> x = 1
2 x = 1

In English, this statement means: set the value of x equal to 1. We can now do basic arithmetic with x:
1 >> y = x + 2
2 y = 3
3 >> y / 2
4 ans = 1.500

The variable ans is the default variable name that MATLAB uses if you dont specify a variable in the interpreter.
You can suppress the displaying of the answer using a semi-colon at the end of each line. Compare the following
two lines of code (note the semi-colon):
1 >> z = x - 5
2 z = -4
3 >> z = x - 5;

In both cases z has the value -4, but this is only displayed on the screen in the first case.

2
If you set a variable to a new value, it replaces the value previously held in that variable:
1 >> x = 100;

So x now has the value 100, not 1 that we assigned to it earlier.


In physics we usually write numbers in scientific notation; for example the speed of light is often written as
c = 2.998 108 ms 1 . To do this in MATLAB you can use the notation e8 to represent 108 . For example:
1 >> c = 2.998e8
2 c = 299800000

1.3.3 Scalars and Vectors


The power of computational science is in its application of multiple operations to large collections of numbers.
MATLAB can store collections of numbers using n-dimensional vectors, also known as arrays. We can define a
row or column vector in MATLAB as shown below:
1 >> a = [5 7 2] % row vector
2 a = 5 7 2

When you define a column vector, the semicolon represents a new line:
1 >> b = [5; 7; 2] % column vector
2 b = 5
3 7
4 2

We can access each element in a vector using its index (position in the vector). For example:
1 >> a = [100 22 pi];
2 >> a(1)
3 ans = 100

MATLAB vectors and arrays are indexed from 1, not from 0 as in some other languages. The first element of this
vector is given by a(1) and the last element of this vector is a(3). Alternatively, we can use the built-in variable
called end to access the last element:
1 >> a(end)
2 a = 3.1416

Although MATLAB knows the value of to much greater accuracy, only 4 decimal places are displayed by default.
To show more, you can change the format :
1 >> format long
2 >> a(end)
3 a = 3.141592653589793

To get back to the default format setting type format short;.


MATLAB vectors are a core part of the language, and so we can perform addition and subtraction on them just as
we can with scalars (individual numbers):
1 >> a = [2 4 6];
2 >> b = [1 2 2];
3 >> c = a + b
4 c = 3 6 8
5 >> d = a - b
6 d = 1 2 4

These operations work on the vectors one element at a time, provided the vectors have the same dimensions. If
they dont, MATLAB will return an error:
1 >> a = [2 4 6];
2 >> c = [3; 3; 3]
3 c = 3

3
4 3
5 3
6 >> a - c
7 ??? Error using ==> minus
8 Matrix dimensions must agree

In this case we have tried to subtract a column vector (3 1) from a row vector (1 3) which isnt possible.
Multiplication and division are slightly more tricky. By default MATLAB assumes everything is a matrix, and so
it tries to do matrix multiplication when given two vectors:
1 >> a = [2 4 6];
2 >> b = [3; 3; 3];
3 >> c = a * b
4 c = 36

Note that the vectors must have the right dimensions for this to work in this case a row vector (1 3) and a
column vector (3 1) resulted in a (1 1) matrix. Well do more on matrix multiplication in later weeks.
If we want to do element-by-element multiplication or division we have to use the dot version of the * or /
operator, and the vectors must be of the correct dimensions:
1 >> a = [2 4 6];
2 >> b = [1 2 2];
3 >> c = a .* b
4 c = 2 8 12

If we want to add a scalar to every element in a vector we can do:


1 >> a = [7 5 1];
2 >> b = a + 10
3 b = 17 15 11

To divide a scalar by a vector, we have to use element-wise division (note the dot):
1 >> a = [2 5 -10];
2 >> b = 1./a
3 b = 0.5000 0.2000 -0.1000

1.3.4 Naming variables


One way of making your code easier to understand is to name your variables in a meaningful, but concise, way.
For example, if we we want to calculate the velocity, given a car travelled 10 km in 15 minutes, we could do:
1 >> dist = 10; % km
2 >> time = 15/60.0; % hr
3 >> vel = dist/time

MATLAB (and most other programming languages) doesnt keep track of the units. If you want to make a note of
what units your variables are in, you can add a comment using the percent symbol, as we have done above (% km).
Another sensible choice of variable names for this example might be:
1 >> s = 10; % km
2 >> t = 15/60.0; % hr
3 >> v = s/t

as these are the standard symbols you probably used in high school. Choosing random names makes your code
difficult to understand. For example:
1 >> cat = 10;
2 >> dog = 15/60.0;
3 >> pig = cat/dog

This code will give the correct answer, but people reading it (including yourself) will have no idea what it means!
You can go too far in the other direction though. If you try to include a full description of each value your code

4
will also be difficult to read (and youll have to do a lot of extra typing). For example:
1 >> distance_travelled_in_km = 10;
2 >> time_taken_in_hours = 15/60.0;
3 >> velocity_of_car = distance_travelled_in_km/time_taken_in_hours

Good coding is about finding a balance between these extremes.


Finally, you should avoid giving your variables names that conflict with well known physical constants, or other
standard symbols like pi, e and i. For example, calling your velocity c would be confusing because c usually
refers to the speed of light in a vacuum.

1.4 Exercises
Question 1
Given the two vectors a and b below:
1 a = [4 8 12 16 20];
2 b = [2 4 2 4 2];

Write MATLAB code to


1. Subtract each element of b from the corresponding element of a.

2. Multiply each element of a by 7.


3. Add the first element of a to the last element of b.
4. Divide every element of a by 2.

5. Divide each element of a by the corresponding element of b.


Write your code in the box below.

1 a- b
2 a*7
3 a(1) + b(end)
4 a/2
5 a./b

5
Question 2
The speed of light in a transparent medium is given by v = nc where c is the speed of light in a vacuum (c =
2.9979 108 ms 1 ) and n is the refractive index of the medium.
Two friends separated by 1000 km signal to each other using an extremely powerful torch. Use MATLAB as a
calculator to work out how long the signal will take to arrive if the space between them is filled entirely by cold
air (n = 1.000293 at 0 C and 1 atm).

1 >> c = 2.9979e8;
2 >> dist = 1000 * 1000;
3 >> n_air = 1.000293;
4 >> v_air = c/n_air;
5 >> time = dist/v_air
The signal will take 3.34 milliseconds to arrive.
Tutor note: Encourage students to use variables, rather than just magic numbers.

Question 3
Work out how long the signal will take to arrive if, instead of cold air, the friends find themselves separated by
each of the substances in the table below:

Substance n
Carbon dioxide 1.00045
Water (at 20 ) 1.3330
Ethyl alcohol 1.3600
60% Glucose solution in water 1.4394
Crown glass 1.52
Diamond 2.42
Hint: You should be able to do this in exactly the same way as the previous question, but using a vector of values
for n. Remember the power of MATLAB is that you dont need to calculate each case individually.

1 c = 2.9979e8; % m/s
2 dist = 1000; % km
3 n = [1.00045 1.3330 1.3600 1.4394 1.52 2.42];
4 v = c./n;
5 t = dist*1000./v % s
Carbon dioxide = 0.0033s; Water = 0.0044s; Alcohol = 0.0045s; Glucose = 0.0048s; Glass =
0.0051s; Diamond = 0.0081s.
Tutor note: Remind students about ./ for vectors. You may need to help them define the vector of
values.

Checkpoint 1:

6
LAB ONE PHYS2011/2911 Computational Physics

1.5 Walkthrough: Arrays and plotting


1.5.1 Creating arrays
One of the advantages of MATLAB is its sophisticated visualisation capabilities. As a computational physicist this
means you can plot and visualise your results directly, without having to learn or run a separate plotting package.
In this lab we will start with some very simple plotting. Firstly, we need to learn how to create vectors without
manually inputting values.
MATLAB provides several ways of creating vectors of numbers over a specified range. For example, to make a
vector with values ranging from 1 to 10 in steps of 2:
1 >> x = 1:2:10
2 x = 1 3 5 7 9

If we leave out the middle parameter (the step size), MATLAB will default to a step size of 1, for example:
1 >> d = 0:10
2 d = 0 1 2 3 4 5 6 7 8 9 10

The step size can be fractional:


1 >> x = 1:0.5:5
2 x = 1.0000 1.5000 2.0000 ... 4.5000 5.0000

and you can also step in reverse:


1 >> x = 1:-0.2:0
2 x = 1.0000 0.8000 0.6000 0.4000 0.2000 0

An alternative is the linspace function:


1 >> d = linspace(0, 10, 11)
2 d = 0 1 2 3 4 5 6 7 8 9 10

where the first argument is the starting value (0), the second is the end value (10) and the third is the number of
values in the array (11). This creates a vector of 11 values linearly spaced between 0 and 10.
You can find more information by using help linspace.

1.5.2 Plotting
Creating 2D plots in MATLAB is straightforward. Typically you first create one array holding your x-values and
another holding your y-values. You can then call the plot() function with various formatting options.
For example, to plot the function x2 between 0 and 10 (inclusive):
1 >> x = [0:10]
2 x = 0 1 2 3 4 5 6 7 8 9 10
3 >> y = x.2
4 y = 0 1 4 9 16 25 36 49 64 81 100
5 >> plot(x, y)

There are a couple of things to note about this syntax. Firstly, we define an array with values from 0 to 10 using
[0:10]. We could change to increment to 2 by using [0:2:10] (experiment in MATLAB to see the effect of
this). Secondly we want to square every individual value in the x vector, so we need to use the dot notation x.2
to do a scalar rather than matrix operation.
To make our plot scientifically acceptable we should add some axis labels. We might also want to change the
formatting such as line colour. You can get more information on the formatting options using help plot.
1 >> plot(x, y, '--b.') % Note there are two dashes here
2 >> xlabel('x')
3 >> ylabel('x2')
4 >> title('A plot of f(x) = x2')

7
If we wanted to keep such plots, and overlay other plots, we can use the hold command. To start this process,
make sure that the figure is still open, then type the commands:
1 >> hold on
2 >> plot(x, x.3, '--r.')
3 >> hold off

hold on turns it on and hold off turns it off.

1.5.3 Built-in functions


MATLAB has a wide range of built-in functions that make mathematical calculations easy. These functions
operate on single numbers (scalars) as well as vectors and matrices. For example to calculate the sin of integer
angles between 1 and 10 radians:
1 >> x = [1:10];
2 >> y = sin(x)
3 y=
4 0.8415 0.9093 0.1411 -0.7568 -0.9589 -0.2794 0.6570 0.9894 0.4121 -0.5440

If we wanted to find the sum of all of these values we could do:


1 >> sumy = sum(y)
2 sumy = 1.4112

Some of the common mathematical functions you might need are listed in the table below.

Operation MATLAB command


cos(a), sin(a), tan(a), cos(a),sin(a),tan(a),
cos 1 (a), sin 1 (a), tan 1 (a) acos(a),asin(a),atan(a)
p
a, sqrt(a)
ab , ab
ea , ln(a), log10 (a), exp(a),log(a),log10(a)
Absolute value, |a| abs(a)
Summation:
i ai sum(a)
Minimum value of a vector a min(a)
Maximum value of a vector a max(a)
Note that trigonometric functions work in radians by default. To work in degrees you can use the version with a d
after the name, e.g. sind(a).

8
LAB ONE PHYS2011/2911 Computational Physics

1.6 Exercises
Question 4
Write a MATLAB program to
1. Create a vector a containing the integers from 45 to 55 (inclusive).
2. Calculate the sum of the integers in vector a.
3. Create a vector b containing the odd numbers between 15 and -15.
4. Create a vector c containing the absolute value of the integers in b.
5. Create a vector d with numbers going from 1 to 2 in steps of 0.1.
Write your code in the box below. Make sure you save it as a script.

1 a = 45:55
2 sum(a)
3 b = 15:-2:-15
4 c = abs(b)
5 d = 1:0.1:2
Tutor note: From this point you should insist that students write all of their code as scripts, saved
with a sensible name, e.g. lab1q4.m. Emphasise the importance of being able to reuse solutions
(and keeping them for future study).

Question 5
The equation of state for an ideal gas is

pV = nRT (1.1)

where p is the pressure (in Pa), V is the volume (in m 3 ), n is the number of moles and T is the temperature (in
K). R is the universal gas constant, R = 8.31 J mol 1 K 1 .
Create a vector V with volume values ranging from 0.01 to 1 m3 (why not from 0 to 1 m3 ?). Apply the ideal gas
equation to calculate a vector with corresponding values of pressure for 1 mole of nitrogen at room temperature
(300 K)
Plot pressure versus volume sketch your plot below. Now zoom in on your plot (click and drag using the zoom
icon) to estimate the volume at a pressure of 1 atmosphere (1 105 Pa).

Volume is between 0.0245 and 0.025 m3


Tutor note: ensure all axes are labelled and numbered.

9
LAB ONE PHYS2011/2911 Computational Physics

Question 6 (PHYS2011)
The equation of state for a real gas is given by the Van der Waals equation:
!
n2 a
p (V nb) = nRT (1.2)
V2

where constants a and b take account of long-range repulsive forces and short-range attractive forces between
molecules.
On the same graph as in Question 5, plot p vs. V for 1 mole of nitrogen at room temperature (300 K) using this
equation. For nitrogen, a = 1.427 10 4 Pa m6 mol 2 and b = 3.913 10 4 m3 mol 1 . Sketch both plots on the
same axes below.

Blue (solid) line = ideal; Red (dashed) line = real


Right plot above shows zoomed in version.

You will have to zoom it to see any differences between these plots!

Question 7 (PHYS2911)
The distribution of molecular speeds v in a gas is given by

M 32 Mv2
P(v) = 4 v2 e 2RT (1.3)
2RT

where v is the speed (in m s 1 ), M is the mass of 1 mole (in kg), and T is the temperature (in K). R = 8.31 J mol 1
K 1 is the universal gas constant.
Plot P(v) vs. v for nitrogen for two temperatures (80 K and 300 K) and sketch your plot below. Estimate the speed
corresponding to the peak of the distribution in each case. For nitrogen, M = 28.0 10 3 kg mol 1 .
Try v ranging from 0 to 1000 m s 1 .

10
LAB ONE PHYS2011/2911 Computational Physics

Blue (solid): T = 300 K


Red (dashed): T = 80 K
Tutor note: They can just duplicate code for each T. Remember to explain hold on/off. The equation
is tricky to get right in this one suggest they look for typos.

Checkpoint 2:

11
LAB ONE PHYS2011/2911 Computational Physics

1.7 Challenge: The Cosmic Microwave Background radiation


A black body is an idealised object that absorbs all incident electromagnetic radiation. No radiation is reflected
or transmitted through the body. A black body in thermal equilibrium emits radiation with spectral radiance B at
frequency according to Plancks Law:

2h3 1
B (T ) = (1.4)
c2 h
e kB T 1

where h is Plancks constant h = 6.62606957 10 34 m2 kg s 1 , kB is the Boltzmann constant kB = 1.3806488


10 23 m2 kg s 2 K 1 and c is the speed of light in a vacuum c = 2.9979 108 m s 1 . The frequency is measured
in Hz, resulting in a spectral radiance B in units of W sr 1 m 2 Hz 1 .
Note that in astronomy and astrophysics, spectral radiance is usually referred to as intensity.

Question 8
Plot the Planck spectrum for T = 1000K and T = 2000K in the frequency range 2 1013 3 1015 Hz
(approximately 100 15 000 nm). Sketch the plots below.

Blue: T = 1000 K
Red: T = 2000 K

Question 9
In 1989 the COBE satellite was launched, with the aim of measuring the Cosmic Microwave Background (CMB)
radiation the thermal radiation left over from the Big Bang. The spectrum of this radiation was found to be
an almost-perfect black body. Two of the COBE principle investigators, Smoot and Mather, won the 2006 Nobel
Prize for Physics for this work.
You can read in the original COBE data from the file blackbody.txt provided using the following code
1 >> data = dlmread('blackbody.txt');
2 >> frequency = data(:, 1);
3 >> intensity = data(:, 2);

This produces two vectors frequency and intensity that contain the measured data. The frequency is in
units of GHz and the intensity is in units of MJy sr 1 . Jy (Jansky) is a non-SI unit used in astronomy: 1Jy =
10 26 W m 2 Hz 1 .
Plot this experimental data and sketch your plot below.
Hint: You should use points to plot experimental data, not lines. To do this you can use a plot command like
plot(frequency, intensity, 'bo').

12
LAB ONE PHYS2011/2911 Computational Physics

1 c = 299792458;
2 figure()
3

4 % Read and plot COBE data


5 data = dlmread('test.out');
6 frequency = data(:,1);
7 intensity = data(:,2);
8 plot(frequency, intensity, 'bo');
9 xlabel('Frequency (GHz)');
10 ylabel('Intensity (MJy/sr)');
11 hold on;
12

13 % Plot theoretical BB spectrum


14 T = 2.725;
15 freq_hz = frequency * 1e9;
16 BnuT = planck_f(T, freq_hz);
17 BnuT_MJy = BnuT ./ (10-26 * 1e6);
18 plot(frequency, BnuT_MJy, 'r')

Tutor note: students may need help downloading the blackbody.txt file into the correct directory.

Question 10
From this data, the temperature of the CMB was measured to be 2.725 K. Confirm this by plotting the theoretical
Planck spectrum for T = 2.725 K. Add your theoretical line to the plot in the previous section.
You will have to do some unit conversions to make sure your values are in the same units as the experimental data
(which has in GHz and B in MJy sr 1 ).
An interesting note is that the uncertainties on the COBE measurements are so small that the error bars are smaller
than the thickness of the plotted line. This makes the measurement of the CMB one of the most precise scientific
experiments ever conducted.

1.8 Extra information and references


The MathWorks website has a student centre with introductory tutorials and videos that cover MATLAB basics:
http://www.mathworks.com.au/academia/student_center/tutorials/launchpad.html
To look up how to use specific functions you can use the online documentation:
http://www.mathworks.com.au/help/matlab
The COBE black body spectrum comes from:
http://lambda.gsfc.nasa.gov/product/cobe/firas_prod_table.cfm
For more information about the COBE experiment and the Cosmic Microwave Background radiation, have a look
at the NASA site:
http://lambda.gsfc.nasa.gov/product/cobe/c_edresources.cfm

13
LAB

TWO

Programming in MATLAB
The best programs are written so that computing machines can perform them quickly and so that
human beings can understand them clearly. A programmer is ideally an essayist who works with
traditional aesthetic and literary forms as well as mathematical concepts, to communicate the way
that an algorithm works and to convince a reader that the results will be correct.
Donald E. Knuth, Selected Papers on Computer Science

2.1 Introduction
In the first lab we introduced MATLAB as a calculator and used it to do solve some simple physics problems.
To solve more complex problems you need some more programming constructs: the ability to make decisions
depending on different inputs, and the ability to repeat the same operation many times.
In this lab we will cover the constructs needed for both of these things: if statements allow you to control the
flow of your program; and for loops allow you to repeat calculations.
We will also introduction functions, which are designed to wrap up blocks of code to make large programs and
complex calculations manageable. Functions allow you to:

Hide the details of a calculation;


Reuse the same code many times in different places;
Reuse the same code in different programs;
Avoid duplication of code (and hence reduce bugs);
Replace a calculation with one using a better method, without changing your whole program;
Make your programs easier to read and understand.

Being able to write modular code is the first step in becoming an effective programmer and computational physi-
cist. In the first four labs we will add more programming skills until you have a good problem solving toolkit that
you can use for the rest of the year.

2.2 Lab objectives


By the end of this lab sessions you should be able to:

1. Repeat operations using for loops.


2. Write a program that makes decisions using if statements.
3. Understand how functions work (arguments and return values).
4. Write your own function.
5. Use your functions in a main program.

If you dont know how to do any of these things once you have completed the lab, please ask your tutor for help.
You should also use these lists of objectives when you are revising for the end of semester exam.

PHYS2011/2911 Computational Physics 1


LAB TWO PHYS2011/2911 Computational Physics

2.3 Walkthrough: Repeating things using for loops


Implementing a numerical model generally involves repeating commands multiple times. This is often called
iterating over a range of values. The simplest way of doing this is using a for loop.
1 >> for i = 1:3
2 >> disp(i)
3 >> end
4 1
5 2
6 3

The for loop starts with the word for and ends with end. Everything in between is run for each iteration of the
loop. In this loop, the loop variable i starts with the value 1 and is incremented by 1 each time the loop runs, until
it reaches 3. As a result the integers from 1 to 3 are printed out. Weve also introduced the disp function that you
can use in MATLAB scripts to print out values to the screen (more on this later).
If you change the loop range to for i=1:10 you will see the first ten integers printed instead. You can also loop
in reverse:
1 >> for i = 3:-1:1
2 >> disp(i)
3 >> end
4 3
5 2
6 1

In plain English this reads: loop from 3 to 1 in steps of -1.


You can also loop with fractional increments or steps:
1 >> for i = 1:0.5:3
2 >> disp(i)
3 >> end
4 1
5 1.5000
6 2
7 2.5000
8 3

The English version of this is: loop from 1 to 3 in steps of 0.5.


Another way of defining a range is using the length of a vector you want to loop over. For example:
1 >> v = [0.5 7.6 8.3 9.2];
2 >> for i = 1:length(v)
3 >> disp([i v(i)])
4 >> end
5 1.0000 0.5000
6 2.0000 7.6000
7 3.0000 8.3000
8 4.0000 9.2000

This prints out the index of each item in the vector, and the value of the vector at that index. The syntax [i v(i)]
joins the two values together for printing by the disp function.
You can include any number of commands and functions between the start and end of a for loop. For example,
we could calculate n-factorial (n!) like this:
1 >> n = 5;
2 >> nfact = 1;
3 >> for i = 1:n
4 >> nfact = nfact * i;
5 >> end
6 >> disp([n nfact])
7 5 120

2
LAB TWO PHYS2011/2911 Computational Physics

2.4 Exercises
Question 1
Write a MATLAB program that loops through the integers 20 to 30, printing out the value of n each time.
Your program should work like this:
1 >> lab2q1
2 20
3 21
4 ...
5 30

Write your code in the box below.

1 for x = 20:30
2 disp(x)
3 end
Tutor note: remind students to save their solutions in a script.

Question 2
Write a program that calculates the sum of all integers less than or equal to 1001. You should do this in two ways:
a) Using a vector of integers and the sum function. You can use help sum if you need more information.

1 s = sum(1:1001)

b) Using a for loop.

1 s = 0;
2 for x = 1:1001
3 s = s + x;
4 end
5 disp(s)
Sum in both cases is 501501.

3
LAB TWO PHYS2011/2911 Computational Physics

2.5 Walkthrough: Functions


2.5.1 Using built-in functions
You have already been using MATLABs built-in functions in the first lab. Every time you use something like cos
or sum or mod you are calling a function:
1 >> theta = 2 * pi;
2 >> x = cos(theta)
3 x = 1

To find out how a particular function works you can use help:
1 >> help cos
2 cos Cosine of argument in radians.
3 cos(X) is the cosine of the elements of X.

It is clearly advantageous to have a large set of ready-made functions in fact one of the great things about
MATLAB is its wide range of built-in functions for engineering and science. This saves you having to implement
an algorithm for calculating cos every time you want to take the cosine of a number. Some more examples are
built-in functions are:
1 >> x = abs(-10)
2 x = 10
3 >> radii = [10, 5, 20];
4 >> r = max(radii)
5 r = 20

Functions take zero or more inputs (called arguments). They perform some calculation using those arguments and
then return zero or more outputs. You can store the output/s in a new variable:
1 >> r = max(radii)
2 r = 20

which you can then use in other calculations:


1 >> area = pi * r2
2 area =
3 1.2566e+03

Some functions hide a lot of complexity so that you dont need to worry about it. For example the trigonometric
functions are very easy to use:
1 >> a = 5;
2 >> b = 10;
3 >> c = 30;
4 >> area = 0.5*a*b*sin(c*pi/180)
5 area = 12.5000

but most people who use it probably dont know how sin(c) is actually calculated under the bonnet. It would
be extremely inefficient to have to implement sin() from scratch every time you wanted to use it: thats where
using functions make sense.
Most MATLAB functions also operate on arrays (but check you understand what they are doing!):
1 >> x = [-5, 10, -13.2];
2 >> abs(x)
3 ans =
4 5.0000 10.0000 13.2000

If you try to give a function the wrong kind of input as an argument you will get an error message as shown below:
1 >> sin('hello')
2 ??? Undefined function or method 'sin' for input arguments of type 'char'.

In this case, it doesnt make sense to take the sin() of a character array (word) 'hello'!

4
LAB TWO PHYS2011/2911 Computational Physics

2.5.2 Defining you own functions


There are many calculations in computational physics that we have to do often, and in different programs. A
simple example of this is converting degrees to radians. By implementing this calculation as a function we can
ensure we dont accidentally do the calculation incorrectly.
Create a new m-file called deg2rad.m. Our function needs to have the format
1 function [ output_args ] = function_name( input_args )
2 % function_name: Summary of this function goes here
3 % Detailed explanation goes here
4 % Code goes here
5 end

We called the function deg2rad which explains what it does. We know it needs to take a single input (a value in
degrees d) and return a single output (the value converted to radians r). So our function definition looks like:
1 function r = deg2rad(d)
2 % Conversion code goes here
3 end

We first add a comment to explain what the function will do, and then add the calculation:
1 function r = deg2rad(d)
2 %DEG2RAD Converts degrees to radians
3 r = d*pi/180;
4 end

Our function is complete and at this point you should save the function file. Now to use the function, go back to
the main interpreter window:
1 >> x = 90
2 x = 90
3 >> y = deg2rad(x)
4 y = 1.5708

Note that the input and output variables dont have to have the same names as those in the function definition. We
can pass the results of one function call directly into another. For example to calculate the sine of 30
1 >> result = sin(deg2rad(30))
2 result = 0.5000

The first line of our function that we added as a comment doubles up as a help message so we can run help on
our own functions:
1 >> help deg2rad
2 DEG2RAD Converts degrees to radians

Creating a little help message is a good habit to get into when you do a lot of coding.
Finally, our function also operates on arrays so we can do multiple calculations in one go:
1 >> angles = [30, 90, 180];
2 >> deg2rad(angles)
3 ans =
4 0.5236 1.5708 3.1416

Now in fact, MATLAB provides a version of its trigonometric functions that take degrees rather than radians:
1 >> sind(30)
2 ans = 0.5000

so we dont need our own conversion function in this particular case after all.

5
LAB TWO PHYS2011/2911 Computational Physics

2.6 Exercises
Question 3
Write a function y = divideby7(x) that takes a number x as an argument and returns that number divided by
7. Your function should work like this:
1 >> x = 14
2 >> y = divideby7(x);
3 y = 2

Remember you have to save your function in a file called divideby7.m for this to work.
Use your function to calculate the value of 69993 divided by 7. Write your code and solution below.

1 function y = divideby7(x)
2 y = x./7
3 end
69993 / 7 = 9999
Tutor note: students dont need the ./ for this part, but make sure you explain it for the second part
below.

What do you have to do to ensure your function works on vectors as well as single numbers? For example:
1 >> x = [14 21 28]
2 >> y = divideby7(x);
3 y = 2 3 4

1 function y = divideby7(x)
2 y = x./7
3 end
Need to use ./ to divide a vector, rather than just / for a single number.

Question 4
Write a function d = radial(x, y) that takes a pair of x and y coordinates and calculates the distance from the
origin (0, 0) to that point. Your function should work like this:
1 >> x = 3;
2 >> y = 4;
3 >> d = radial(x, y);
4 d = 5

Use your function to calculate distances to the three sets of coordinates: (0, 7); (5.5, 3.1); (65, 72). Write your
code and solutions below.

1 function dist = radial(x, y)


2 dist = sqrt(x.2 + y.2);
3 end
(0,7): d = 7
(5.5, 3.1): d = 6.3135
(-65, 73): d = 97.7445

6
LAB TWO PHYS2011/2911 Computational Physics

Question 5
Write a function s = esum(n) that calculates the sum

n
X
s= e x (2.1)
x=0

between 0 and n.
For example, for n = 1, your function should work like this:
1 >> s = esum(1);
2 s = 1.3679

Hint: The exponential function e is exp() in MATLAB.

1 function s = esum(n)
2 xvals = 0:n;
3 terms = exp(-xvals);
4 s = sum(terms);
5 end

Question 6 (PHYS2911)
Write a script to find the value for n at which Equation 2.1 converges, to 5 significant figures. You can tell the sum
is converging when adding additional terms does not change the sum.
To do this you should call your esum function inside a for loop and display the result for each iteration.
Hint: Typing format long; at the prompt will change your output to give more significant figures.

1 for x = 1:20
2 s = esum(x);
3 disp([x s])
4 end
Convergences to 5 dp at n = 12, s = 1.58197.
Note the analytic solution between 0 and infinity is e/(e-1). It is the sum of a geometric series.
Tutor note: you may need to explain how to print out two numbers on a line using disp([x s]).

You can compare your result to the analytic solution for the sum between 0 and 1.

Checkpoint 1:

7
LAB TWO PHYS2011/2911 Computational Physics

2.7 Walkthrough: MATLAB logic and decisions


Most programs wouldnt be very interesting if we couldnt control their behaviour depending on the outcomes
from the previous step. For example, you might want to say if the brightness is greater than 10, apply a fil-
ter to my measurement, otherwise keep the original value. In MATLAB, one way of doing this is to use the
if... else... construct.
The first step is knowing how to evaluate logical expressions such as x > 5 (is the value of x greater than 5?).
Each expression is either true (1) or false (0). You can test out logical expressions by typing them directly into
the MATLAB interpreter. For example, set the variable x to an initial value of 3 and then experiment:
1 >> x = 3;
2 >> x > 5
3 ans = 0

This shows that x is not greater than 5 (of course!) the result of the comparison is 0. Whereas:
1 >> x < 5
2 ans = 1

shows that x is less than 5 and the result of the comparison is 1. The logical operators you will need are: greater
than (>), less than (<), greater than or equal to (>=), less than or equal to (<=), equal to (==) and not equal to =
1 >> x == 3
2 ans = 1
3 >> x = 3
4 ans = 0

Note a very important point about the check for equality. A single equals sign = assigns a value to the variable on
the left. A double equals sign == compares the variable to the value on the right and does not change the variable
itself. This is the source of many gotchas for new programmers.
As with most MATLAB commands, these logical operators work on vectors and arrays as well:
1 >> x = [1 2 3; 4 5 6]
2 >> x >= 3
3 ans =
4 0 0 1
5 1 1 1

We can now use these logical operators to make decisions with an if... else... statement.
1 >> x = 9;
2 >> if x > 10
3 disp('x is greater than 10')
4 elseif x == 10
5 disp('x is equal to 10')
6 else
7 disp('x is less than 10')
8 end
9 x is less than 10

Only one line of text was printed to the screen the one that corresponded to the true condition. If we run the
same example again with a different value for x we would get a different outcome:
1 >> x = 20;
2 >> if x > 10
3 disp('x is greater than 10')
4 elseif x == 10
5 disp('x is equal to 10')
6 else
7 disp('x is less than 10')
8 end
9 x is greater than 10

The if...else... statement allows you to create a program in which some parts run only if a condition is true.

8
LAB TWO PHYS2011/2911 Computational Physics

2.8 Exercises
Question 7
Write a MATLAB function even(x) to check whether a given number x is even. Your function should return
true (or 1) if it is, and false (or 0) otherwise:

1 >> even(2)
2 ans = 1
3 >> even(1)
4 ans = 0

Hint: you might find the built-in function mod() useful.

1 function result = even(x)


2 if (mod(x,2)==0)
3 result = 1;
4 else
5 result = 0;
6 end
7 end

Question 8
As you know, triangles can be classified according to the lengths of their sides. Write a MATLAB function
triangle(a, b, c) that takes the lengths of the three sides of a triangle (a, b and c) and returns the type of
triangle: equilateral, isosceles or scalene. Your function should work like this:
1 >> triangle(1, 1, 1)
2 ans = equilateral
3 >> triangle(2, 3, 2)
4 ans = isosceles
5 >> triangle(2, 3, 4)
6 ans = scalene

You can assume that all lengths will be positive.

1 function type = triangle(side1, side2, side3)


2 if (side1 == side2 || side1 == side3)
3 if(side2 == side3)
4 type = 'equilateral';
5 else
6 type = 'isosceles';
7 end
8 elseif (side2 == side3)
9 type = 'isosceles';
10 else
11 type ='scalene';
12 end;
13 end
Tutor note: A common mistake is a==b==c which does not result in a MATLAB error. Also, note
you dont need to use in the solution (we havent covered that yet).

Extension: Improve your function so that it determines whether the triangle satisfies the triangle inequality: the
sum of the lengths of any two sides must be greater than the length of the remaining side. Test your solution using
triangle(4, 2, 1)

9
LAB TWO PHYS2011/2911 Computational Physics

2.9 Putting it all together


We have now covered some of the main programming constructs you need to write a useful program. The final
step is putting them together, and working out how to translate a physics problem into something you can solve
programmatically. In this section we will build up a program that uses some of these constructs to solve a problem
and plot the results.
Question 9
A ball is fired from a cannon at velocity v and an angle of from the ground. The x and y components of the balls
position after time t are given by:

1
yt = vy t + at2 (2.2)
2
xt = vx t (2.3)

where v x and vy are the x and y components of the initial velocity, and a = 9.8 ms 2 is the acceleration due to
gravity.
(a) Assume the ball is fired with an initial velocity of 10 ms 1 at an angle = 45 . Use MATLAB to calculate the
x and y components of the initial velocity, v x and vy . Write your code below.

1 v = 10; % m/s
2 theta = 45; % degrees
3 vx = cosd(theta)*v
4 vy = sind(theta)*v
vx = vy = 7.07 m/s
Tutor note: Remind students to use cosd and sind as their input is in degrees.

(b) Keeping the same initial parameters, extend your script to calculate the x and y position of the ball, xt and yt ,
after 1 second. To do this you need to implement Equations 2.2 and 2.3.

1 t = 1; % seconds
2 a = -9.8; % m/s/s
3 xt = vx*t
4 yt = vy*t + 0.5*a*t2
xt = 7.07 m
yt = 2.17 m
Tutor note: Only the new lines of code are shown above.

(c) Now we want to be able to do this calculation for a range of different initial conditions. Wrapping up this code
in a function will allow us to reuse it.
Write a function [xt, yt] = projectile(v, theta, t) that takes three arguments: the initial velocity v,
the initial angle, , and the time t. Your function should return the x and y components of the position of the ball,
xt and yt, after time t.
You can test your function by running it with the same initial conditions you used in parts (a) and (b). For example:
1 >> v = 10;
2 >> theta = 45;
3 >> t = 1;
4 >> [xt, yt] = projectile(v, theta, t);

and this should produce the same results as before.


Use your function to calculate the position of the ball after t = 8 seconds, for an initial velocity v = 100ms 1 and
an initial angle = 89 . Write your answer below.

10
LAB TWO PHYS2011/2911 Computational Physics

xt = 13.96 m
yt = 486.28 m

(d) We can now call this function multiple times to visualise the projectile motion of the cannonball. One nice
trick you can use in MATLAB is plotting things in a for loop, with the pause command. This allows you to see
each point as it is plotted.
A template for this is:
1 for t = 0:0.1:2
2 % Call your function here
3 plot(xt, yt, 'o');
4 hold on;
5 pause(0.1)
6 end

Write a script that uses the for loop shown above to call your function and visualise the results. For our initial
parameters of v = 10 ms 1 and = 45 a time range of t = 0 to 2 seconds in steps of 0.1 seconds works reasonably
well. Sketch your final plot below (you should see the path of the cannon ball over time).

Tutor note: Ensure axes are labelled before you mark off work.

Youll notice that the plot is non-physical. The cannonball travels down past y = 0 and goes underground! In a
later lab well introduce while loops and break statements to deal with this problem.

Checkpoint 2:

11
LAB

THREE

Numerical Modelling
When sunlight is scattered by raindrops, why is it that colorful arcs appear in certain regions of the
sky? Answering this subtle question has required all the resources of mathematical physics.
H. M. Nussenzveig, Scientific American, 1977

3.1 Introduction
Rainbows are a well known atmospheric phenomena caused by the dispersion of sunlight by water droplets.
Different wavelengths of light are refracted at different angles resulting in distinct bands of colour. The formation
of a rainbow can be understood using concepts from geometric optics.

In this lab we will use the MATLAB skills weve learnt so far to construct a numerical model of a rainbow that
demonstrates why a rainbow appears visually as it does. The exercise is split into several sections. In each section
you will write and test code a piece of code which relies on work from the previous section. At the end you will
have a complete working model. Writing and testing the code in pieces makes it easier to find bugs and mimics
the development cycle for large numerical codes used in research.
Before you start coding it is critical you understand what youre trying to code! One way of doing this is to try
and explain the solution in plain English to your partner. Another way is to write comments in your code outlining
the steps, and then write the the code for each part.

3.2 Lab objectives


By the end of this lab sessions you should be able to:

1. Solve physics problems using MATLAB.


2. Develop a MATLAB script built from multiple components.
3. Visualize simple datasets using plot().

If you dont know how to do any of these things once you have completed the lab, please ask your tutor for help.
You should also use these lists of objectives when you are revising for the end of semester exam.

PHYS2011/2911 Computational Physics 1


LAB THREE PHYS2011/2911 Computational Physics

3.3 Activity: Creating a rainbow Part I


3.3.1 Refraction in a raindrop
Refraction is the change in direction of a ray of light when it traverses the boundary of two media with different
refractive indices. For light travelling from a medium with refractive index n1 to a medium with refractive index
n2 , the relationship between the angle of incidence 1 and angle of refraction 2 is given by Snells law:

n1 sin 1 = n2 sin 2 . (3.1)

A dispersive medium is one where the refractive index is a function of wavelength. Water is dispersive and it is
this property that gives rise to rainbows, as different wavelengths of light are refracted at different angles resulting
in the angular separation of different colours.
In order to construct a rainbow it is necessary to consider the wavelength dependence of the refractive index of
water. It is difficult to derive a formula for n( ) for water from first principles. Instead, it is easier to use an
approximate model constructed from empirical data. A good approximation in the visible range (400 700 nm) is
n n n
n( ) = n0 + 1 + 22 + 33 , (3.2)

where n0 = 1.3128, n1 = 15.7622, n2 = 4382, n3 = 1.1455 106 , and is the wavelength of light in nanometres.
Question 1
Write a script that calculates n( ) over the range 425 650 nm using 256 points. Produce a plot of n( ) vs and
sketch it in the box below. You can attack this problem in three parts:

1. Write code to generate a vector of wavelength values over the specified range;
2. Write code to calculate the value of n( ) using Equation 3.2;
3. Plot n( ) vs with appropriate labels.

Each of these parts requires a few lines of MATLAB, and you can test each part as you write it.
Hint: The linspace function allows you to construct vectors with a fixed number of points over a given range.
For example, the code below generates a vector of 256 uniformly spaced points spanning the interval [1, 10].
1 >> xmin = 1.;
2 >> xmin = 10.;
3 >> npoints = 256;
4 >> x = linspace(xmin, xmax, npoints);

1.344

1.342

1.34

1.338
n()

1.336

1.334

1.332

1.33
400 450 500 550 600 650
(nm)

2
LAB THREE PHYS2011/2911 Computational Physics

3.3.2 Path of rays in a raindrop


The next stage of our model is calculating the path of a single ray of light as it passes through a raindrop.
The left panel of Figure 3.1 shows the path of a single ray of monochromatic light inside a raindrop. The ray is
parallel to the dotted line when it enters the drop but after undergoing two refractions and a reflection it exits at an
angle of deflection . The angle depends on the angle of incident of the ray , and the wavelength of light .
The right panel of Figure 3.1 shows how the path varies depending on wavelength. A single ray of light is a
superposition of different wavelengths and all are initially parallel to the x axis of the figure. It can be seen that
upon exiting the raindrop the different colours are travelling along different paths, i.e. differs for each.
Using this information we can calculate ( , ) for a range of different wavelengths and entry points.

Figure 3.1: Left: The path of a ray through a drop of water. The angles shown are the angle of incidence , the
angle of refraction and the total angle of deflection . Right: This figure shows how the path changes with
wavelength of light (represented by different colours).

Question 2
Using Snells law derive an expression for the angle of refraction in terms of and n( ). You can assume that
the refractive index of air is 1.0.

n1 = 1 (air)
n2 = n( ) (water, wavelength dependent)
1 = (angle of incidence)
2 = (angle of refraction)
Now substitute and rearrange
!
sin
= sin 1
n( )

Question 3
Using Figure 3.1 as a guide, derive an expression for the angle of deflection, , in terms of and .

( , ) = 4 2

3
LAB THREE PHYS2011/2911 Computational Physics

Question 4
Write a MATLAB script that computes the angle of deflection, , for a single ray given a wavelength and an
initial angle of incidence . The computation requires three steps:

1. Compute n( ) from Equation (3.2)

2. Compute using your formula from Question 2


3. Compute using your formula from Question 3

Use your program to calculate assuming = 650 nm, = 30 and write the answer in the box. Remember to
use the trigonometric functions that take input in degrees not radians (i.e. sind rather than sin).

n = 1.3308 theta = 22.07


gamma = 28.27
Tutor note: check for degrees/radians confusion (if they use the radians version of the trig functions
the answer will be -63.34).

Question 5
The next step is to calculate for multiple monochromatic rays that are initially parallel and uniformly spaced
vertically (as in Figure 3.2). If y is the perpendicular distance between the starting point of the ray and the centre
of the drop, we can represent this as a vector of points y = {y1 , y2 , . . . , yN } in the range [0, Rdrop ] which are the
starting points of our rays.

y4=Rdrop

y3

y2

y1=0

Figure 3.2: Multiple monochromatic rays entering the drop from vertically spaced starting points. In this example
there are four rays. The first ray has an elevation of zero (y1 = 0), and the final ray has an elevation equal to the
radius of the drop (y4 = Rdrop ).

The radius of the drop Rdrop doesnt matter for the purpose of calculating angles, for convenience we can use
Rdrop = 1. Each ray strikes the drop with a different angle of incidence . From Figure 3.1 you can see that the
angle of incidence is related to the distance y by y = Rdrop sin( ).
Make a copy of your script from Question 4 and extend it to compute the angles of incidence ( ) and deflection
( ) for multiple monochromatic rays. To do this you will need to:

1. Construct a vector y, of 256 points in the range [0, 1] representing the starting positions of the rays
(you might want to use linspace);

2. Use this vector to compute the angle of incidence for each ray;

3. Calculate the corresponding angle of deflection for each point.

4
LAB THREE PHYS2011/2911 Computational Physics

Plot versus y for = 650 nm. Sketch your plot below.

45

40

35

30
( degrees)

25

20

15

10

0
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1
y/R
drop

3.3.3 Creating a function


In the second half of this lab we want to calculate these angles for light at a range of different wavelengths. Rather
than modify the code each time, if we save it as a function we can reuse it by passing in different parameters.
Your function needs to take in the wavelength of incident light, , and the radius of the raindrop, Rdrop . It will
return a vector of values for the initial positions, y and a vector of values for the angles of deflection, .
If we translate these requirements to MATLAB, we end up with a function definition something like this:
1 function [y, gamma] = calculate_deflection(lambda, rdrop)
2 % Your function code here
3 end

The last line of your function should calculate gamma and hence return the vector to the main program. Dont
include your plotting inside the function as that will change depending on what problem we are solving.
You can test your function by passing the same input values as we used in Question 5:
1 >> clear all;
2 >> lambda = 650;
3 >> rdrop = 1;
4 >> [y, gamma] = calculate_deflection(650, 1);
5 >> plot(y, gamma, 'b.');

Its a good idea to use clear all before you test your function, so you can ensure that it is working indepen-
dently, and not accidentally using variables that are already defined in your workspace.
Make sure you have this function working before you continue with the lab.

Checkpoint 1:

5
LAB THREE PHYS2011/2911 Computational Physics

3.4 Activity: Creating a rainbow Part II


Now we have code for computing for a single wavelength, we can to extend the model to polychromatic light.
To do this we need to loop over the range of wavelengths were interested in.
Question 6
Write a program to plot versus y for each of 32 wavelengths in the range 425 650 nm. To do this, you should:

1. Create a vector of 32 wavelength values between 450 and 650 nm;

2. Loop through the vector and call your calculate_deflection function;

3. Plot versus y for each wavelength, on the same plot.

Use hold on; to force the plots to appear on the same figure.
To make the plot more informative, we have provided you with a MATLAB function rainbow_ct.m that converts
a wavelength in nanometres to an RGB colour value. This way the colours of the curves will reflect the actual
colour of that wavelength of light. The code snippet below demonstrates the use of the function.
1 >> lambda = 650;
2 >> rgb = rainbow_ct(lambda);
3 >> plot(y, gamma, 'Color', rgb);

Note that the input must always be a scalar, passing a vector will results in an error.
Sketch your rainbow below.

45

40

35

30
(degrees)

25

20

15

10

0
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1
y/R drop

Question 7
Use your plot, and Figure 3.1, to explain how a rainbow is created.

There are two effects evident in Figure 1.2. Firstly, rays with a large angle of incidence tend
to experience the largest deflection. This can be inferred from vs y plot which obtains a
maximum around 60 (correponding to 43 ). Secondly, for a given , red rays are
deflected more than blue. This can be seen in the vs y plot as the red curve sits above the
blue.

6
LAB THREE PHYS2011/2911 Computational Physics

3.5 The intensity of scattered light (PHYS2911)


So far we have determined that different wavelengths of light initially travelling in same direction will be scattered
at different angles after transversing the raindrop. To complete the model of the rainbow we need to calculate the
intensity of the light exiting the drop I( ), as a function of .
The intensity of light is determined by the number of rays which exit for a particular value. We can construct
a histogram of values (which provides the number of rays in an interval ). MATLAB has a built in function
hist which computes the data required to plot a histogram. The code snippet below illustrates the use of this
function.
1 % Create a vector of N random numbers
2 N = 1e3;
3 y = rand(N, 1);
4

5 % Create a histogram using the hist function


6 % hist(data,number of bins)
7 [counts bin_loc] = hist(y,sqrt(N));
8

9 % Plot histogram using bars


10 bar(bin_loc,counts);

The first argument of hist is the data; the second is the number of bins. It is convenient to set the number of bins
to the square root of the number of points. The function hist returns two vectors. The first (called counts in the
example) is the number of counts in each bin, the second (called bin_loc in the example) is the location of the
start of each bin. The function bar plots the histogram as a bar graph.
Question 8
With = 450 nm plot a histogram showing how is distributed for 6000 rays uniformly spaced vertically. Sketch
your plot below.

12

10

8
I() (%)

0
0 5 10 15 20 25 30 35 40 45

7
LAB THREE PHYS2011/2911 Computational Physics

Question 9
Compute I( ) due to 32 different wavelengths. To do this put your code from Question 8 inside a for loop which
loops over the different values of . Use 105 rays to ensure a smooth histogram.
To colour code your plot you need to set the 'FaceColor' and 'EdgeColor' options when calling bar as
demonstrated below.
1 bar(bins,I,'FaceColor',rgb,'EdgeColor',rgb);

Where rgb is generated using rainbow_ct.m.

4.5

3.5

3
I()(%)

2.5

1.5

0.5

0
0 5 10 15 20 25 30 35 40 45

Question 10
Describe how the intensity of different wavelengths varies with angle. Measure the angular size of the bow.

Each wavelength obtains an intensity maximum at a different value of . This results in the
formation of the distinct bands of colour synonymous with rainbows. The bow is 1.8 in
size.

Checkpoint 2:

8
LAB THREE PHYS2011/2911 Computational Physics

3.6 Challenge: Double rainbows


In Figure 3.1 the ray undergoes a single reflection inside the raindrop. The rainbow formed as a results is called a
first-order rainbow. A second-order rainbow results when the ray undergoes a second reflection before exiting the
drop. A double rainbow occurs when both the first-order and second-order rainbows are visible.
Question 11
Sketch the light path for a second-order rainbow. (Feel free to use Google if you need help. . . )

Question 12
Compute in terms of and for the second-order rainbow.

( , ) = + 6 2

Question 13
Adapt your code from Question 10 to compute the intensity distribution for the second-order rainbow. Draw your
plot in the box. What do you notice about the order of the colours? Hint: Construct y in the range [ Rdrop , 0].

3.5

2.5

2
I()(%)

1.5

0.5

0
40 60 80 100 120 140 160 180

Note that the colours are reversed compared to the first order rainbow.

9
LAB THREE PHYS2011/2911 Computational Physics

Question 14
Plot the intensity of the first and second order rainbows on the same plot. Compare the widths of the two bows.

4.5

3.5

3
I()(%)

2.5

1.5

0.5

0
0 20 40 60 80 100 120 140 160 180

Second order rainbow is thicker that the first order, but is fainter in general. The intensities
of the rainbows are not realistic. We have ignored the losses due to transmission/reflection at
each refraction/reflection. These effects require use of the Fresnel equations at each interface.

3.7 Extra information and references


The activities in this lab are based on Amundsen et al. 2009, American Journal of Physics, 77, 795.
http://scitation.aip.org/content/aapt/journal/ajp/77/9/10.1119/1.3152991
The schematic in Figure 3.1 is also taken from this reference.
A great introduction to the science of rainbows is given in the Scientific American article:
http://www.phys.uwosh.edu/rioux/genphysii/pdf/rainbows.pdf
For a full quantitative treatment of rainbows, you might be interested in this paper:
http://www.cems.uvm.edu/tlakoba/AppliedUGMath/rainbow glory review.pdf
Equation 3.2 is taken from Quan and Fry 1995 Applied Optics, 34, 3477.
http://www.opticsinfobase.org/ao/fulltext.cfm?uri=ao-34-18-3477&id=45728
Note that some of these articles may only be available through the University library subscription (in other words
you will have to download them on campus using your University account).

10
LAB

FOUR

Numerical Ray Tracing


4.1 Introduction
The aim of ray tracing it to determine the geometric path of light through a system. Ray tracing arises in many
contexts including optical instrument design, astronomy, and computer graphics, it is also important in areas like
seismology where the rays represent the paths of seismic waves rather than light.
All but the most trivial ray tracing problems are intractable analytically and require numerical treatment. In this lab
we will develop a program to perform ray tracing in two dimensions through a medium with a variable refractive
index. We will first apply our code to a test case to verify its correctness. We will then use it to study total internal
reflection, as shown below in the image of light from a laser travelling along a perspex rod.

To develop your numerical ray tracing program you will have to use all the programming skills you have learnt
so far, putting them together to create a sophisticated program. Well also learn a few more control structures to
complete your understanding of basic MATLAB functionality: while loops and break statements.
Taking an abstract idea like an algorithm and realising it in code can be a formidable task. It is always simpler to
develop a code in stages. That way we only need to think about a small part of the problem at any one time, and
it also helps us debug the code.

4.2 Lab objectives


By the end of this lab sessions you should be able to:

1. Write code using while loops.


2. Solve problems using for loops or while loops.
3. Exit from loops using the break statement.
4. Combine different programming control structures to write a program.

If you dont know how to do any of these things once you have completed the lab, please ask your tutor for help.
You should also use these lists of objectives when you are revising for the end of semester exam.

PHYS2011/2911 Computational Physics 1


LAB FOUR PHYS2011/2911 Computational Physics

4.3 Walkthrough: While loops and breaking


In Lab 2 we used for loops to iterate over a range of values, repeating a series of commands each time. for
loops are good when you want to run for a fixed number of iterations. However, sometimes you want to calculate
something for which you dont know the number of iterations in advance. A while loop lets you continue to
iterate while some condition remains true.
For example, say you want to work out how many consecutive integers need to be summed before the total exceeds
100. If you start by setting a variable sum = 0 we can then iterate until sum is equal to 100:
1 >> x = 0;
2 >> sum = 0;
3 >> while sum <= 100
4 >> x = x + 1;
5 >> sum = sum + x;
6 >> end
7 >> disp([x sum]);
8 14 105

As the output shows, you need to sum all the integers from 1 to 14 before their sum exceeds 100.
A while loop repeats the following steps:
1. Evaluate the condition expression (in this case sum <= 100)
2. If the condition is true, run the body (in this case, lines 4 and 5)
3. If the condition is false, jump to the statement after the body (disp([x sum]))

4.3.1 While loops and for loops


Anything that can done with a for loop, can also be done with a while loop. For example, to print the numbers
from 1 to 5 we could use either loop. A for loop would look like this:
1 >> for x = 1:5
2 >> disp(x);
3 >> end

and a while loop to do the same thing would look like this:
1 >> x = 1;
2 >> while x < 6
3 >> disp(x);
4 >> x = x + 1;
5 >> end

In each iteration the loop counter, x has to be incremented. If you dont increment it you will end up with an
infinite loop. Try removing line 4 (x = x + 1) from the code snippet above and rerunning it. This loop will
continue running forever. Press CTRL-C while the cursor is in the command window to terminate the program
and regain control of the command prompt. If this fails, then kill MATLAB, or kill the computer!

4.3.2 The break statement


In the example above, both code snippets result in exactly the same output, but the for loop is more convenient.
Other examples lend themselves more naturally to a while loop. For example, say we want to print out the square
of all integers where the square is less than 100. To do this with a while loop:
1 >> x = 1;
2 >> while x2 < 100
3 >> disp(x2);
4 >> x = x + 1;
5 >> end
6 1
7 4
8 ...
9 64

2
LAB FOUR PHYS2011/2911 Computational Physics

10 81

To do this using a for loop we need to introduce a new concept: breaking out of a loop. Not surprisingly, this is
done with the break command. The break command is usually used inside an if statement that checks whether
some condition is true:
1 >> for x = 1:1000
2 >> if x2 >= 100
3 >> break
4 >> end
5 >> disp(x2);
6 >> end
7 1
8 4
9 ...
10 64
11 81

In this example we start by looping between 1 and 1000. In each iteration, the value of x2 is calculated and if it
is greater than or equal to 100 we break out of the loop. If you remove lines 2 and 3, then the program will print
out the squares of all the integers up to 1000 instead.
It is good practice to indent your code so that it is easier to read. Notice how in the example above the if statement
block is indented inside the for loop block, which makes it easier to see the flow of control in the program. The
MATLAB editor has a smart indenting facility that should automatically indent code inside loops.

4.3.3 Multiple conditions


Sometimes you need a while loop or if statement that depends on multiple conditions. For example, if you want
to check whether a number is within a given range 1 < x < 1 you need to check two conditions. One way of
doing this is to nest if statements inside each other:
1 >> x = -0.5;
2 >> if x > -1
3 >> if x < 1
4 >> disp('The number is in range');
5 >> end
6 >> end

Try changing the value of x to something outside the range to check this code works.
A more convenient way is to combine the two conditions using the and operator &&:
1 >> x = -0.5;
2 >> if x > -1 && x < 1
3 >> disp('The number is in range');
4 >> end

There is also an or operator, represented by the double pipe symbol ||:


1 >> x = -0.5;
2 >> if x <= -1 || x >= 1
3 >> disp('The number is out of range');
4 >> end

These operators work exactly the same way in a while loop. For example, to print out the value of the square
numbers until either the value is greater than 100 or we have run 5 iterations of the loop:
1 >> x = 1;
2 >> count = 0;
3 >> while x2 < 100 && count < 5
4 >> disp(x2);
5 >> x = x + 1;
6 >> count = count + 1;
7 >> end

3
LAB FOUR PHYS2011/2911 Computational Physics

4.4 Exercises
Question 1
Write a program that prints out all the multiples of 12 that are less than 200.
Hint: Be careful of the end case.

1 x = 1;
2 mult = x * 12;
3 while mult < 200
4 disp(mult)
5 x = x + 1;
6 mult = x * 12;
7 end
Tutor note: check the first and last values are correct. Explain how the order of commands inside
the loop affects the results.

Question 2
If you used a for loop in Question 1, rewrite your program with a while loop and check it gives the same results.
If you used a while loop, rewrite it using a for loop.

1 for x = 1:100
2 mult = x * 12;
3 if mult >= 200
4 break;
5 end
6 disp(mult);
7 end

Question 3
Write a program to work out how many cubic numbers you need to add so that the the total exceeds 1000.

1 sum = 0;
2 x = 0;
3 while sum < 1000
4 x = x + 1;
5 sum = sum + x3;
6 end
7 disp([x sum]);
7 numbers gives a sum of 784
8 numbers gives a sum of 1296
Tutor note: check the end condition a common error is incrementing x one extra time.

4
LAB FOUR PHYS2011/2911 Computational Physics

4.5 Walkthrough: Relational operators


When you want to compare two (or more) things you need to use a relational operator. These operators, such as
less than (<) or equal to (==) return 1 if the comparison is true, and 0 if the comparison is false. For example:
1 >> 10 >= 5
2 ans = 1
3 >> 3 > 5
4 ans = 0

The operators we will use is given in the table below.


== = > < >= <=
Equal to Not equal to Less than Greater than Greater than or equal to Less than or equal to
You can apply these operators to vectors to find elements that match particular criteria. Rather than a single 1 or
0 being returned, a vector of 1s and 0s is returned. For example:
1 >> a = [1 -3 2 -4 5 7];
2 >> a > 0
3 ans = 1 0 1 0 1 1

In this case, the first element of a is greater than 0, so the first element of the output vector is 1 (true). The second
element of a is less than 0, so the second element of the output vector is 0 (false), and so on.
MATLAB has a nifty way of getting the values in an array that satisfy a certain condition: you can pass this output
vector back in to the original vector like this:
1 >> a(a>0)
2 ans = 1 2 5 7

The new output vector contains only the positive elements of a. This trick uses the fact that you can pass one
vector into another one to return the specified elements. For example, if we want to get the 2nd and 4th elements
of a we could do this:
1 >> a = [1 -3 2 -4 5 7];
2 >> b = [2 4]
3 >> a(b)
4 ans = -3 -4

Comparing vectors
In the above examples we have compared a vector to a scalar value. You can also compare two vectors in an
element-by-element fashion. For example:
1 >> a = [2 4 5 1];
2 >> b = [1 6 2 7];
3 >> a > b
4 ans = 1 0 1 0

The output vector has a value of 1 (true) for each element of a that is greater than the corresponding element of
b, and a value of 0 (false) otherwise. In other words 2 is greater than 1, so the first element of the output vector
is 1. However, 4 is less than 6, so the second element of the output vector is 0.
As before, you can take this output vector and pass it in to one of the original vectors to get all the values that
satisfy the condition. For example, to find all the values of a that are greater than the corresponding value of b:
1 >> a(a > b)
2 ans = 2 5

These operators are exactly the same as the ones you have used in if statements. For example:
1 x = 2
2 if x > 0
3 disp(x)
4 end

5
LAB FOUR PHYS2011/2911 Computational Physics

4.6 Exercises
Question 4
Given the two vectors a and b below:
1 a = [1 -2 3 -4 5 -6 7 8];
2 b = [-40 -30 -20 -10 0 10 20 30];

Write MATLAB code to

1. Print out the elements of a that are less than 0.

2. Print out the elements of b that are greater than or equal to 3.


3. Print out the elements of b that are greater than the corresponding value of a.

4. Print out the number of elements of a that are positive.

Write your code in the box below.

1 a(a<0)
2 b(b>=3)
3 b(b>a)
4 length(a(a>0))
Tutor note: emphasise the need for general solutions, not hard coding the answer for the particular
case. i.e. if the content of vector a changes their solution should still work.

Question 5
Given the two vectors a and b defined in Question 4, write MATLAB code to:

1. Create a new vector c that consists of the negative values of a.


2. Create a new vector c that consists of the negative values of a and b.

3. Print out the first positive element of a.

4. Print out the last positive element of a.

Write your code in the box below.

1 c = a(a<0)
2 c = [a(a<0) b(b<0)]
3 c = a(a>0); c(1)
4 c = a(a>0); c(end)

Checkpoint 1:

6
LAB FOUR PHYS2011/2911 Computational Physics

4.7 Activity: Tracing a single straight ray


The goal of ray tracing is determine the path of a ray given an initial starting point and direction of the ray. We
will write our ray tracing program in three stages, progressively implementing more advanced features. In this
section we will implement the first stage: a program that draws the paths of straight rays.
The coordinates of the starting position of the ray can be denoted as r0 = (x0 , y0 ). In vector form, this is

r0 = x0 x + y0 y , (4.1)

We can represent this real world vector as a MATLAB vector:


1 r0 = [x0, y0];

The first element is the initial x-position x0, and the second element is the initial y-position y0.
We will assume that the light is initially travelling in a direction that is inclined by 0 degrees from the horizontal.
In vector notation, this is

s0 = cos(0 )x + sin(0 )y, (4.2)

Note that this vector has unit length.


Question 6
Implement Equation 4.2 as a MATLAB vector. Test it works using an angle of 0 = 45 .

1 theta0 = 45;
2 s0 = [cosd(theta0), sind(theta0)];
p
Each component should be equal to 2.
Tutor note: It is critical that students understand the relationship between physics vectors and
MATLAB vectors.

4.7.1 An iterative model


In iterative models you compute the current parameters by taking small steps based on the parameters at the
previous step. In this case we will update the position and direction of the ray by taking a small step in the
direction s0 .
If our step-size if h, then the new position r1 is given by the vector addition

r1 = r0 + hs0 . (4.3)

This vector sum is demonstrated in Figure 4.1.

hs^0

r0 r1

Figure 4.1: Illustration of one step of the position update.

Assuming the light continues to travel in the same direction, we can compute the next step r2 from r1 in the same
way as we did for r0 . The general expression for rk is then

rk+1 = rk + hs0 . (4.4)

7
LAB FOUR PHYS2011/2911 Computational Physics

This is an example of an iterative method, since the new value is generated from previous values. After k applica-
tions of the method we expect to have travelled a distance of kh.
Question 7
Write a program that traces a ray according to Equation 4.4. The initial position and angle should be r0 = (0, 0)
and 0 = 45 . Use a step size h = 0.05.
To do this, use a loop that iterates for 10 steps, plotting the position of your ray each time. You can use the same
trick we used in Lab 2 Question 9 to plot in the loop with a pause(0.2) between each point so you can see it:
1 for x = 1:10
2 plot(r(1), r(2), 'r.');
3 hold on
4 pause(0.2);
5 % Add your code to update the position here
6 end

In this example, r is a vector containing the x and y components of position. Sketch your final plot below.

Tutor note: Make sure Question 8 is working with the correct while loop conditions.

Question 8
Our simulation would be better if, rather than running for a set number of iterations, it ran until the ray left some
predefined region. Imagine we have a box that spans the range 0 x L x and 0 y Ly ) where Lx = Ly = 1.
Make a copy of your program and modify it so that it uses a while loop instead of a for loop. Your while loop
should have multiple conditions that means the ray keeps moving until it leaves the simulation box:

y > 0: ray leaves bottom of box

y < Ly: ray leaves top of box

x > 0: ray leaves right side of box

x < Lx: ray leaves left side of box

You should set the axes of your plot to be slightly bigger than the box so you can check if your loop is
working correctly. For example, to have your axes extend 10% beyond the edge of the box you could use
axis([0, 1.1*Lx, 0, 1.1*Ly]).
Run your program and make sure you understand the output. If you dont discuss it with your tutor before
continuing.

8
LAB FOUR PHYS2011/2911 Computational Physics

4.8 Activity: Ray tracing with refraction


In this section we will extend our program to model the refraction of light.
Refraction is the change in direction of light due variations in the refractive index. The simplest example is when
the change occurs at a sharp boundary, such as the interface between air and glass. In this case a ray follows
a piece-wise linear path. In general rays will follow curved paths in media where the refractive index varies
continuously with position.
To model the refraction of light we have to update the direction vector s after each step. We will derive a simple
method for computing the new direction based on Snells law for refraction. For simplicity our method assumed
that the refractive index only varies with height: n(r) = n(y).
Assume we are at a point r1 and the direction of the ray at this point is s1 . The new position is then

r2 = r1 + hs1 . (4.5)

Our goal is to compute an update equation for s2 , the direction vector at the new position. To do this will treat
n as if it were comprised of thin layers of constant n. Figure 4.2 shows two layers; the lower layer labelled 1
has refractive index n1 = n(r1 ) and the upper layer labelled 2 has refractive index n2 = n(r2 ). The ray starts at
r1 , travels a distance h in direction s1 and encounters the boundary at r2 . We apply Snells law to calculate the
direction of the ray s2 in the upper layer.

n = n(r )
2 2
hs^2

n = n(r )
1 1
hs^ 1

Figure 4.2: Diagram illustrating the position and direction update steps.

The left panel of Figure 4.3 shows the direction vectors of a ray travelling in the positive y direction. We can use
basic trigonometry to relate the angle of incidence 1 to the x component of s1 . The vector s1 has unit length and
y y

2 ^s2
^
s 1
1

^
s1 x x
1 ^s
2
2

Figure 4.3: Left: Refraction of a ray travelling in the positive y direction. Right: Refraction of a ray travelling in
the negative y direction.

9
LAB FOUR PHYS2011/2911 Computational Physics

it follows that

1 = sin 1 (s1x ), (4.6)

where s1x is the x component of s1 . Using Snells law,

n2 sin(2 ) = n1 sin(1 ), (4.7)

we can determine the angle of refraction 2 , since both n2 and n1 are known. Once 2 has been found, we can use
trigonometry to determine the components of s2 . For the ray travelling in the positive direction we find that the
new direction vector is

s2 = sin(2 ) x + cos(2 )y. (4.8)

The right panel of Figure 4.3 shows the direction of a ray travelling in the negative y direction. Applying the same
procedure to this case yields

s2 = sin(2 ) x cos(2 )y. (4.9)

We can combine the two cases into a single equation using the sgn(.) function:

s2 = sin(2 ) x + sgn(s1y ) cos(2 )y, (4.10)

where s1y is the y component of s1 and


8
>
>
> +1 x > 0
<
sgn(x) = >
> 0 x=0 (4.11)
>
: 1 x < 0.

The MATLAB version of the sgn function is called sign.


Question 9
Write a MATLAB function function s2 = refract_ray(n1, n2, s1) which computes the new direction
vector using Equation (4.10).
The function should take the direction vector at the current position s1, the refractive index at the current position
n1, and the refractive index at the new position n2 as arguments. It should return the direction vector at the new
position s2.
p p
Test your function using an initial directon vector of s1 = [ 2, 2] and
a) n1 = n2 = 1 (air to air)
b) n1 = 1, n2 = 1.5 (air to glass)

Write your answers below.

1 function s2 = refract_ray(s1, n1, n2)


2 s1x = s1(1);
3 s1y = s1(2);
4

5 theta_i = asind(abs(s1x));
6 theta_r = asind(n1*sind(theta_i)/n2);
7

8 s2(1) = sign(s1x)*sind(theta_r);
9 s2(2) = sign(s1y)*cosd(theta_r);
10 end
p p
(a) s2 = [ (2), (2)]
(b) s2 = [0.47, 0.88]
In the case there the refractive indices are the same the ray should continue in a straight line.

10
LAB FOUR PHYS2011/2911 Computational Physics

Question 10
Create a copy of your program from Question 8 and modify it so that at each iteration it calls refract_ray to
take account of possible changes in the refractive index.
As a test, use a uniform refractive index of n = 1. Run your code and check that it produces straight lines.

Question 11
The final stage of our simulation is modelling the refraction of light as it passes from air downward into a slab of
glass.
The refractive index for the air-glass system is
(
1.5 y 0.5
n(r) = (4.12)
1.0 y > 0.5.

Write a function called n = air_glass_interface(r) that takes a position vector r and returns the refractive
index at that position, as given by Equation (4.12).
You should incorporate this function into the main loop of your simulation.
Add the line of code
1 plot([0 Lx], [Ly/2,Ly/2], 'b-');

to the plotting portion of your code to draw a horizontal line showing the air-glass interface.
Use your program to trace a ray from the top left corner (r0 = (0, 1)) of the domain moving in a direction 0 = 45
to the horizontal. Draw the ray path in the box below.

Tutor note: check their initial position vector is [0, 1] (i.e. top left corner).
Also, you need to calculate n1 at the current position, and n2 at the next position (see solution code).

Checkpoint 2:

11
LAB FOUR PHYS2011/2911 Computational Physics

4.9 Challenge: Total internal reflection


Total internal reflection is the phenomena where a ray is completely reflected from a transparent boundary. It
occurs when a ray passes from a region of high refractive index to a region of low refractive index, but only when
the angle of incident is large than the critical angle c defined by

n
sin c = 2 . (4.13)
n1

We will need to account for this phenomenon in our ray tracing code. In our model where n only depends on y,
the direction of the reflected ray is

s2 = s1x x s1y y , (4.14)

i.e. the y component changes sign, and the x component is unchanged.


Modify your solution to Question 11 to account for total internal reflection. To do this your need a way of detecting
when the conditions are met for total internal reflection to occur. One way is to notice that when the incident angle
exceeds c , the quantity

n1
sin 1 (4.15)
n2

is greater than unity. When this occurs the angle of refraction 2 = sin 1 (n1 /n2 sin 1 ) becomes meaningless,
because the inverse sine of a number greater than one is imaginary. Modify refract_ray.m so that the new
direction is computed using Equation (4.10) if (n1 /n2 ) sin 1 1, and is computed using Equation (4.14) when
(n1 /n2 ) sin 1 > 1.

Question 12
Using air_to_glass_interface.m to compute n, draw a ray starting at r0 = (0, 0) with initial angle 0 = 45 .
Use a step-size of h = 0.05. Draw the ray path in the box provided.

12
LAB

FIVE

Introduction to Fourier Transforms


5.1 Introduction
A time-varying signal such as a sound wave can either be described as amplitude as a function of time, or amplitude
as a function of frequency. These are two equally valid ways of describing the signal. The same idea holds for
spatially-varying signals too, where the independent variable is space rather than time. Fourier analysis is the
technique of converting between these two different viewpoints, i.e. taking a signal and decomposing it into its
frequency components. This operation is called a Fourier transform.
The basis functions of the frequency domain are sinusoids, which means that you can build up any function by
combining sinusoids (each representing one frequency) of the appropriate amplitudes and phases. Jean Bap-
tiste Joseph Fourier showed in 1807 that for continuous periodic functions, you only need to combine sinusoids
with frequencies that are an integer multiple of the fundamental frequency. Non-periodic functions can also
be built from sinusoids, but this requires that a continuous summation (i.e. an integral) be taken over them.

Frequency decomposition is an important concept, because there


are many applications whose natural measurement space is the fre-
quency domain of the quantity we are actually after. These include
X-ray crystallography, Fourier transform spectroscopy, and radio
and optical interferometry. For example in X-ray crystallography,
the peaks in the X-ray diffraction pattern tell you which families of
atomic planes (i.e. spatial frequencies) are present, and this can be
used to deduce the arrangement of atoms in the crystal. The law that
governs this is the famous Braggs law of X-ray diffraction, named
after William Henry Bragg and his son, William Lawrence Bragg,
who in 1913 successfully applied this to analysing the atomic struc-
ture of sodium chloride.
Since continuous functions cannot be exactly represented by digi- Figure 5.1: The historic Photo 51,
tal computers (the signal must always be discretised and of finite showing the X-ray diffraction pattern
length), computers perform a Discrete Fourier Transform (DFT) of DNA taken by Rosalind Frankin
rather than a true continuous Fourier transform. DFTs can be eval- and Ray Gosling in 1952, from which
uated efficiently on computers thanks to the Fast Fourier Transform the double-helix structure was deduced
(FFT) algorithm, developed by Gauss in 1805 and later rediscovered (source: http://www.bbc.com/
by Cooley and Tukey in 1965. In this lab we will explore how to news/health-18041884).
do one-dimensional Fourier Transforms with MATLAB, and in the
following labs extend this analysis to two dimensions.

5.2 Lab objectives


By the end of this lab session you should be able to:

1. Understand the concept of frequency decomposition.


2. Use fft to perform discrete Fourier transforms and be familiar with its output format.
3. Understand the importance of the Nyquist limit.

If you dont know how to do any of these things once you have completed the lab, please ask your tutor for help.
You should also use these lists of objectives when you are revising for the end of semester exam.

PHYS2011/2911 Computational Physics 1


LAB FIVE PHYS2011/2911 Computational Physics

5.3 Fourier transforms


Suppose we have a function y(x) defined along 1 < x < +1, where x represents the independent variable (this
could be space, time, etc.). The key concept of Fourier analysis is that this function can alternatively be described
as a combination of frequencies Y( f ), where f denotes frequency. If x is a spatial coordinate then f is a spatial
frequency (also called a wavenumber, or the number of oscillations per unit length). If x is a time coordinate then
f is a temporal frequency (the number of oscillations per unit time). The complex amplitude of the sinusoid of
frequency f that goes into building y(x) is given by
Z +1
Y( f ) = y(x)e 2i f x dx , (5.1)
1

where the units of f are the reciprocal of the units of x. For example, if x is measured in seconds, then f has units
of hertz (s 1 ). We say that Y( f ) is the Fourier transform of y(x).
There are multiple conventions for defining Y( f ), sometimes with factors of 2 1 or p1 out the front. The frequency
2
variable f is also sometimes defined with the factor of 2 in the exponent absorbed into it. In such cases, the units
of f will be slightly different, e.g. radians per second rather than hertz, if x is in seconds. However, we are going
to stick with the definition of f without it absorbing the factor of 2, because this makes it more straightforward
to interpret the units as just plain reciprocals of the original units.
Computers cannot store and represent continuous functions over infinite domains, so they must instead make do
with a discrete and finite version of Eq. (5.1). In MATLAB, the discrete Fourier transform or DFT is evaluated by
the inbuilt fft function as the sum

N
X
Y(k) = y( j)e 2i( j 1)(k 1)/N , (5.2)
j=1

where N is the number of measurements, and j and k are the indices of the arrays y and Y, respectively. An
important point to note is that the individual data points must be evenly spaced for Eq. (5.2) to hold, i.e. the fft
function can only be used to analyse data taken at regular intervals.

5.4 MATLABs fft function


For an input signal described by a vector of data points y, its discrete Fourier transform Y can be computed using
the fft function:
1 >> Y = fft(y);

The entries of Y will in general be complex numbers, encoding the amplitudes and phases of each frequency
component present in the input vector y. Each entry of Y corresponds to one frequency.
It is important to understand the output format of the function fft, i.e. what frequencies each element of the array
Y corresponds to. This differs depending on whether the input vector y contains an odd or an even number of
elements. The rules for this are as follows:

1. The number of entries in y and Y are always equal.


2. The first entry in Y always corresponds to the zero-frequency (i.e. constant offset) component.
3. Suppose that the values in y are sampled at a cadence/spacing of dx for a range 0 to L. If y has an even
number of elements, then the frequencies of the entries in Y are given by the ordered sequence
" #
1 2 1 1 2 2 1
feven = 0, , , , Nq , Nq, Nq + , Nq + , , , , (5.3)
L L L L L L L

where
1
Nq = (5.4)
2dx
is known as the Nyquist frequency.

2
LAB FIVE PHYS2011/2911 Computational Physics

4. If y has an odd number of elements, then the frequencies of Y are instead


" #
1 2 1 1 3 2 1
fodd = 0, , , , Nq , Nq + , Nq + ,, , . (5.5)
L L 2L 2L 2L L L

Notice the abrupt jump from positive to negative frequencies near the middle of each array. This ordering stems
from the way MATLAB implements its FFT algorithm. Equations (5.3) and (5.5) are summarised schematically
in Fig. 5.2.

Figure 5.2: Output format of MATLABs fft function, where the array elements are labelled with their associated
frequencies. When the number of samples is even, fmax = Nq L1 and fmin = Nq. When the number of samples
is odd, fmax = Nq 2L 1 and f 1
min = Nq + 2L .

Negative frequencies appear naturally when we use complex exponentials to represent sinusoids. For example,
a sine wave can be expressed as the linear combination of two complex exponentials with positive and negative
frequencies + f and f :

1 2i f x
sin 2 f x = (e e 2i f x ) . (5.6)
2i
Both positive and negative frequencies are necessary to fully describe functions if we use complex arithmetic. If
the signal is purely real, then it turns out that the negative-frequency components are redundant (their amplitudes
are complex conjugates of the corresponding positive-frequency components) so in this case they can just be
ignored. In these labs we will not deal with any complex input signals.
None of the frequencies in Equations (5.3) and (5.5) exceed Nq in absolute value. As we will discuss in more
detail later, Nq is the highest frequency that can be measured from an input signal given a fixed sampling rate. It
is an important concept in the context of discrete signal processing, because it specifies the limit on the highest
frequency than can be reconstructed accurately from any data.
Question 1
If a signal is sampled at a cadence of dx = 2 s for a duration of L = 10 s, use Equation 5.5 to calculate the
frequencies corresponding to the elements of the array output by fft. There are an odd number of samples and
therefore frequencies, so we will call this vector fodd. What are the correct units?

fodd = [0, 0.1, 0.2, 0.2, 0.1] (units of Hz, or s 1 )


Nq = 1/2dx = 1/(2 2) = 1/4 = 0.25
Tutor note: this question is a by-hand calculation - you dont need fft()

Question 2
If a signal is sampled at spatial intervals of dx = 0.5 m over a length of L = 4 m, use Equation 5.3 to calculate the
frequencies corresponding to the elements of the array output by fft. There are an even number of samples and
therefore frequencies, so we will call this vector feven. What are the correct units?

[0, 0.25, 0.5, 0.75, 1, 0.75, 0.5, 0.25] (units of m 1 )


Tutor note: this question is a by-hand calculation - you dont need fft()

3
LAB FIVE PHYS2011/2911 Computational Physics

5.5 MATLABs fftshift function


If you wanted to plot the output of fft versus frequency, you would need to accommodate for the awkward
ordering of frequencies. MATLAB has an inbuilt function called fftshift that is designed for this purpose.
fftshift takes a vector output by fft and re-orders it such that the negative frequencies are placed to the left
of the positive frequencies. After this operation, all frequencies will be in ascending order. The result is shown
schematically in Fig. 5.3 (compare this to Fig. 5.2).

Figure 5.3: The resultant frequency ordering of a vector generated by fft, after it has been passed to fftshift.
fmin and fmax refer to the same quantities mentioned in Fig. 5.2.

Question 3
Apply fftshift to the vectors of frequencies fodd and feven you found in Questions 1 and 2. Write down the
resultant vectors.

1 fftshift([0, 0.1, 0.2, -0.2, -0.1])


2 ans = -0.2000 -0.1000 0 0.1000 0.2000
3

4 fftshift([0, 0.25, 0.5, 0.75, -1, -0.75, -0.5, -0.25])


5 ans = -1.0000 -0.7500 -0.5000 -0.2500 0 0.2500 0.5000 0.7500

5.6 How to compute and plot a Fourier transform


We will now put this together to calculate the Fourier transform of an input signal. Lets start with a sine wave
(Equation 5.6) of frequency f = 3 sampled with dx = 0.01 over a range of L = 2. We can create the input signal
and plot it like this:
1 dx = 0.01;
2 L = 2;
3 x = dx:dx:L;
4 f = 3;
5 y = sin(2*pi*f*x);
6 plot(x, y, 'o');
7 xlabel('x');
8 ylabel('y(x)');

resulting in the plot in the left panel of Figure 5.4. We can then calculate the Fourier transform, reorder the
frequency components using fftshift and plot the results. In MATLAB this is:
1 Y = fft(y);
2 F = fftshift(Y);
3 Nq = 0.5/dx;
4 freqs = -Nq : 1/L : Nq-1/L;
5 sqmod = abs(F).2;
6 plot(freqs, sqmod);
7 xlabel('f');
8 ylabel('|F|2');

which results in the plot in the right panel of Figure 5.4. The two spikes you see represent the two complex
exponential terms appearing on the RHS of Equation (5.6), which have frequencies +3 and 3 for this example
(the input sine wave, sin 2 f x, had f = 3).
Since the output amplitudes are complex, it is usually the modulus or the squared modulus that is plotted as a
function of frequency. Both the modulus and squared modulus of a complex number are real numbers. The more

4
LAB FIVE PHYS2011/2911 Computational Physics

physically meaningful quantity in an optics context is the squared modulus, because the intensity of a diffraction
pattern is directly proportional to the squared modulus of the Fourier transform of the aperture.
Because the input signal is real, the output complex amplitudes of the components with frequencies + f and f for
a given f found in the array Y are complex conjugates of one another. Their squared moduli are therefore equal.
Hence if the input signal is real, the plot of the squared modulus as a function of frequency will be symmetric
about f = 0. For this reason, you will sometimes see just the positive frequencies being plotted.
An important thing to do is to put the correct numbers on the frequency axis. The rules in Section 5.4 tell us that if
y has an even number of elements, the minimum and maximum frequencies are fmin = Nq and fmax = Nq L1 ,
otherwise if y has an odd number of elements, the minimum and maximum frequencies are fmin = Nq + 2L 1 and

fmax = Nq 2L 1 . In both cases, the frequency step size is 1 . Recall that Nq = 1 . Applying these rules to this
L 2dx
example, we constructed the vector of frequency values freqs = -Nq : 1/L : Nq-1/L.

Figure 5.4: (a) A sine wave and (b) its Fourier transform.

Question 4
In Section 5.6 we constructed a vector of frequencies using the command freqs = -Nq : 1/L : Nq-1/L,
where Nq is the Nyquist frequency and L is the range of the data. This expression is the fftshifted version of
Equation (5.3), and is relevant for cases where there are an even number of samples. Write down the command
you would use to construct the frequency vector freqs if there were an odd number of samples.

freqs = -Nq+1/(2*L) : 1/L : Nq-1/(2*L)

Question 5
Consider a waveform comprising a superposition of three sinusoids with frequencies f1 , f2 and f3 , which has the
functional form

y(x) = sin(2 f1 x) + sin(2 f2 x) + sin(2 f3 x) . (5.7)

Set f1 = 0.5, f2 = 2 and f3 = 5, and sample this at the points x = dx:dx:L, where dx = 0.05 and L = 10.
Sketch the resulting signal below.

5
LAB FIVE PHYS2011/2911 Computational Physics

1 dx = 0.05;
2 L = 10;
3 x = dx:dx:L;
4 y = sin(2*pi*0.5*x) + sin(2*pi*2*x) + sin(2*pi*5*x);
5 plot(x, y)
6 xlabel('x')
7 ylabel('y(x)')

Question 6
Now compute and plot the squared modulus of its Fourier transform. Use Equation (5.3) to work out the frequen-
cies that should go on the horizontal axis. Verify that the peaks appear at the correct frequencies.

1 Y = fft(y);
2 F = fftshift(Y);
3 Nq = 0.5/dx;
4 freqs = -Nq : 1/L : Nq-1/L;
5 sqmod = abs(F).2;
6 plot(freqs, sqmod);
7 xlabel('f');
8 ylabel('|F|2');

The peaks should occur at f = 0.5, 2, 5.

Checkpoint 1:

6
LAB FIVE PHYS2011/2911 Computational Physics

5.7 Aliasing and the Nyquist limit


The Nyquist limit is the highest frequency that can be reconstructed from a discretely-sampled signal. Imagine
you are filming a spinning object, which could be a wheel or a propeller, at some given frame rate, e.g. 30 frames
per second. If the object were to rotate at exactly 30 revolutions a second, then the video would appear to show
the object completely still and non-rotating. Someone watching the video would incorrectly conclude that the
frequency of rotation was zero. For a video demonstration of this effect, see

http://www.youtube.com/watch?v=VNftf5qLpiA

Whats happening is that above a certain threshold, the sampling rate is not high enough to catch the rotation of
the object. The object may appear on film to rotate more slowly than it actually is, or even rotate in the opposite
direction. This effect where measured frequencies differ from actual frequencies because of too low a sampling
rate is known as aliasing, and the threshold signal frequency above which this occurs (for a given sampling rate)
is called the Nyquist frequency. Figure 5.5 shows a schematic of how aliasing for a rotating wheel occurs.

Figure 5.5: Snapshots of a clockwise-rotating wheel at a fixed sampling rate and different rotation speeds. In
the third row, it is not possible to distinguish this from an anticlockwise rotation of 1 rev/s with 1/4 of a rotation
between snapshots. (Source: http://derek.dkit.ie/graphics/aliasing/aliasing.html).

The Nyquist frequency is always equal to half the sampling frequency ( f s ):

Nq = 0.5 f s (5.8)

which is another way of writing Equation (5.4). For example, if you are trying to measure a time-varying signal
and are sampling at 10 Hz, then the highest frequency you can accurately reconstruct from your data is 5 Hz. If
the signal frequency exceeds 5 Hz, then you will instead measure a signal of frequency lower than 5 Hz, and we
say that the signal has been aliased.
We are now going to explore what happens when we sample a given signal at different rates.
Question 7
Consider a signal oscillating at a frequency of 20 Hz. At what cadence dt must we sample in order to accurately
reconstruct the waveform? Give your answer in seconds.

To reconstruct the signal accurately, we need to sample at at least 40 Hz, which corresponds
to a cadence of dt = 0.025 s.

Question 8
Construct a sinusoidal wave with a frequency of f = 20 Hz over a 1 s interval, using a grid spacing of
delt = 0.005 s. You can define the time vector to be t = delt:delt:1.
Sample this waveform at a cadence of = 0.2dt, seconds, by extracting values only every seconds,
where dt is the answer to Question 7. You can do this using MATLAB array slice notation, for example
t1 = t(1:tau/delt:end) where tau is the desired cadence.

7
LAB FIVE PHYS2011/2911 Computational Physics

Sketch the original signal and its Fourier transform below. This sampling cadence is five times higher than the
Nyquist frequency, so there should be no aliasing. Check that the resulting frequency components make sense.

The peaks appear at 20 Hz for = 0.2dt.

Question 9
Now experiment with different values of to see what happens when we change the sampling rate (cadence).
Loop through a range of values (e.g. 0.2dt, 0.8dt, 1.0dt, 1.6dt) and compute and plot the Fourier transform for
each case.
At which frequencies do the peaks appear, and how does this compare to the Nyquist frequency for that value of
? At which cadence(s) do you see evidence for aliasing?

The peaks appear at 20 Hz for = 0.8dt and 1.0dt, and 5 Hz for = 1.6dt. The correspond-
ing Nyquist frequencies are 1/2 = 25 Hz, 20 Hz and 12.5 Hz, respectively. The frequency is
measured accurately for the first two values of , but there is aliasing when = 1.6dt. For the
first two values of the signal frequency does not exceed the Nyquist frequency, but it does for
= 1.6dt.

Tutor note: to loop through automatically, students will have to have an if statement to deal with the
case of even number of points and an odd number of points (see solutions). You may want to show
them how to use subplots, but producing multiple plots is fine.

8
LAB FIVE PHYS2011/2911 Computational Physics

5.8 Fourier transform of a noisy signal (PHYS2911)


Signals measured in real life are often corrupted by noise. A common type of noise is white Gaussian noise.
Gaussian means that the perturbation from the true signal at each measurement point is a random number drawn
from a Gaussian distribution, and white means that no two perturbation values in the series are correlated.
We will now investigate what happens to the Fourier transform of a signal corrupted by white Gaussian noise, using
the waveform you constructed in Question 5. A vector of uncorrelated, Gaussian-distributed random numbers can
be generated by g = randn(size(x)); where x is the vector of data points. By default, randn generates
Gaussian noise with a characteristic amplitude of 1.
Question 10 (PHYS2911)
Generate a vector of Gaussian noise using the above command, add this on to the signal you created in Question
5, and plot the result. Sketch your plot below. If you didnt already know that the signal contained three periodic
components, would you have been able to guess just by looking at it?

The waveform is now extremely corrupted and it is not possible to visually identify the pres-
ence of periodic components. By eye, it looks indistinguishable from random chaotic noise.

Question 11 (PHYS2911)
Now compute the Fourier transform of this signal and plot the squared modulus of the result. How does it differ
from your answer to Question 6? Can you suggest why Fourier transforms are useful for analysing noisy signals?

Although the waveform is so corrupted, the spectral peaks are still prominent. This demon-
strates that Fourier transforms can easily recover periodic signals that have been corrupted
by white Gaussian noise, even when the noise levels are significant. They are very useful for
identifying periodic signals buried within noise.

Checkpoint 2:

9
LAB FIVE PHYS2011/2911 Computational Physics

5.9 Challenge: The Fourier transform phase


A complex number z can in general be expressed in terms of an amplitude r and phase , as z = rei . When we
take the squared modulus of a complex number, this is the operation of multiplying it by its complex conjugate,
i.e. |z|2 = zz = rei re i = r2 . Since |z|2 does not depend on , the operation of taking the squared modulus
removes information about the phase . While phases are not important for some applications, they turn out to
be a crucial pieces of information if we want to reconstruct the original waveform. We will now explore the
consequences of modifying the phases of a Fourier transform.
The example we are going to use is a sawtooth function, which can be generated using the inbuilt MATLAB
function sawtooth, e.g.
1 >> x = 0.2:0.2:6*pi;
2 >> s = sawtooth(x);

The resultant function looks like the one shown in Fig. 5.6.

Figure 5.6: A sawtooth function.

Question 12
Generate a sawtooth function using the above commands and compute its Fourier transform. Decompose this into
amplitude and phase values, which you can achieve using the MATLAB functions abs and angle, respectively.
Store these in two variables r and . Plot r and to see what they look like.

10
LAB FIVE PHYS2011/2911 Computational Physics

The MATLAB function for taking the inverse Fourier transform to recover the original function is ifft. This
is an exact inverse of fft, in that any input x should be equal to ifft(fft(x)). If the original signal is real,
then its Fourier transform should be Hermitian and taking the inverse Fourier transform should again recover
the purely real input. However, internal roundoff error can sometimes lead to the appearance of small imaginary
components in the inverse-Fourier-transformed signal. This can be suppressed by invoking the ifft function with
the 'symmetric' option, e.g.
1 >> X = ifft(x, 'symmetric');

An important point to note is that ifft expects input of the format output by fft, i.e. with the strange frequency
ordering. If you used fftshift to reorder the array, you need to first put it back using fftshifts inverse
function, ifftshift, before you pass it to ifft. E.g. if you started off with some data a, the commands
1 >> A = fftshift(fft(a));
2 >> b = ifft(ifftshift(A), 'symmetric');

will recover a vector b that is identical to a.


Question 13
Use the ifft function with the 'symmetric' option to compute the inverse Fourier transform of

1. rei , i.e. the unmodified Fourier transform, and

2. rei0 = r, i.e. the Fourier transform of the sawtooth function with all phases set to zero.

Overplot these and comment on the similarities/differences. The waveform you obtain for part 1 should look
identical to the one plotted in Fig. 5.6.

The two functions have the same overall periodicities and peak in the same places, but their
shapes are very different.

Question 14
What information is encoded in the phase of a sinusoidal wave? Why would changing the phases modify the shape
of a periodic waveform but preserve its overall periodicity?

The phase of a sinusoid encodes its horizontal displacement. Changing the phases of the
various sinusoidal components changes their positions relative to each other, and therefore
where they constructively/destructively add to produce different features of the waveform.
The dominant period is not changed because the relative amplitudes of the sinusoids dont
change when the phase is modified, so the frequency component that had the largest amplitude
in the original signal will still be the one with the largest amplitude after the phases have been
changed.

11
LAB

SIX

Two-dimensional Fourier Transforms


6.1 Introduction
In this lab we will use two-dimensional Fourier transforms to simulate a famous historic experiment, the Youngs
double-slit experiment, devised by Thomas Young in 1801. This was the first demonstration of the wave nature of
light, where the diffraction of light upon passing through two narrow slits formed interference fringes on a distant
screen. Two-dimensional Fourier transforms are closely related to the phenomenon of diffraction in optics. The

Figure 6.1: Interference pattern formed by shining lasers of different wavelengths through a double-slit aperture
(source: http://tsgphysics.mit.edu).

diffraction pattern produced on a distant screen is the 2D Fourier transform of the aperture. The size and shape
of the aperture directly influence the size and shape of the diffraction pattern in a very important way, which you
will investigate in this lab. Along the way you will learn how to handle 2D arrays in MATLAB, and also several
tips and tricks for visualising them.

6.2 Lab objectives


By the end of this lab session you should be able to:

1. Use fft2 to perform DFTs on two-dimensional data and be familiar with its output format.

2. Know the basics of 2D array manipulation in MATLAB.

3. Know how to simulate Youngs double-slit experiment in MATLAB.

4. Understand how the size/shape of a function and the size/shape of its Fourier transform are related.

If you dont know how to do any of these things once you have completed the lab, please ask your tutor for help.
You should also use these lists of objectives when you are revising for the end of semester exam.

PHYS2011/2911 Computational Physics 1


LAB SIX PHYS2011/2911 Computational Physics

6.3 Walkthrough: 2D arrays in MATLAB


This lab will make use of MATLABs powerful capabilities for generating and manipulating 2D arrays. Below is
a brief introduction to some of the functions and operators we will be using.

6.3.1 Creation
There are many ways to create 2D arrays. One way is using the MATLAB function zeros, which produces an
array of zeroes. The integers passed as arguments to zeros correspond to the desired dimensions of the output
array. The first number passed is the number of rows, the second number the number of columns, and so on. For
example, to produce a 2D array A of zeroes with 3 rows and 5 columns, do
1 >> A = zeros(3,5)
2 A=
3 0 0 0 0 0
4 0 0 0 0 0
5 0 0 0 0 0

Another way to create 2D arrays is using the meshgrid function. This is very useful for creating arrays that
represent the coordinates of some other array, which might contain the values of measurements at those coordi-
nates. For example, if you had a 2D grid of measurements taken at coordinates x = [0.1,0.2,0.3,0.4] and
y = [0.02,0.04,0.06] (i.e. each value of x for each value of y), then you could form the 2D coordinate grids
as follows:
1 >> x = [0.1, 0.2, 0.3, 0.4];
2 >> y = [0.02, 0.04, 0.06];
3 >> [Mx, My] = meshgrid(x,y)
4 Mx =
5 0.1000 0.2000 0.3000 0.4000
6 0.1000 0.2000 0.3000 0.4000
7 0.1000 0.2000 0.3000 0.4000
8

9 My =
10 0.0200 0.0200 0.0200 0.0200
11 0.0400 0.0400 0.0400 0.0400
12 0.0600 0.0600 0.0600 0.0600

6.3.2 Manipulation
If two arrays A and B have the same dimensions, you can perform element-wise addition by using the + operator,
i.e. the element-wise sum of A and B is A+B. The resultant array has the same dimensions as A and B.
You can reference single elements in 2D arrays by using parentheses and indexing the entries by two integers, the
first corresponding to the row and the second corresponding to the column. For example, the value of the entry
in the third row and second column of an array C is C(3,2). To reference a range of entries, use the colon (:)
operator. For example, to output an array containing just the entries between the second to sixth rows in the fifth
column of an array D, type D(2:6,5). Note that the slice notation is inclusive, i.e. 2:6 will retrieve the second
and sixth rows, as well as everything in between. The resultant array in this example will have 5 rows and 1
column.

6.4 Walkthrough: 2D Fourier transforms


Multi-dimensional Fourier transforms are what you get when you apply one-dimensional Fourier transforms suc-
cessively to each dimension in turn. If you have a function z(x, y) defined along 1 < x, y < +1, where x and
y are two independent coordinates (they could be two spatial dimensions, or one spatial and one time dimension,
etc.), then its two-dimensional Fourier transform is given by
Z +1 Z +1
Z( f x , fy ) = z(x, y) e 2i( f x x+ fy y) dx dy , (6.1)
1 1

where f x and fy are the frequencies corresponding to the x and y coordinates, respectively.

2
LAB SIX PHYS2011/2911 Computational Physics

The MATLAB function for performing the two-dimensional Fourier transform is fft2, which is really just two
nested ffts in disguise: given an input 2D array x, the result of fft2(x) is the same as fft(fft(x).').',
where the .' operator in MATLAB transposes the array (i.e. flips rows and columns). Note that when fft is
passed a 2D array rather than a vector, it performs a one-dimensional DFT along each individual column.
Just like for the fft function we used in the previous lab, the frequencies corresponding to the elements of
the array output by fft2 are in a semi-jumbled order, with the negative frequencies occurring after the positive
frequencies along each axis. To re-order the array such that all frequencies are in ascending order along each axis,
we can use the same fftshift function from before, which works just as well on multi-dimensional arrays as it
does on vectors. The same odd/even rules for fft stated in the previous lab apply for fft2, now separately for
each dimension. The effect of applying fftshift to a 2D array is illustrated in Fig. 6.2.

Figure 6.2: What the fftshift function does to a 2D array. Credit: MATLAB documentation.

Lets now put all these functions together in an example of a 2D Gaussian. You may recall Gaussian functions
as the bell-curves from statistics. Among their many special properties, they have the property that the Fourier
transform of a Gaussian is another Gaussian. In two dimensions, a Gaussian function centred at the origin has the
following functional form:
0 1
BB x2 y2 CCCC
g(x, y) = exp BBB@ CA (6.2)
2 2x 2 2y

where x and y are the standard deviations (widths) in the x and y directions.
A 2D Gaussian centred at the origin with x = 0.2 and y = 0.1 on a 4 4 grid with spatial resolution 0.04 units
can be constructed using the following commands:
1 sig_x = 0.2;
2 sig_y = 0.1;
3 delt = 0.04;
4 L = 4;
5 x = -L/2:delt:L/2;
6 y = -L/2:delt:L/2;
7 [Mx, My] = meshgrid(x,y);
8 g = exp(-Mx.2/(2*sig_x2) - My.2/(2*sig_y2));
9 figure; imshow(g, 'XData', x, 'YData', y)
10 axis on;
11 xlabel('x'); ylabel('y')

The command axis on makes the axis ticks appear, since imshow leaves this off by default. You can compute
and display the Fourier transform of this Gaussian function using the following commands:
1 G = fftshift(fft2(g));
2 Nq = 0.5/delt;
3 Fx = -Nq+0.5/L : 1/L : Nq-0.5/L;
4 Fy = -Nq+0.5/L : 1/L : Nq-0.5/L;
5 figure; imshow(mat2gray(abs(G.2)), 'XData', Fx, 'YData', Fy)
6 axis on;
7 xlabel('Fx'); ylabel('Fy')

The resulting plots are shown in Fig. 6.3 below.

3
LAB SIX PHYS2011/2911 Computational Physics

Figure 6.3: A Gaussian function (left) and its Fourier transform (right).

The imshow function is handy for visualising 2D arrays, but note that it shades the output plot assuming that the
data lie between the range 0 and 1. Any values below 0 get assigned to black, and any above 1 get assigned to
white. To improve the contrast when displaying arbitrary data with imshow, the function mat2gray will linearly
rescale an input array such that the minimum value is mapped to 0 and the maximum value is mapped to 1. We
needed to use imshow together with mat2gray when plotting the Fourier transform in the above example because
its amplitudes were outside the range 0 to 1.
In the absence of any other input arguments, imshow will label its axes with the pixel coordinates (e.g. if you
simply executed the command imshow(g)). If you want to put your own values on the axes, e.g. the frequen-
cies Fx and Fy of the 2D Fourier transform, you can specify these using the options 'XData' and 'YData' as
demonstrated above.

6.5 Activity: Light on a rectangular aperture


When parallel wavefronts impinge upon an aperture, each point within the aperture acts as a source of secondary
wavelets, in accordance with the Huygens-Fresnel principle. These wavelets constructively and destructively
interfere, producing a series of bright and dark regions on a distant screen. When the screen is sufficiently distant,
namely when the distance-to-aperture-size ratio greatly exceeds the aperture-size-to-wavelength ratio, we are in
the Fraunhofer regime and the intensity pattern on the screen is proportional to the squared modulus of the 2D
Fourier transform of the aperture.
An aperture can be simulated in MATLAB as a 2D array, by putting a 1 at every point where light can come
through and a 0 everywhere else. To compute the Fraunhofer diffraction pattern, we then Fourier transform the the
2D array representing the aperture using fft2 and plot the squared modulus of the result. (You might recall from
lectures that although the electric field E of the light waves is what interferes to produce the diffraction pattern, it
is the intensity |E|2 that is actually observed).
In this section we will start off by simulating diffraction for a simple rectangular aperture, and later upgrade this
to two slits for Youngs double-slit experiment.
Question 1
Write a function rect = rect_aperture(r1, c1, r2, c2) that constructs a rectangular aperture on a 512
1024 grid, where the top-left corner of the rectangle has row, column coordinates r1, c1 and the bottom-right
corner has coordinates r2, c2.
Hint: you can use array slice notation of the form A(r1:r2,c1:c2) to select the rectangular region bounded
between rows r1 and r2, and columns c1 and c2 (inclusive) within the array A.
Test out this function by using it to generate a rectangular aperture 20 pixels high and 100 pixels wide. The top
left corner should be at row, column coordinates of (247, 463). This corresponds to the rectangle being roughly at
the centre of the grid.
Display your result using imshow(rect) with axis on to check the rectangle appears at the right location.
Sketch your plot below.

4
LAB SIX PHYS2011/2911 Computational Physics

1 function rect = rect_aperture(r1, c1, r2, c2)


2 rect = zeros(512, 1024);
3 rect(r1:r2, c1:c2) = 1;
4 end
5

6 >> rect = rect_aperture(247, 463, 247+19, 463+99);


7 >> imshow(rect)
8 >> axis on

Question 2
Compute and plot the squared modulus of the 2D Fourier transform of the array you constructed in Question
1, using MATLABs fft2 and fftshift functions. Remember to use the mat2gray function to rescale the
amplitudes between 0 and 1, so that imshow plots this properly.
Plotting tip: To adjust the brightness scale on the output plot, the command
1 >> colormapeditor

brings up a GUI that allows you to make instant changes. Change Color data max from 1.0 to 0.01 to enhance
the features of the pattern. If you like, you can select between a range of inbuilt colour schemes (click on Tools !
Standard Colormaps). Clicking and dragging on the colour bar allows you to stretch or compress certain ranges,
and you can even add your own colours.

1 >> R = fftshift(fft2(rect));
2 >> imshow(mat2gray(abs(R).2))

Tutor note: make sure students change the intensity scale of the plot, as described above, otherwise
they wont be able to see any of the features.

5
LAB SIX PHYS2011/2911 Computational Physics

Question 3
Now lets see what happens when we shrink the horizontal width of the aperture by a factor of 2, such that it now
has 50 columns and its top-left corner is located at row, column coordinates of (247,487). Compute and plot the
squared modulus of its 2D Fourier transform. How does this differ from the diffraction pattern in the previous
question?

The diffraction pattern stretches by roughly a factor of 2 in the horizontal direction,


compared to the diffraction pattern in Question 2.

Question 4
Based on your answer to Question 3, what can you say about the relationship between the characteristic size of
the aperture and that of the diffraction pattern (i.e. Fourier transform)? Use this to explain the relative widths of
the diffraction pattern in Question 2 between the horizontal and vertical directions.

The characteristic width of the aperture and that of its Fourier transforms are inversely
related. If the aperture is narrow along a certain direction then its Fourier transform will be
wide along that direction. If the width of the aperture increases by a certain factor, the width
of its Fourier transform decreases by that factor and vice versa. We made no change to the
vertical width of the aperture between Questions 2 and 3, and so there was no change to the
vertical scale of the diffraction pattern. In Question 2 the diffraction pattern was wider in the
vertical direction than it was in the horizontal direction, because the aperture was narrower
in the vertical direction than the horizontal direction.

Checkpoint 1:

6
LAB SIX PHYS2011/2911 Computational Physics

6.6 Activity: Youngs double-slit experiment


We are now ready to simulate Youngs double-slit experiment. We will construct the two slits as two thin rectan-
gular apertures with the long axis oriented in the vertical direction, and compute the diffraction pattern using the
fft2 function. The squared modulus of the result corresponds to the intensity pattern one would see on a distant
screen if light were to be shone through the two slits.
In class, you would have treated Youngs double-slit experiment as a one-dimensional problem, assuming that the
slits were infinite in length. Here we will simulate this on a 2D grid, where both slits have a finite length. The
effect of giving the slits a finite length is to broaden the diffraction pattern along the direction in which the slits
are oriented. This bears closer resemblance to what would actually occur in reality.

Question 5
Using the function you wrote for Question 1, construct an aperture with two long, narrow vertical slits of width
1 and height 100, with their top edges aligned with row 207. Place one of them at column 500 and the other
at column 524. You can do this by constructing each slit separately, then adding the two arrays together using
MATLABs element-wise addition operation. Compute and plot the squared modulus of the 2D Fourier transform
of this aperture.

1 >> slit1 = rect_aperture(207, 500, 207+99, 500);


2 >> slit2 = rect_aperture(207, 524, 207+99, 524);
3 >> aperture = slit1 + slit2;
4 >> A = fftshift(fft2(aperture));
5 >> imshow(mat2gray(abs(A).2))

7
LAB SIX PHYS2011/2911 Computational Physics

Question 6
Now move the slits closer together by placing the first one at column 506 and the second one at column 518 (do
not change the size of each slit). How does the diffraction pattern change?

1 slit1 = rect_aperture(207, 506, 207+99, 506);


2 slit2 = rect_aperture(207, 518, 207+99, 518);
3 aperture = slit1 + slit2;
4 A = fftshift(fft2(aperture));
5 imshow(mat2gray(abs(A).2))
The pattern widens by a factor of two, i.e. the spacing between adjacent peaks doubles com-
pared to before.

Question 7
Slits of width 1 can be thought of as the numeric equivalent of -functions (infinitesimally thin spikes). We are
now going to see what happens if the slits have a finite width. Construct a double-slit aperture again, but this time
give the slits a width of 3 pixels. The top-left corners of the two slits should now be at row, column coordinates
of (207,505) and (207,517). Compute and plot the squared modulus of its 2D Fourier transform. How does this
differ from the pattern in the previous question?
Some features may be difficult to see with the default brightness scaling. Bring up the colormapeditor GUI
and change Color data max from 1.0 to 0.1 to enhance the contrast.

1 slit1 = rect_aperture(207, 505, 207+99, 505+2);


2 slit2 = rect_aperture(207, 517, 207+99, 517+2);
3 aperture = slit1 + slit2;
4 A = fftshift(fft2(aperture));
5 imshow(mat2gray(abs(A).2))
We still see a pattern of peaks, with the same spacing as before and in the same positions, but
the peaks near the centre are brightest and their brightness changes with horizontal location.
They reach minimum brightness at around 20% from the edges of the screen, and then become
brighter again as you move further out.

8
LAB SIX PHYS2011/2911 Computational Physics

Question 8 (PHYS2911)
Compute and plot the squared modulus of the 2D Fourier transform for a single slit of width 3 pixels, with the
top-left corner positioned at row, column coordinates of (207,512). You may want to set Color data max to
0.1 again to enhance the contrast. Can you guess how this pattern combines with the pattern from Question 6 to
produce the one in Question 7? The way in which these two patterns combine is known as convolution.

1 slit = rect_aperture(207, 512, 207+99, 512+2);


2 S = fftshift(fft2(slit));
3 imshow(mat2gray(abs(S).2))

The pattern in Question 7 is the product of this pattern and the one in Question 6. The double-
slit pattern where the two slits have finite width is the double-slit pattern for infinitesimally
thin slits, modulated by the pattern for a single slit of finite width.

6.7 Activity: Plane waves


A 2D plane wave is a function that oscillates sinusoidally in one direction and is constant along the orthogonal
direction. It has the example functional form

z(x, y) = cos(2 f x x + 2 fy y) , (6.3)

where f x and fy describe the projections of the oscillation frequency along the x and y axes. For example, a plane
wave with f x = 1 and fy = 2 experiences one oscillation every unit of x and two oscillations for every unit of
y. The lines of constant phase are given by f x x + fy y = constant. These lines are slanted with respect to the x
and y axes. The oscillation direction (the
q wavevector) is perpendicular to the lines of constant phase, and the
oscillation frequency f is given by f = f x2 + fy2 (see Fig. 6.4). These are the two-dimensional analogues of the
one-dimensional sinusoids you saw in the previous lab.
The following lines of code show how to construct a plane wave with these parameters and display it as a 3D
surface plot using the inbuilt MATLAB function surf.
1 x = 0.02:0.02:2;
2 y = 0.02:0.02:2;
3 [Mx, My] = meshgrid(x,y);
4 fx = 1;
5 fy = 2;
6 z = cos(2*pi*fx*Mx + 2*pi*fy*My);
7 surf(x, y, z, 'LineStyle', 'none')
8 xlabel('x'); ylabel('y'); zlabel('z')
9 axis([0 2 0 2 -3 3])

The surface plot generated by these lines of code is shown in Fig. 6.4.

9
LAB SIX PHYS2011/2911 Computational Physics

q p
Figure 6.4: Left: Surface plot of a 2D plane wave, with a frequency of f = f x2 + fy2 = 5. Right: The
corresponding wavevector, which lies in the x, y-plane.

Question 9
Construct a 2D plane wave with f x = 6 and fy = 5, over the the x-range x = 0.02:0.02:1 and y-range
y = 0.02:0.02:1. Display this as a surface plot like in the example.
Plotting tip: The command axis allows you to set the display range along the different axes of a plot. For a
three-dimensional plot such as a surface plot with axes x, y and z, you can set the display range by passing axis a
vector of the form [xmin xmax ymin ymax zmin zmax]. For this particular example, a suitable display range
for the plane wave turns out to be given by axis([0 1 0 1 -3 3]).

1 fx = 6; fy = -5;
2 x = 0.02:0.02:1;
3 y = 0.02:0.02:1;
4 [Mx, My] = meshgrid(x,y);
5 z = cos(2*pi*fx*Mx + 2*pi*fy*My);
6 figure; surf(x,y,z, 'LineStyle', 'none')
7 xlabel('x'); ylabel('y'); zlabel('z')
8 axis([0 1 0 1 -3 3])

10
LAB SIX PHYS2011/2911 Computational Physics

Question 10
Compute the squared modulus of its 2D Fourier transform, and display this as a surface plot. Remember to use
fftshift, and label the axes appropriately. Check that the peaks appear at the correct frequencies.
Tip 1: You can use the Data Cursor tool to query the coordinates of the peaks (the button for this has a black +
and a pale yellow box you can find this on every MATLAB figure panel).
Tip 2: To expand the data to fill all the plot space, use the command
1 >> axis tight

Tip 3: To change the transparency of the surface plot, invoke the 'FaceAlpha' option with a number between 0
(transparent) and 1 (opaque) when you call surf, e.g.
1 >> surf(x,y,z, 'FaceAlpha', 0.5)

to produce 50% transparency.

1 Z = fftshift(fft2(z));
2 Nq = 0.5/0.02;
3 Fx = -Nq : Nq-1;
4 Fy = -Nq : Nq-1;
5 figure; surf(Fx, Fy, abs(Z).2)
6 xlabel('Fx'); ylabel('Fy'); zlabel('|Z|2')
7 axis tight

Checkpoint 2:

11
LAB SIX PHYS2011/2911 Computational Physics

6.8 Challenge: Diffraction grating


Question 11
The Shah function is an infinite series of evenly-spaced spikes. Using the function you wrote in Question 1 (or
otherwise), construct a series of evenly-spaced slits tiled along the whole horizontal length of the grid, with a
spacing of 16 pixels. Compute and display the squared modulus of the Fourier transform of this pattern, using
imshow and mat2gray. (Although the array isnt infinite, it does reasonably well in replicating the actual Shah
function and its Fourier transform.) To improve the contrast, bring up the colormapeditor and set Color data
max to 0.01.
Aside: As you may have seen in class, an aperture constructed from a long series of regularly-spaced slits like this
is called a diffraction grating.

1 aperture = zeros(512,1024);
2 for i = 1:16:1024
3 aperture(207:207+99, i) = 1;
4 end
5 A = fftshift(fft2(aperture));
6 figure; imshow(mat2gray(abs(A).2))

Tutor note: You may need to zoom into the plots to convince yourself that all the evenly-spaced
lines are present, since these are quite thin.

Question 12
What property do you notice the Shah function sharing in common with Gaussians, but not plane waves?

The property the Shah function shares in common with Gaussians but not plane waves is that
its Fourier transform is a function of the same type, i.e. another Shah function. However, this
property does not hold for plane waves, whose Fourier transforms are -function spikes and
do not resemble the original function.

12
LAB

SEVEN

Radio Interferometry
7.1 Introduction
Observations in astronomy are often limited by the effects of diffraction. The angular resolution of a telescope
is of order /D, where is the observing wavelength and D is the diameter of the telescope (the Rayleigh cri-
terion). This means that when is large, D must be large to achieve a good resolution. The extreme case of a
diffraction-limited regime is radio astronomy, where the wavelengths (centimetres to metres) are comparable to
the physical size of the telescope components themselves. This makes high-resolution imaging challenging at
radio wavelengths. For example, if we were to build a radio telescope that had the same resolution as the Hubble
Space Telescope (which operates at visible wavelengths), the radio telescope would need to be as big as the Earth!

The birth of radio astronomy was marked by


Karl Janskys discovery of radio emission from
the centre of the Milky Way, which he an-
nounced in 1933. Subsequently, the develop-
ment of radio astronomy using radar equipment
left over from World War II was led by groups
from Cambridge University, and also the CSIRO
here in Australia. A clever technique to achieve
high angular resolutions without needing to build
an unreasonably large telescope is interferom-
etry, also called synthesis imaging. This was
developed in 1946 by the Australian pioneers
Lindsay McCready, Joseph Pawsey and Ruby
Payne-Scott, the last of whom was a graduate
of the University of Sydney. Radio interferom-
etry uses Fourier transforms to combine the sig- Figure 7.1: The Australian Telescope Compact Array, a 6 an-
nals measured by many different radio receivers, tenna radio interferometer located in Narrabri, NSW. Only 5
to achieve the equivalent resolution of a much antennae are visible in the image, the 6th is located 6 km away.
larger telescope with a diameter equal to the
spacings of the smaller receivers. This has made
high-resolution imaging possible at radio wavelengths. Thanks to these developments, Australia is now the world
leader in radio astronomy.
In this lab, you will learn the basics of how radio interferometers produce images of objects in the sky.

7.2 Lab Objectives


By the end of this lab session you should be able to:

1. Understand what a response function is and how it affects scientific measurements.

2. Use fft2 and ifft2 to perform two-dimensional convolution.


3. Understand the link between Fourier transforms and interferometry.

4. Simulate a multi-element interferometer.

PHYS2011/2911 Computational Physics 1


LAB SEVEN PHYS2011/2911 Computational Physics

If you dont know how to do any of these things once you have completed the lab, please ask your tutor for help.
You should also use these lists of objectives when you are revising for the end of semester exam.

7.3 Walkthrough: Inverse Fourier transforms


Given the Fourier transform of a function, you can perform the inverse Fourier transform to recover the original
function. For one-dimensional arrays in MATLAB, the function to do this is ifft. This is an exact inverse of fft,
in that any input y should be equal to ifft(fft(y)). If the original signal is real, then taking the inverse Fourier
transform should recover the purely real input, even though fft(y) may be complex. However, internal roundoff
error can sometimes lead to the appearance of small imaginary components in the inverse Fourier transformed
signal. This can be suppressed by invoking the ifft function with the 'symmetric' option, e.g.
1 y = ifft(Y, 'symmetric');

An important point to note is that ifft expects input of the format output by fft, i.e. with the strange frequency
ordering. If you used fftshift to reorder the array output by fft, you need to put it back using fftshifts
inverse function, ifftshift, before you pass it to ifft. E.g. if you started off with some data y, the commands
1 Y = fftshift(fft(y));
2 x = ifft(ifftshift(Y), 'symmetric');

will recover a vector x that is identical to y. ifftshift works for arrays of any dimension, just like fftshift.
We can illustrate the inverse Fourier transform using the example of a sine wave with frequency f = 3, the same
one you saw way back in Section 5.6. The code to generate and plot its Fourier transform is
1 dx = 0.01;
2 L = 2;
3 x = dx:dx:L;
4 f = 3;
5 Y = fftshift(fft(sin(2*pi*f*x)));
6 Nq = 0.5/dx;
7 freqs = -Nq : 1/L : Nq-1/L;
8 plot(freqs, abs(Y).2)

producing the plot on the left in Fig. 7.2. The -function spikes at 3 tell us that this describes a signal containing
a single frequency component with f = 3. Now see what happens when we compute and plot the inverse Fourier
transform of Y:
1 y = ifft(ifftshift(Y), 'symmetric');
2 plot(x, y, 'o')

The resultant vector y is plotted in the right panel of Fig. 7.2. If you count the number of oscillations per unit
length, youll see that this is indeed a sine wave of frequency 3.

Figure 7.2: A pair of -function spikes at f = 3 (left), and their inverse Fourier transform (right).

2
LAB SEVEN PHYS2011/2911 Computational Physics

Question 1
In the example we just saw, we obtained the pair of -function spikes by initially Fourier transforming a sine wave.
An alternative is to construct the -function spikes directly. Refer to the code on page 2 and create a vector freqs,
then construct a vector Y of zeroes of the same size and put a 1 where the frequencies are 2. This corresponds to
a pair of -function spikes at f = 2. Sketch your plot below.
Hint:
You can use MATLABs logical indexing notation to achieve this. For example, A(B == -2 | B == 2) = 1
performs the operation wherever the entries of B equal 2, change the corresponding entries of A to 1. The
arrays A and B must have the same dimensions.

1 dx = 0.01;
2 L = 2;
3 x = dx:dx:L;
4 Nq = 0.5/dx;
5 freqs = -Nq : 1/L : Nq-1/L;
6 Y = zeros(size(freqs));
7 Y(freqs == -2 | freqs == 2) = 1;

Question 2
Compute the inverse Fourier transform, and sketch the result below. By counting the number of oscillations per
unit length, what is the frequency of this wave? Does this match the input?

1 y = ifft(ifftshift(Y), 'symmetric');
2 plot(x, y, 'o')
The waveform undergoes two oscillations per unit length, so the frequency is 2. This matches
the input.

Tutor note: This is a cosine rather than a sine wave because the way we constructed the ampli-
tudes implicitly sets all phases to zero (only cosine terms present).

3
LAB SEVEN PHYS2011/2911 Computational Physics

7.4 Walkthrough: Convolution


The concept of convolution is of fundamental importance to astronomical imaging. Mathematically, convolution
is an operation denoted by the symbol that in the one-dimensional case takes as input two functions, f and g,
and outputs
Z +1
[ f g](x) = f ()g(x ) d . (7.1)
1

The Convolution Theorem states that

F ( f g) = F ( f )F (g) , (7.2)

where F means Fourier transform of. This means that convolution can be performed by multiplying the Fourier
transforms of f and g together, and then inverse Fourier transforming the result. Although there is a discrete
version of Eq. (7.1) that is implemented in MATLAB with an inbuilt function conv, in this lab we will perform
convolution based on Eq. (7.2), i.e. using MATLABs FFT functions.
Qualitatively, the effect of convolution is to smear the two functions f and g together, so that the end result has
features from both1 . To demonstrate this, lets convolve a square pulse with a triangular pulse, as shown below.

Figure 7.3: When a square pulse (left) is convolved with a triangular pulse (middle), the result is a function that
looks somewhat in-between the two (right).

Firstly, we can create and plot a square pulse with the following MATLAB code:
1 x = linspace(0,2,200);
2 box = zeros(200,1);
3 box(x > 0.25 & x < 0.75) = 0.25;
4 plot(x, box)

Then we can create a triangular pulse with similar code:


1 triangle = zeros(200,1);
2 triangle(x > 0.25 & x < 0.5) = x(x > 0.25 & x < 0.5) - 0.25;
3 triangle(x > 0.5 & x < 0.75) = 0.75 - x(x > 0.5 & x < 0.75);
4 plot(x, triangle)

Try plotting these and make sure they look like you expect. Now to convolve the two functions we need to Fourier
transform them, multiply them together, and then take the inverse transform:
1 fftconv = fft(box) .* fft(triangle);
2 boxtriangle = ifft(fftconv, 'symmetric');
3 plot(x, boxtriangle)

Remember that the .* operator does element-wise multiplication for two arrays that have the same dimensions.
This process is illustrated in Fig. 7.3, where you can see that the final result looks like something in-between a
square pulse and triangular pulse.
1 See http://en.wikipedia.org/wiki/Convolution for an animation of this effect.

4
LAB SEVEN PHYS2011/2911 Computational Physics

The two-dimensional analogue of ifft is ifft2, where for a given 2D array x, the result of ifft2(fft2(x))
recovers x (up to the effects of roundoff error). To guard against roundoff error, use the the option 'symmetric'
when calling ifft2, just as for ifft.
Convolution is important in astronomy because the image formed by a telescope is not the true brightness distri-
bution in the sky it is the brightness distribution convolved with something called the response function of the
telescope. The response function is the brightness distribution measured by the telescope in response to a bright
point-like object, and can be calculated as the inverse Fourier transform of the telescope aperture.

7.5 Activity: The Moon through a circular aperture


In this lab, we will make use of one of MATLABs demo images, which is of the Moon (Fig. 7.4, left). You can
load and display this image in MATLAB using the commands
1 moon = imread('moon.tif');
2 imshow(moon)

Figure 7.4: Left: image of the Moon (credit: Michael Myers). Middle and right: A circular aperture and its Fourier
transform, respectively.

A circular aperture with a radius of 0.05 in spatial frequency units is shown in the middle panel of Fig. 7.4. The
MATLAB commands to construct this aperture are
1 [Mfx, Mfy] = meshgrid(fx, fy);
2 radius = 0.05; % we are choosing radius to be 0.05
3 circle = zeros(size(M));
4 circle(Mfx.2 + Mfy.2 < radius2) = 1;
5 imshow(circle, 'XData', fx, 'YData', fy)

where fx and fy are the vectors containing the frequency coordinates (you will be required to work out what these
are in Question 3). The corresponding response function, which is the famous Airy disk pattern (right panel of
Fig. 7.4) can be computed via
1 C = ifft2(ifftshift(circle), 'symmetric');
2 imshow(mat2gray(fftshift(C)))

Take note that we need to use ifftshift before calling ifft2, because ifft2 expects input of the format output
by fft2, i.e. with the frequencies in the strange semi-jumbled order.
A brief note about plotting 2D arrays: MATLAB displays these by default with the first row, column entry on the
top-left. This means that the x-axis increases from left to right and the y-axis increases from top to bottom. If
you want to flip the y-axis so that it matches the plotting convention most people are used to (y-values increasing
upwards), use the command
1 set(gca, 'YDir', 'normal')

when the figure whose y-axis you want to flip is open.

5
LAB SEVEN PHYS2011/2911 Computational Physics

Question 3
In Lab 5, you constructed frequency vectors for one-dimensional data. For two-dimensional data you will need to
construct two frequency vectors, one for each dimension. To work out the two vectors, you need apply those rules
for each dimension separately, because the input array will in general have different resolutions and ranges along
its different dimensions.
You can work out the dimensions of the Moon image using [Lx, Ly] = size(moon) where Lx and Ly are the
horizontal and vertical dimensions, respectively, in pixel coordinates.
Based on these values, and using the rules from Lab 5, write down the commands you would use to construct the
frequency vectors fx and fy corresponding to the x and y dimensions. You can assume that each pixel represents
one unit of length, implying that the Nyquist frequencies along each dimension, Nqx and Nqy, are both 0.5.

1 [Ly, Lx] = size(moon);


2 Nqx = 0.5; Nqy = 0.5;
3 fx = -Nqx : 1/Lx : Nqx-1/Lx;
4 fy = -Nqy+0.5/Ly : 1/Ly : Nqy-0.5/Ly;
Tutor note: The dimensions of the image are an even odd number of elements, hence the
different expressions for the frequency vectors.

Question 4
Compute and plot the squared modulus of the 2D Fourier transform of the Moon image, labelling the frequency
axes with the vectors fx and fy that you constructed in Question 3.
Plotting tip: The amplitudes of the Fourier transform span a very wide range of scales, so it may help to plot the
logarithm of the values instead. You can use either the MATLAB function log for the natural logarithm or log10
for the base-10 logarithm.

1 M = fftshift(fft2(moon));
2 imshow(mat2gray(log10(abs(M).2)), 'XData', fx, 'YData', fy)
3 axis on; xlabel('f_x'); ylabel('f_y')
4 set(gca, 'YDir', 'normal')

6
LAB SEVEN PHYS2011/2911 Computational Physics

Question 5
Convolve the Moon with an Airy disk by multiplying the array corresponding to the 2D Fourier transform of the
Moon image by the circular aperture (you can use the construction commands given in the example), and then
taking the inverse 2D Fourier transform using ifft2. Remember to invoke the 'symmetric' option. Plot the
resulting image using imshow and mat2gray, and comment on what you see.

1 M = fftshift(fft2(moon));
2 [Mfx, Mfy] = meshgrid(fx, fy);
3 radius = 0.05;
4 circle = zeros(size(M));
5 circle(Mfx.2 + Mfy.2 < radius2) = 1;
6 mcircle = ifft2(ifftshift(M.*circle), 'symmetric');
7 imshow(mat2gray(mcircle))

The resulting image is a blurry version of the original. Faint ring-like features are artefacts
that come from the Airy disk response function.

Checkpoint 1:

7
LAB SEVEN PHYS2011/2911 Computational Physics

Figure 7.5: Left: A simple 2-element interferometer (source: http://www.cv.nrao.edu/course/


astr534/Interferometers1.html). Right: The u, v-coverage of a 2-element interferometer with a base-
line vector of ~b = (2, 3).

7.6 Activity: The 2-element interferometer


The simplest radio interferometer comprises two receiving elements. The electric fields associated with radio
waves arriving at the interferometer produce voltage fluctuations at the two receivers, and these signals are then
correlated (multiplied together and averaged over time). A schematic of a 2-element interferometer is shown in
Fig. 7.5 (left). If the path difference between the two receivers for an incoming wavefront is an integer number
of wavelengths, constructive interference occurs and the correlated signal has maximum amplitude. If the path
difference is a half-integer number of wavelengths, then there is destructive interference and the correlated signal
drops to zero.
This is exactly the same principle that gives rise to the interference fringes in Youngs double-slit experiment! In
fact, the 2-element interferometer can be thought of as Youngs double-slit experiment in reverse. The difference
is that the slits are now radio receivers, and the electric field is being received rather than emitted.
A pair of radio receivers that are correlated together forms a baseline. In general, a radio interferometer comprises
more than two receivers, and therefore more than one baseline. Every pair of receivers in an interferometric
array measures one spatial frequency of the skys brightness distribution. The spatial frequency f is related to
the baseline b and observing wavelength by f = b/ . In two dimensions, f and b are vectors with x and
y components. For example, if the two receivers are at (1,0) m and (5, 6) m and the observing wavelength is
= 2 m, then the baseline vector is ~b = (5, 6) (1, 0) = (4, 6) m and the spatial frequency measured is
f = ~b/ = (2, 3) in units of . The aperture corresponding to this interferometer has two holes, at f~, and
~
is shown in the right panel of Fig. 7.5. A plot like this is called a u, v-coverage plot, where u and v refer to the
horizontal and vertical spatial frequencies, respectively (here u = 2 and v = 3 in units of ).
For simplicity, we are now going to rescale the frequency units such that each pixel in the 2D Fourier array
corresponds to one unit of . The frequency vectors for our Moon example can then be constructed as
1 u = int32(-Lx/2 : Lx/2-1);
2 v = int32(-(Ly-1)/2 : (Ly-1)/2);

where Lx and Ly are the dimensions of the Fourier grid (equal to the dimensions of the Moon image). The
MATLAB commands for generating the u, v-plot in Fig. 7.5 (right) are
1 [Mu,Mv] = meshgrid(u,v);
2 bx = 2; by = -3;
3 uvplane = zeros(size(M));
4 uvplane(Mu == bx & Mv == by) = 1;

8
LAB SEVEN PHYS2011/2911 Computational Physics

5 uvplane(Mu == -bx & Mv == -by) = 1;


6 imshow(uvplane, 'XData', u, 'YData', v)
7 set(gca, 'YDir', 'normal')

This constructs a 2D array of zeroes, and puts a 1 where (u, v) = (2, 3) and another 1 where (u, v) = ( 2, 3).
Note: If you run the above code, youll need to zoom in to see the holes.
Question 6
Using the code given for the 2-element interferometer example, generate the u, v-coverage plot in the rightmost
panel of Fig. 7.5 and take its inverse Fourier transform. Display this with imshow and mat2gray, and sketch what
you see. This is the response function of a 2-element interferometer.

1 M = fftshift(fft2(moon));
2 [Ly, Lx] = size(moon);
3 u = int32(-Lx/2 : Lx/2-1);
4 v = int32(-(Ly-1)/2 : (Ly-1)/2);
5 [Mu,Mv] = meshgrid(u,v);
6 bx = 2; by = -3;
7 uvplane = zeros(size(M));
8 uvplane(Mu == bx & Mv == by) = 1;
9 uvplane(Mu == -bx & Mv == -by) = 1;
10 xyplane = ifft2(ifftshift(uvplane), 'symmetric');
11 imshow(mat2gray(xyplane))

Question 7 (PHYS2911)
As a radio source (e.g. the Sun) drifts across the sky, constructive and destructive interference occur to produce
a fringe pattern. The precision to which the position of such a radio source can be measured is determined by
the fringe spacing, which sets the angular resolution of the interferometer. The closer the fringes, the higher the
resolution. Based on what you know about Youngs double-slit experiment, can you suggest two ways to improve
the resolution of a 2-element interferometer?

In Youngs double-slit experiment, the fringe spacing decreases as the slits move further apart,
and also when a shorter wavelength is used. This means that you can improve the resolution
of a 2-element interferometer by moving the receivers further apart, and/or observing at a
higher radio frequency (shorter wavelength).

9
LAB SEVEN PHYS2011/2911 Computational Physics

7.7 Activity: Simulating a multi-element interferometer


The effect of adding more receivers to an interferometric array is to increase the number of baselines. Each
baseline adds a new pair of conjugate-frequency holes to the aperture of the interferometer, i.e. a new pair
of spatial frequencies to the u, v-plane. The more complete the coverage of the u, v-plane, the more accurate the
image of the sky that is produced. When designing a radio interferometer, people often perform simulations to
see what the u, v-coverage will be like for different numbers and configurations of receivers. This allows them to
optimise the layout of the array for particular science goals and to predict its response to different sky brightness
distributions.
For this lab, you have been provided with a pre-written MATLAB function, fillUVplane(x,y). This automates
the processes of calculating the baseline vectors and u, v-coverage of an interferometer, given a list of positions of
the receivers. It performs the same steps for simulating a 2-element interferometer that you saw earlier in Section
7.6, but now looped over all receiver pairs. fillUVplane(x,y) takes as input a list of 2D receiver coordinates,
where the x and y-coordinates are stored in the variables x and y respectively, calculates the baselines, creates a
2D array of zeroes, and puts a 1 at the appropriate spatial frequencies. If you are curious, you can open up the
function file to see how it works. The syntax for using this function is
1 uv = fillUVplane(x, y);

where uv is the 2D array of ones and zeroes representing the aperture of the interferometer.
Question 8
We will now try out this function for a 6-element interferometer. This is the number of receivers that comprises the
Australia Telescope Compact Array (ATCA), a world-class radio astronomical facility located in Narrabri, NSW
about 500 km northwest of Sydney. The dishes of the ATCA are mounted on rail tracks and can be moved around
into different configurations.
Let the ground coordinates of the six receivers be ~r1 = (0, 0), ~r2 = (12, 10), ~r3 = ( 1, 2), ~r4 = ( 3, 4),~r5 =
(4, 0) and ~r6 = (5, 6) in units of . Plot and sketch their layout. How many baselines does this interferometer have
(hint: how many unordered pairs can you form from six elements)?

1 x = [0, 12, -1, -3, 4, 5];


2 y = [0, -10, -2, 4, 0, 6];
3 plot(x, y, 'o')

The number of unordered pairs you can form from n elements is nC2 = n(n 1)/2. A 6-element
interferometer has 6C2 = 15 baselines.

10
LAB SEVEN PHYS2011/2911 Computational Physics

Question 9
Use fillUVplane to compute and plot the u, v-coverage of this interferometer. Does the number of holes in
this aperture match up with what you expect from your answer to Question 8?

1 u = int32(-Lx/2 : Lx/2-1);
2 v = int32(-(Ly-1)/2 : (Ly-1)/2);
3 uv = fillUVplane(x, y);
4 imshow(uv, 'XData', u, 'YData', v)

There are 30 holes in this aperture, which is consistent with what we expect from the num-
ber of baselines there are 15 baselines, each contributing one pair of conjugate-frequency
points in the u, v-plane (15 2 = 30).

Question 10
Image the Moon using this interferometer, by convolving the response function with the Moon image. Recall
that this involves multiplying the Fourier transform of the Moon image with the aperture (in this case, this is the
array output by fillUVplane) and inverse Fourier transforming the result. Display the result using imshow and
mat2gray, and describe what you see. Is this recognisable as the Moon?

1 moon6 = ifft2(ifftshift(M.*uv), 'symmetric');


2 imshow(mat2gray(moon6))

The image is full of blurry, wispy structure that bears little resemblance to the Moon.

11
LAB SEVEN PHYS2011/2911 Computational Physics

What is going on? Well, from the u, v-coverage plot that you computed in Question 9, it is apparent that the
u, v-coverage of this interferometer is quite sparse (only a small number of spatial frequencies are measured). The
response function, which you can compute and plot using the commands
1 response = ifft2(ifftshift(uv), 'symmetric');
2 imshow(mat2gray(response))

is shown in Fig. 7.6. The complicated pattern of blobs you see in the response function are called sidelobes.
Sidelobes cause false structure to be imprinted on the image formed by an interferometer. This can be remedied
by a process called deconvolution, which as the name suggests is intended to reverse the effects of convolution.
However, this is beyond the scope of the material we will cover here.

Figure 7.6: Response function of 6-element interferometer.

The image you obtained for Question 10 looks the way it does because it is the Moon convolved with this messy-
looking function. A raw image like that, before it has undergone deconvolution to remove sidelobe structure, is
called a dirty map. No points for guessing why it is called this! In reality, interferometers with a small number
of receivers like the ATCA can still make nice images by augmenting their u, v-coverage using a number of tricks
thereby improving their response function, but we wont discuss those here.

Question 11
Lets now repeat this for a 128-element interferometer. This is the number of receivers that currently comprises
the Murchison Widefield Array (MWA), a next-generation radio telescope in Western Australia that became op-
erational in 2013. The MWA is a technology testbed for the future Square Kilometre Array, which will be the
worlds largest radio telescope and consist of thousands of receivers scattered across Australia and South Africa.
Generate a centrally-condensed distribution of 128 receivers using the commands
1 x= int32(round(20*randn(128,1)+Lx/2));
2 y= int32(round(20*randn(128,1)+Ly/2));
3 x(x < 1) = 1; x(x > Lx) = Lx; % make sure x never falls outside of [1,Lx]
4 y(y < 1) = 1; y(y > Ly) = Ly; % make sure y never falls outside of [1,Ly]

and then compute the u, v-coverage of this interferometer using fillUVplane. There are a large number of
baselines, so fillUVplane may take a few seconds. randn is one of a number of inbuilt MATLAB functions
for generating pseudo-random numbers (others include randi, which we will use in the Challenge section to this
lab, and also rand). randn generates random Gaussian-distributed points.

12
LAB SEVEN PHYS2011/2911 Computational Physics

1 x = int32(round(20*randn(128,1)+Lx/2));
2 y = int32(round(20*randn(128,1)+Ly/2));
3 x(x < 1) = 1; x(x > Lx) = Lx;
4 y(y < 1) = 1; y(y > Ly) = Ly;
5 uv = fillUVplane(x, y);
6 imshow(uv, 'XData', u, 'YData', v)

Question 12
Image the Moon with the 128-element interferometer. How well can you see it now?

1 moon128 = ifft2(ifftshift(M.*uv), 'symmetric');


2 imshow(mat2gray(moon128))

There is still some wispy structure, but the Moon can now be seen clearly.

Checkpoint 2:

13
LAB SEVEN PHYS2011/2911 Computational Physics

7.8 Challenge: Re-baselining the 128-element interferometer


Lets now see what happens if we were to redistribute the 128 receivers of the interferometer over a much larger
area. Instead of a centrally-condensed array, we are now going to spread them out in a uniformly random manner.
Question 13
Generate a uniformly-random distribution of 128 receivers using the commands
1 x = randi([1,Lx], 128, 1);
2 y = randi([1,Ly], 128, 1);

where Lx and Ly are the dimensions of the Moon image. Compute and display the u, v-coverage plot.

1 x = randi([1,Lx], 128, 1);


2 y = randi([1,Ly], 128, 1);
3 uv = fillUVplane(x, y);
4 imshow(uv, 'XData', u, 'YData', v)

Question 14
Image the Moon using this interferometer. How does it differ from the Moon image in Question 12?

1 moon128_unif = ifft2(ifftshift(M.*uv), 'symmetric');


2 imshow(mat2gray(moon128_unif))

There is more wispy structure in this image. It is possible to make out a sharp crescent outline,
but the features/craters/etc. on the Moon are now difficult to see. The overall image of the
Moon is not recovered as well as it was in Question 12.

14
LAB SEVEN PHYS2011/2911 Computational Physics

Question 15
Can you explain why a centrally-condensed interferometer might be better for imaging a large object like the
Moon? What about if you were trying to detect and measure the positions of small point-like objects, such as
pulsars?

A centrally-condensed configuration is much more sensitive to smaller spatial frequencies,


i.e. large-scale structure on the sky, than an interferometer spread out over a much larger area.
The Moon is a large object and is therefore built mainly from small spatial frequencies, so it is
imaged more accurately by a centrally-condensed array. On the other hand, interferometers
with many long baselines are very sensitive to small-scale structure, as evidenced by the very
sharp edge of the Moon when imaged with the more spread-out array. Point-like objects like
pulsars would therefore be easier to detect with a spread-out array.

15
LAB

EIGHT

Random Numbers, Random Walks


Random numbers should not be generated with a method chosen at random.

Donald Knuth, The Art of Computer Programming.

8.1 Introduction
There are many processes in nature that consist of a series of effectively random events. For example, radioactive
decay or the division of bacteria cells. There are also processes that can be modelled by selecting values from a
known statistical distribution, for example the heating of gas particles in a container. In the next three labs we
introduce an important family of numerical techniques called Monte Carlo simulations that can be used to model
situations that involve random events.

Figure 8.1: The notebook records of Jean Perrin showing the irregular motion of particles suspended in water.

In 1827 the botanist Robert Brown used a microscope to observe particles from pollen suspended in water. He
noticed that they jiggled around, seemingly randomly, but did not know what was causing the motion. The effect
was named Brownian motion.
In 1905 Albert Einstein proposed that the jiggling could be explained by thermal molecular motions. Jean Perrins
work (for which he won the 1926 Nobel Prize) confirmed this experimentally, and provided a way of calculating
the size of molecules.
In this lab we will investigate random numbers and use them to generate one dimensional random walks based on
the idea of Brownian motion.

8.2 Lab objectives


By the end of this lab sessions you should be able to:

1. Generate random numbers using MATLAB;


2. Generate random numbers from different probability distributions;
3. Run random walk simulations to model a system.

If you dont know how to do any of these things once you have completed the lab, please ask your tutor for help.
You should also use these lists of objectives when you are revising for the end of semester exam.

PHYS2011/2911 Computational Physics 1


LAB EIGHT PHYS2011/2911 Computational Physics

8.3 Walkthrough: Random Numbers


You can generate random numbers in MATLAB using the rand function. rand returns a uniformly distributed
pseudo-random number in the range 0 x < 1. For example:
1 >> rand()
2 ans = 0.2785

You can also get the same result calling rand without the parentheses. If you run rand multiple times, you will
notice that the number is different each time:
1 >> rand()
2 ans = 0.9575
3 >> rand()
4 ans = 0.9649
5 >> rand()
6 ans = 0.1576

You can also generate a vector or matrix of random numbers by passing in the vector dimensions:
1 >> rand(2,3)
2 ans = 0.8491 0.6787 0.7431
3 0.9340 0.7577 0.3922

Experiment to see what happens if only a single argument is given to rand?

Result is a square matrix. This can be a problem if you write rand(1e6) instead of rand(1e6,1)!

Now we mentioned that these are actually pseudo-random numbers from a uniform distribution. What do each of
these terms mean?

8.3.1 Pseudo-randomness
Although these numbers seem random, MATLAB is using a sophisticated algorithm to generate each successive
random number, and so they are not truely random. Theoretically, MATLAB can generate over 21492 (about
10450 ) numbers before repeating itself. Each time you start up a MATLAB session, the random number sequence
begins at the same place. You can change the starting point of the sequence (a process known as seeding), by
invoking the statement rng(n), where n is any integer. By default, n is set to zero when MATLAB starts.
For example, lets seed the random number generator with n = 5, and then generate some numbers:
1 >> rng(5)
2 >> rand()
3 ans = 0.2220
4 >> rand()
5 ans = 0.8707

Now lets re-seed the number generator and generate some more numbers:
1 >> rng(5)
2 >> rand()
3 ans = 0.2220
4 >> rand()
5 ans = 0.8707

You can see these numbers are identical to before, demonstrating that our random number generator is not truely
random. This is why computationally generated random numbers should really be called pseudo-random numbers.

2
LAB EIGHT PHYS2011/2911 Computational Physics

8.3.2 The uniform distribution


The random numbers generated by rand are drawn from a uniform distribution. That means that if you divide the
range 0 to 1 into equal bins, there should be an equal number of numbers in each bin. You can check if this is true
by generating a set of random numbers and then plotting a histogram of their values:
1 >> numbers = rand(1, 100)
2 >> hist(numbers)

Youll probably find that the plotted distribution is somewhat even, but maybe not as even as you expected. The
reason is that numbers drawn from a uniform distribution will be uniformly distributed if we draw enough of them.
For example, if we generate a 10 000 numbers instead of 100, the distribution should be much more uniform.
1 >> numbers = rand(1, 10000)
2 >> hist(numbers)

Figure 8.2: A histogram of 100 (left) and 10 000 (right) random numbers drawn from a uniform distribution.

8.4 Walkthrough: Monte Carlo simulations


A Monte Carlo simulation is one in which repeated random sampling is used to obtain a numerical solution to
a problem. Usually many iterations of the simulation are run, resulting in a probability distribution for some
unknown entity (for example, the probability that a neutron will escape the shielding around a radiation chamber).
Monte Carlo was a secret code name chosen by Nicholas Metropolis, who was one of the scientists who developed
Monte Carlo methods as part of the Los Alamos nuclear weapons project in World War II. It was named after the
casino, where the uncle of another of the inventors, Stanislav Ulam, used to gamble.
To demonstrate a simple Monte Carlo simulation, we can use the example of a tossing a coin. Say we want to
answer the question: If a toss a coin a large number of times, what fraction of the time will it come up heads?
With such a simple case, we could just answer this question analytically. But imagine we didnt know how to do
that. An alternative would be to actually toss a coin thousands times, but this would take a long time. A Monte
Carlo simulation lets us do this experiment computationally.
We start by modelling a single coin toss. There are two options when you toss a coin, and both are equally likely.
So we can say that if we generate a number x between 0 and 1, then we will call it heads if x < 0.5 and tails if
x 0.5. One way of implementing this is to use round, and make heads equal to 0 and tails equal to 1:
1 >> x = round(rand())
2 x = 0
3 >> x = round(rand())
4 x = 1

Now we know how to toss a single coin, we can easily simulate tossing a coin 100 times by generating a vector
with 100 random numbers in:
1 >> n = 100;
2 >> x = round(rand(1, n));

3
LAB EIGHT PHYS2011/2911 Computational Physics

We could then count the number of heads by working out how many elements of x are equal to 0:
1 >> nheads = length(x(x==0))
2 nheads = 44

If we had just done this experiment in real life (physically tossing a coin 100 times) wed probably be pretty tired.
We would conclude that since heads comes up 44 times out of 100, the probability of heads P(h) is:
1 >> pheads = nheads / n
2 pheads = 0.4400

But there is a problem with this conclusion. Say our friend has also been tossing a coin, and after 100 tosses she
has found there are 52 heads. Her conclusion is that P(h) = 0.52. Another friend claims to have got 49 heads out
of 100 coin tosses and concludes that P(h) = 0.49. What is the correct answer?

8.4.1 A probability distribution


What we obtain from a simulation like this is not an exact answer, but a probability distribution. We can repeat the
coin toss experiment many times using a for loop, adding the calculated probability to a vector in each iteration.
You should save this code as coin toss.m so you can run it multiple times.
1 p = [];
2 n = 100;
3 for iters = 1:1000
4 x = round(rand(1, n));
5 pheads = length(x(x==0)) / n;
6 p = [p pheads];
7 end

Running this code and plotting a histogram of these probabilities:


1 >> coin_toss
2 >> hist(p, 0:0.05:1)

shows a range of values centred on 0.5 (see Figure 8.3). The peak of this distribution (0.5) is the best estimate of
the probability of getting heads in a coin toss experiment. Note that you might have to adjust the histogram bin
range and plot axis range to get a clear plot.

Figure 8.3: Distribution of probabilities after repeating the coin toss experiment 1000 times.

The power of Monte Carlo methods is that we can run simulations that are impractical to do in real life.

4
LAB EIGHT PHYS2011/2911 Computational Physics

8.5 Activity: Calculating


In this activity we will look at a clever and yet simple way of estimating using a Monte Carlo simulation.
Question 1
Imagine you have a circle inscribed inside a square, as shown. Derive an expression for in terms of the area of
the square (A s ) and the area of the circle (Ac ).

Ac = r2
Implies = Ac /(r2 ) (Eq. 1)
A s = (2r)2 p
Implies r = (A s )/2 (Eq. 2)
Substitute (2) into (1)
= 4Ac /A s

Question 2
Write MATLAB code to generate two vectors x and y that both contain 100 random numbers with values between
-1 and 1. Check the numbers appear random by plotting x vs. y. Write your code below.

1 n = 100;
2 a = -1;
3 b = 1;
4 x = a + (b-a).*rand(n,1);
5 y = a + (b-a).*rand(n,1);
Tutor note: you need to multiple by 2 so the numbers span the range 0-2, then shift to offset to -1.

Question 3
Now imagine an experiment in which you throw n darts randomly at the square. All of the darts fall inside the
square (n s = n), but only some fraction of them fall inside the circle (nc ).
Assume the circle has a radius of 1. Write a program to simulate throwing 100 darts at the square. To do this,
generate 100 random numbers between 1 and 1 in each coordinate (x and y). Plot a circle of radius 1, and on the
same axes plot the positions of the 100 darts. Sketch your plot below or show it to your tutor.
Hint: It would be useful to plot the darts that fall inside the circle one colour, and the darts that fall outside the cir-
cle in a different colour. You can plot a circle using plot(sin(0:0.1:2*pi+0.1),cos(0:0.1:2*pi+0.1)).

5
LAB EIGHT PHYS2011/2911 Computational Physics

Question 4
Calculate the number of darts that fall within your circle, and from this, provide an estimate of using the result
you derived in Question 1:

nc
=4 (8.1)
ns

Estimate should be somewhere between 2.9 and 3.3 (of course there is a small chance it is
higher or lower if theyve only run their code once).
Tutor note: even though PHYS2011 students dont have to do the next question, it would be good to
mention, when doing the marking, how they could improve their estimate of pi.

If you want to get a more accurate estimate of , try increasing the number of darts to, say, 100 000.

Question 5 (PHYS2911)
The estimate of provided by this method is not very accurate. One way of improving this is to increase the
number of iterations in our simulation.
Modify your program so that it loops through a range of values for the number of darts, n. For example, you
might try iterations from n = 10 to n = 1000 in steps of 10 and n = 1000 to n = 10000 in steps of 1000. Use
pause(0.1) in your loop so you can see each iteration.
Plot the estimate of versus the number of iterations, and sketch it below (you probably want make the x-axis on
a log scale, using semilogx). Include a horizontal line showing the true value of .

Checkpoint 1:

6
LAB EIGHT PHYS2011/2911 Computational Physics

8.6 Walkthrough: The Normal Distribution


In this section we will use Monte Carlo simulations to model a random walk which can be used to represent
Brownian motion and particle diffusion.
The normal (or Gaussian) distribution is one of the most important probability distributions and it appears in many
different contexts. You have probably already seen this distribution in first year statistics. The probability density
function for a normal distribution is

(x x)2
1 2
f (x) = p e 2 (8.2)
2

where x is the mean, and is the standard deviation of the distribution.


We have previously obtained random numbers from a uniform distribution using the rand() function in Matlab.
To obtain random numbers from a Gaussian distribution with x = 0 and = 1, you can use the randn() function:
1 >> x = randn(1,10000);
2 >> hist(x, 100);

The left panel in Figure 8.4 shows a histogram of 10000 numbers generated using randn().

Figure 8.4: Two normal distributions. Left: x = 0 and = 1. Right: x = 5 and = 10. For comparison, both are
plotted with the same axis ranges.

We can scale the output from rand() in order to obtain numbers from a normal distribution with, say, a mean
x = 5 and a standard deviation = 10:
1 >> xbar = 5;
2 >> sigma = 10;
3 >> x = xbar + sigma.*randn(1,10000);
4 >> hist(x, 100);

Notice that the peak of the distribution is now at 5, and the distribution is wider than before because the standard
deviation is higher.
We can calculate the mean and standard deviation of the resulting distribution using:
1 >> mean(x)
2 ans = 5.0540
3 >> std(x)
4 ans = 10.1361

You should see that these results agree (approximately) with the values of x and you used to create the distribu-
tion.

7
LAB EIGHT PHYS2011/2911 Computational Physics

8.7 Activity: Random Walks


A random walk is a path that is formed by taking a series of random steps. The next position in the path depends
only on the current position, which makes a random walk an example of a Markov process. Brownian motion,
the random motion of particles suspended in a fluid resulting from their collision with the fluid molecules, can be
modeled using a random walk.
Question 6
You can generate a 1D random walk by considering a particle (e.g. a grain of pollen) that starts out at position
y = 0 and at each time step (on the x-axis) takes a step of +1 or 1 units with equal probability.
Write a program to plot the path taken by the particle over 1000 steps. In each step you should randomly choose
whether the particle moves up by one unit (+1) or down by one unit ( 1). Sketch your plot below.

Question 7
Now convert your program to a function walker_1d that takes a number of steps nsteps as an input argument,
and returns the position of the particle after taking that many steps. You can run your function like this:
1 >> position = walker_1d(1000)
2 position = -26

(Note your answer will probably be different each time, since the walk is random.)

Question 8
Write a program that calls your walker_1d function to simulate 10 000 particles each taking 1000 steps. Plot
a histogram of the final position of the particles (use hist(x,-200:200)) and sketch it below. What is the
expected or mean final position of the particles?

8
LAB EIGHT PHYS2011/2911 Computational Physics

Peak is at zero (mean).

Question 9 (PHYS2911)
The characteristic distance that the particle has moved (with respect to its starting point) after n steps is given by
the standard deviation. Calculate the standard deviations of the final positions for 10 000 particles for a different
number of steps n = 10:10:1000
p
Plot vs n and sketch your plot below.

Question 10 (PHYS2911)
What is the relationship between the characteristic distance travelled and n? How many more steps are needed for
a particle to travel twice as far as it does with n steps.

p
/ n

9
LAB EIGHT PHYS2011/2911 Computational Physics

Question 11 (PHYS2911)
The relationship you found in Question 11 was not known when Brownian motion was first observed, which was
a source of confusion for scientists. At the time, scientists tried to measure the speed of diffusion (what might be
thought of as the overall speed of the particle) by dividing the change in position by time.
By thinking carefully about your answer to the previous question, what was the apparent paradox that they ob-
served?

Dividing the change in position


p by time assumes that x / t. However, from the previous
question, we know that x / t. Therefore, initial observations showed that the shorter the
measurement time, the higher the apparent velocity - yet the particle never seemed to slow
down in its motion.

Checkpoint 2:

8.8 Extra information and references


A copy of Browns original 1827 manuscript describing what was later called Brownian motion is available here:
http://sciweb.nybg.org/science2/pdfs/dws/Brownian.pdf
Einsteins 1905 paper (translated into English) is available here:
http://users.physik.fu-berlin.de/kleinert/files/eins brownian.pdf

10

S-ar putea să vă placă și