NGG1811 Lab 11: Matlab
After completing this lab, students should be able to use the following features of Matlab:
- Writing a script
- Writing a user-defined function
- Using array: creating, indexing, elementwise operations, vectorisation,
- Performing some data analysis
This lab has three parts: Parts A to C. You need to show your tutors all three parts.
For all the programs, we expect that you choose informative variable names and document your program.
There is also an online multiple choice question which is worth 1 mark. We suggest that you attempt this question after completing Parts A-C.
Organising your work
You should make a directory called lab11 to store your files for this lab.
In case you have problems doing the work, you can look up the Matlab documentation. There are plenty of examples in the documentation. There are two ways to use the documentation. Go to the top-right corner of the Matlab window, click on the question mark ? to browse or enter some texts to search:
Note that some of the questions will ask you to look up the documentation. This is to give you some practice to learn something new on your own, which is a situation that you will face all your life.
Part A: Arrays
This is an exercise for you to create a script and perform some simple operations on arrays. You are asked not to add a semicolon at the end of the Matlab statement so that we can see the results on the screen.
Example: typing the Matlab command
id = [1, 0; 0, 1]
is one way of creating the identity matrix of order 2 and displaying the result.
- Create a 2×3 array m whose first row contains the values 1, 2 and 4 and whose second row contains 3, -7 and 16.
- Confirm how big m is with the size and length functions.
- Many Matlab built-in functions can work with arrays as well as scalars. An example is the mod()function which computes the remainder. For example, the command mod(10,3) returns the remainder when 10 is divided by 3, which equals to 1. Enter the command p = mod(m,2) and explain what it does.
- You want to create a 2×3 array m_prime which has the same elements as m except that the odd numbers are changed to zero, i.e. m_prime is expected to be the array shown below. You are asked to obtain m_prime from the arrays m and p, where p is the array that you have computed in Step 3. Hint: You need to use .* (elementwise multiplication) and – (subtraction).
0 2 4 0 0 16
Part B: Functions
An object of mass m (in kg) is suspended from the end of a rigid horizontal beam of length b (in metres) that is attached to a wall by a pivot. The beam is supported by a cable of the same length as the beam attached to the beam at a distance d(in metres) from the wall. The tension T (in Newtons) on this cable is given by the equation
where g is the acceleration due to gravity and you can assume its value is 9.81.
Your task is to write a function that calculates the tension given the mass m, and lengths b and d as parameters. A requirement is that you need to make sure your function should work even when the inputs are vectors.
Your program should pass all the following three tests:
- In this test, the parameters m, b and d are scalars. Their values are respectively 100kg, 2m and 1.2m. The answer should be about 2044N.
- In this test, the input d is a vector, and m and b are scalars. Specifically,
- Generate a vector d which is an arithmetic progression starting at 0.4 and ending at 1.95, and the increment between two consecutive values is 0.01. If you’re unsure how to make incremental vectors in Matlab, remember you can use the colon : operator.
- The values of m and b are the same as Test 1.
Use your function to generate a vector
- of the corresponding tension values. It should require nothing more than passing the vector as the last argument.
If you get a message like Error using __*__ and you don’t understand why, click here.
Your function should return a vector with 156 elements. The elements at indices 1, 50, 100 and 156, are approximately, 5006, 2462, 1963 and 4528, respectively.
- In this test, all the three inputs m, b an d are vectors. You want to use the function to compute the tension of the cable for the following three cases. The restriction is that you are only allowed to call the function only once. Hint: You need to define three vectors of m, b and d values.
- m = 100, b = 2, d = 1
- m = 200, b = 3, d = 2
- m = 300, b = 4, d = 3
The expected answer is a vector with 3 elements whose approximate values are [2266, 3948, 5933].
Part C: A Data Processing Exercise
You might have heard of the recommendation that we should walk at least 10,000 steps per day to stay healthy. Some people use Fitbit, pedometers or smartphone apps to keep track of the number of steps they walk per day. Have you ever wondered how these devices and applications work? In order to count the number of steps, you need both hardware and software. In Fitbit, pedometers and smartphones, there is a common piece of hardware called the accelerometer, which as its name suggests, measures acceleration.
The picture below plots the acceleration data collected by an ENGG1811 lecturer using his smartphone during his commute to work. The horizontal axis shows time measured in minutes. The vertical axis shows the acceleration in the x-, y- and z-directions measured in m/s^2.
Note that these acceleration data were collected in a trip consisting of walking, train and bus rides. The aim of this lab exercise is to determine which part of the data corresponds to walking.
Fitbit and smartphone apps use fairly sophisticated algorithms for data processing. In this lab, you will use a basic algorithm to decide whether a person is walking in a certain time interval or not. The basic idea is to look at the acceleration over a short time interval. The figures below show the acceleration when the person was walking and not walking over a time interval of about 6 seconds. Note that the y-axes of the two sub-plots have the same scale to make the comparison easier. If the person was not walking (the plot on the right), the acceleration varied around the value of 10. However, when the person was walking, the acceleration varied between 4 and 20. Hence, a way to distinguish between walking and non-walking is to say: walking corresponds to larger variation in acceleration and non-walking corresponds to smaller variation of acceleration. There are many ways to measure variation. In this lab, we will use variance. If we calculate of the variance of the walking and non-walking data in the plots below, we get 20.85 and 0.04 respectively. So, one key point that you need to use later on is this: large variation in acceleration means walking and vice versa.
You are provided with a matlab mat file named acc_data.mat. The file contains a variable mat_data which is a matrix with 49910 rows and 4 columns.
Let us inspect the contents of the first 8 rows of the matrix mat_data
>> mat_data(1:8,:) ans = 0 0.7219 3.6775 12.2583 0.0990 1.1169 2.7922 9.5751 0.1990 0.1090 3.3778 7.3958 0.2960 0.1090 3.2144 6.9736 0.3990 -3.9499 3.5277 10.0382 0.5090 -9.6160 3.1463 6.7829 0.6090 -10.1472 0.2724 5.1349 0.7090 -8.8124 0.8853 3.9090
The first column is time (in seconds); the second, third and fourth columns are respectively the accelerations (in m/s^2) in the x-, y- and z-directions.
The first row of data is
0 0.7219 3.6775 12.2583
which means that at time 0, the accelerations in the x-, y- and z-directions were 0.7219, 3.6775 and 12.2583.
The third row of data is
0.1990 0.1090 3.3778 7.3958
which means that at time 0.1990, the accelerations in the x-, y- and z-directions were 0.1090, 3.3778 and 7.3958.
You can see that the numbers in the first column are 0, 0.0990, 0.1990, 0.2960 and so on, this means that the accelerometer was trying to measure the accelerations in the three directions roughly every 0.1 seconds, or about 10 samples per seconds.
You are asked to do your work in a script so that you can show your tutor later on. We have divided the work into Exercises 1, 2, 3 and 4.
Exercise 1: Preliminary processing
The first part of your script is shown below. A couple of steps have been done for you and the comments are there to help you to understand what the steps are. The places that say “Your task” contain the work that you have to do. Some further explanation is below the yellow box.
% ENGG1811 Lab 11 % Processing acceleration data
% Constants THRESHOLD = 0.5; % Threshold to separate walking from non-walking % Load the data file which contains one variable called mat_data load acc_data % The file contains one variable called mat_data
% The matrix mat_data has 49910 rows and 4 columns.
% You should check the size of the matrix to confirm % % Column 1: The time at which the acceleration is measured % Column 2: Acceleration in x-axis % Column 3: Acceleration in y-axis % Column 4: Acceleration in z-axis %% YOUR TASK: Create a vector vec_time which contains the first column of the % the matrix mat_data
% Note that you will only be using the vector vec_time for plotting,
% you won't be using this vector for calculations % Hint: See examples in indexing2_ex.m that was discussed in the lecture vec_time = % You to complete %% YOUR TASK: Create a matrix called mat_acc_3axes which contains columns 2-4 of % the matrix mat_data % Hint: See examples in indexing2_ex.m that was discussed in the lecture mat_acc_3axes = % You to complete %% YOUR TASK: Use the following Matlab commands to
% plot the accelerations in the three axes against time
figure(1) plot(vec_time,mat_acc_3axes) xlabel('time') ylabel('Acceleration') legend('x','y','z')
%% YOUR TASK: Calculate the total acceleration (See explanation below)
% You can store the result in a vector called vec_acc_total
% Note: You shouldn't use any loops.
%% YOUR TASK: Plot the total acceleration vec_acc_total against time
% using the following commands
figure(2) plot(vec_time,vec_acc_total) xlabel('time') ylabel('Acceleration') legend('total acceleration')
Here we explain the meaning of total acceleration. We assume you have the matrix mat_acc_3axes which is a matrix with 3 columns. The three elements at each row of the matrix is the acceleration in the x-, y- and z-directions at a particular time instance. The matrix mat_acc_3axes has the form
then the total acceleration is the following vector
You should use array operations and vectorisation to calculate the total acceleration. No loops should be used.
Hint: One method is to use the elementwise exponentiation (.^), sum() (making sure to specify the correct dimensions – remember in Matlab columns = 1 and rows = 2) and sqrt().
If you want to check your answers, some of them are here.
Exercise 2: Determining which segments contain walking data using a (for or while) loop
Let us assume that you store the total acceleration in a vector called vec_acc_total. This vector has 49910 rows. (You may wish to check the size of the vector to confirm.) We will partition the elements in this vector into segments where each segment contains 60 elements. With this partition, we have:
- Segment 1 contains elements 1 to 60
- Segment 2 contains elements 61 to 120
- Segment 3 contains elements 121 to 180, and so on
Given that the vector vec_acc_total has 49910 elements and each segment has 60 elements, it means that there is going to be an incomplete segment at the end. We will simply discard that incomplete segment. We will use num_segments to denote the number of complete segments.
Since each segment contains 60 elements (or data points), and acceleration data were collected once per 0.1 seconds, each segment contains roughly 6 seconds of acceleration data. For each segment, you should compute the variance of the total acceleration in the segment. If the variance is greater than or equal to a threshold (i.e. if the variance is big) then the person was walking during this time segment; otherwise, the person was not walking. The threshold you should use is 0.5 and it is specified in the beginning of the script shown in Exercise 1.
You should output your answer in a vector with num_segments elements. The k-th element of this vector is 1 if Segment k corresponds to walking; otherwise the k-th element should be 0.
We will use a small example to illustrate the calculations. Let us assume that the transpose of vec_acc_total is a vector with 14 elements shown below and each segment contains 3 elements. (Note you will use 60 elements per segment for you calculation, but for illustration, we need to use a much smaller number.)
The total accelerations in Segment 1 are 2, 20 and 2. The variance of 2, 20 and 2 is 108, which is at or above the threshold of 0.5, so this is walking. Similarly:
- Segment 2: Variance of 10, 10 and 10 is 0. Below threshold 0.5. Not walking.
- Segment 3: Variance of 10, 9 and 10 is 0.333. Below threshold 0.5. Not walking.
- Segment 4: Variance of 3, 18 and 3 is 75. At or above threshold 0.5. Walking.
The output should be in a vector with 4 elements because there are 4 complete segments. The output in this case should be the vector
[1; 0; 0; 1]
because Segments 1 and 4 correspond to walking. Note that the last elements (i.e. the values of 6 and 7) are not used because they do not form a complete segment.
For Exercise 2, you task is to use an implementation that uses loops.
You will find that, out of a total of 831 complete intervals, 265 of them are walking intervals. More answers are here.
Hint: The following code will help you get started:
% Use segments of 60 samples and determine whether the person is walking % Basic parameters num_samples_per_segment = 60; % number of samples per segment num_samples = length(vec_acc_total); % total number of samples in the data num_segments = floor(num_samples/num_samples_per_segment); % number of complete segments % Create a vector whose length is the number of complete segments walking_segments_loops = zeros(1,num_segments); % if Segment k is walking, then we will set walking_segments_loops(k) to 1 % Loop over each segment, if the variance is bigger than threshold, set % the index of that segment in walking_segments_loops to 1 for k = 1:num_segments % Extract the sub-array for this segment.
% Need to work out the first index of the segment and the index for the segment % After that, use colon notation to select the appropriate elements. %
% Determine the variance and compare it to the threshold end
Exercise 3: Determining which segments contain walking data WITHOUT using any loops
For this part, you should do the calculations stated in Exercise 2 but your implementation should NOT use any loops.
You will need to use the var function in Matlab to calculate variance. You can look at the documentation on how to use this function.
Hint: Consider the small example in Exercise 2. Let us start from
ex_0 = [2; 20; 2; 10; 10; 10; 10; 9; 10; 3; 18; 3; 6; 7]
You need to extract all the complete segments:
ex_1 = [2; 20; 2; 10; 10; 10; 10; 9; 10; 3; 18; 3]
and then think about using the Matlab reshape() function (Please read the note below on the Matlab reshape() function) to obtain the matrix:
2 10 10 3 20 10 9 18 2 10 10 3
Once you get this matrix, you see that each segment is in a column. You can then use var() to calculate the variance of the segments. After that you compare against the threshold.
Note that the Matlab reshape() function stacks columns, you can look up the examples in the online documentation. The numpy reshape function by default is row-wise, but allows the option of column-wise stacking.
If you got 264 total walking segments instead of 265, check out this link for more information.
Exercise 4: Comparing the outputs from Exercises 2 and 3
The results from Parts B2 and B3 should be identical, and your task is to verify this. The vectors from Parts B2 and B3 are quite long, so visual comparison is tedious. However, in Matlab, you can do this verification with one line of code. We impose the following requirements in how you verify whether the two vectors are identical.
- Your method can use only one line of code
- You cannot use any if-statements
- You cannot use any for- or while-loops
- The line of code should return 1 if the vectors are identical, otherwise it should return 0
You can use any methods you like as long as they meet the above requirements. For this part, you need to come out with two different methods.
Some functions or operators that you may find useful: any, all, sum, ~, ==, ~=, -.
Remark 1: Now that you have determined which segments of data correspond to walking, you can count the number of steps in those segments if you want. The process of counting the number of steps is fairly similar to that of counting the number heart beats, which you have done a few times in the course. So, we won’t ask you to do it.
Remark 2: This exercise asks you to compare two vectors consisting of integers (0 and 1). In this case, the comparison is straightforward. You may recall that we discussed in an earlier lecture on the topic of finite precision on the problem of comparing floating point numbers in Python. The same issue will also appear when you try to compare floating point numbers in Matlab due to inherent errors in representing floating points numbers. This isn’t an issue with this exercise, but you may need to compare floating point numbers in the future. See this link for one way of approaching the problem similar to what you have already done in Python.
At the End of the Lab
You should be able to show your tutor the exercises. You should be comfortable with the following aspects of Matlab: creating an array, elementwise operations, writing functions, array indexing and data operations.
Finally, do not forget to complete your online multiple choice question if you have not done it yet.
If you have completed everything, please do not forget to logout. Simply double click on the “Log Out” icon