Back to tutorial index

Two dimensional arrays


Topics in this lab

Introduction

clear all
format short e

Back to the top

From one-dimensional arrays to higher dimensional arrays

In our discussion of one-dimensional arrays we have discussed the length of the arrays, which we can get using the length function, but we have said little about the shape of the arrays we have created. But you may have noticed that both the linspace and the colon operator : create arrays with one row, and multiple columns :

x = linspace(-1,1,11)
x =
  Columns 1 through 6
  -1.0000e+00  -8.0000e-01  -6.0000e-01  -4.0000e-01  -2.0000e-01            0
  Columns 7 through 11
   2.0000e-01   4.0000e-01   6.0000e-01   8.0000e-01   1.0000e+00
y = -1:0.2:1
y =
  Columns 1 through 6
  -1.0000e+00  -8.0000e-01  -6.0000e-01  -4.0000e-01  -2.0000e-01            0
  Columns 7 through 11
   2.0000e-01   4.0000e-01   6.0000e-01   8.0000e-01   1.0000e+00

You may have also noticed that when we generated an array of random numbers using the rand command, we always supplied two arguments to the function, as in

z = rand(1,5)
z =
   5.9780e-02   2.3478e-01   3.5316e-01   8.2119e-01   1.5403e-02

Finally, using square brackets, we constructed arrays as

w = [3.4 5.6 7.8 9.1]
w =
   3.4000e+00   5.6000e+00   7.8000e+00   9.1000e+00

In each of above examples, we constructed arrays whose length was the number of elements in the array. But in fact, each array also had a shape. Each of the arrays above is a $1 \times N$ array, where the 1 indicates the number of rows (one in each case), and $N$ is the length of the array.

The power of Matlab comes from its ability to easily manipulate two, three, and higher dimensional arrays. In the above example, neither linspace nor the colon operator, by themselves, can be used to construct higher dimensional arrays. But the rand can. For example,

A = rand(3,5)
A =
   4.3024e-02   7.3172e-01   5.4701e-01   1.8896e-01   3.6848e-01
   1.6899e-01   6.4775e-01   2.9632e-01   6.8678e-01   6.2562e-01
   6.4912e-01   4.5092e-01   7.4469e-01   1.8351e-01   7.8023e-01

creates a $3 \times 5$ array, or an array with 3 rows and 5 columns.

We can even construct three dimensional arrays with the rand function:

B = rand(4,2,3)
B(:,:,1) =
   8.1126e-02   4.3586e-01
   9.2939e-01   4.4678e-01
   7.7571e-01   3.0635e-01
   4.8679e-01   5.0851e-01
B(:,:,2) =
   5.1077e-01   3.7861e-01
   8.1763e-01   8.1158e-01
   7.9483e-01   5.3283e-01
   6.4432e-01   3.5073e-01
B(:,:,3) =
   9.3900e-01   5.8704e-01
   8.7594e-01   2.0774e-01
   5.5016e-01   3.0125e-01
   6.2248e-01   4.7092e-01

Back to the top

Shapes of arrays

The shape of two dimensional arrays can be characterized by how many rows and columns it has. For every array (including scalars, which, in Matlab, are just $1\times 1$ arrays) Matlab stores its dimensions and its number rows and columns. To find the shape of an array, we can use the size function. For example,

A = rand(4,3)
[r,c] = size(A);
fprintf('A has %d rows and %d columns\n',r,c);
A =
   2.3049e-01   1.7071e-01   9.2338e-01
   8.4431e-01   2.2766e-01   4.3021e-01
   1.9476e-01   4.3570e-01   1.8482e-01
   2.2592e-01   3.1110e-01   9.0488e-01
A has 4 rows and 3 columns

Two arrays have the same shape if they have the same number of rows and columns.

If we only ask for one return argument, we will get an array containing the length of both dimensions.

mn = size(A)
mn =
     4     3

If we ask for the length of an array in which neither dimension is 1, we will get the length of the largest dimension. This comes in handy if you know your array has, for example, many more rows than columns (as if often the case with large data sets) and you simply want to know how many rows of data you have.

my_data = zeros(237,5);
length(my_data)
ans =
   237

In Matlab, even string variables have a length. For example,

s = 'Hello, World';
length(s)
ans =
    12

Back to the top

Indexing two dimensional arrays

We have already seen how we can retrieve a single entry in a one-dimensional array. We simply use the parenthesis operator () with an argument indicating the entry we want.

v = (1:10).^2
v =
     1     4     9    16    25    36    49    64    81   100

Retrieve the second entry in v

v(2)
ans =
     4

Retrieving a single entry from a two dimensional array uses the () operator as well, but this time with two arguments, the desired row and column index.

A = magic(4)  % Create a 4x4 magic square
A =
    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

Retrieve the entry in the first row, second column

A(1,2)
ans =
     2
A(3,4)
ans =
    12
A(2,3)
ans =
    10

As with one dimensional arrays, we can also retrieve multiple entries in a two dimensional array at once. For example, to get the second row of the array A above, we use the : operator.

A(2,:)
ans =
     5    11    10     8

The third column is obtained in analogous fashion:

A(:,3)
ans =
     3
    10
     6
    15

To obtain rows 1 and 3 at the same time, we can use integer arrays in exactly the same way that we used them in the vector case.

A([1 3],:)
ans =
    16     2     3    13
     9     7     6    12

To retrieve columns 2 and 3, we do the following

A(:,[2 3])
ans =
     2     3
    11    10
     7     6
    14    15

And finally, if we want the last column or row, we use the end keyword. The last column of A is

A(:,end)
ans =
    13
     8
    12
     1

and the last row is

A(end,:)
ans =
     4    14    15     1

The : operator by itself, when used in arrays can be used to retrieve the entire array as one long vector. When used with row vectors, it has the additional effect of converting the array to a column vector.

A(:)
ans =
    16
     5
     9
     4
     2
    11
     7
    14
     3
    10
     6
    15
    13
     8
    12
     1
v(:)
ans =
     1
     4
     9
    16
    25
    36
    49
    64
    81
   100

Suppose we really wanted to see if A is a magic square. We need to see if the rows and columns each add up to the same number. There are many ways to do this in Matlab, but here, we will use a single for loop.

for i = 1:4,   % sum over rows
    row_sum(i) = sum(A(i,:));
end

for j = 1:4,   % Sum over columns
    col_sum(j) = sum(A(:,j));
end
% Row sum :
row_sum
row_sum =
    34    34    34    34
% Column sum :
col_sum
col_sum =
    34    34    34    34

The row sums and the column sums are equal, so A is a magic square.

Back to the top

Assigning values to arrays

We use array indexing to not only select values from an array, but also to assign particular values to an array. For example, we can create an $4\times 3$ array of all 1s and then reassign the third row to contain values [1,2,3]

X = ones(4,3)
X =
     1     1     1
     1     1     1
     1     1     1
     1     1     1
X(3,:) = -rand(1,3)
X =
   1.0000e+00   1.0000e+00   1.0000e+00
   1.0000e+00   1.0000e+00   1.0000e+00
  -9.7975e-01  -4.3887e-01  -1.1112e-01
   1.0000e+00   1.0000e+00   1.0000e+00

The array on the right hand side should have the same shape as the array array indexed on the left hand side. In the above example, the use of the ': allows us to specify all the columns. The array on the left hand side, then should have the same number of columns as those in the array X.

Here is an example in which we re-assign the 'interior' entries of an array the value 7.

A = zeros(5,5)
A =
     0     0     0     0     0
     0     0     0     0     0
     0     0     0     0     0
     0     0     0     0     0
     0     0     0     0     0
A([2:4],[2:4]) = 7
A =
     0     0     0     0     0
     0     7     7     7     0
     0     7     7     7     0
     0     7     7     7     0
     0     0     0     0     0

We can assign the 'exterior' values of the array to a different value, but this will require two steps. First, we assign the first and last columns the value -3.

A(:,[1 end]) = -3
A =
    -3     0     0     0    -3
    -3     7     7     7    -3
    -3     7     7     7    -3
    -3     7     7     7    -3
    -3     0     0     0    -3

And then we assign the top and bottom rows the same value.

A([1 end],:) = -3
A =
    -3    -3    -3    -3    -3
    -3     7     7     7    -3
    -3     7     7     7    -3
    -3     7     7     7    -3
    -3    -3    -3    -3    -3

There are many instances in which we need to use arrays to store values, say from an iterative calculation that we are doing. In this case, we might use a for loop. The following simple example shows how we might use the series approximation to the function $\sin(x)$ to approximate the sine function. $$ \sin(x) = \sum_{i=0}^{\infty} \frac{(-1)^{i} x^{2i+1}}{(2i+1)!} $$ We can show how the approximations get closer and closer to our desired value, and plot the convergence of the sum.

sinx = 0;
x = 1.2;
for i = 0:10,
    n = 2*i+1;
    sinx = sinx + (-1)^i*x^n/factorial(n);
    approx(i+1,:) = [sinx abs(sinx-sin(x))];
    fprintf('%2d %24.16f %12.4e\n',i,approx(i+1,1),approx(i+1,2));
end
 0       1.2000000000000000   2.6796e-01
 1       0.9119999999999999   2.0039e-02
 2       0.9327359999999999   6.9691e-04
 3       0.9320250514285713   1.4035e-05
 4       0.9320392703999999   1.8443e-07
 5       0.9320390842607376   1.7065e-09
 6       0.9320390859789461   1.1720e-11
 7       0.9320390859671641   6.2172e-14
 8       0.9320390859672265   2.2204e-16
 9       0.9320390859672263   0.0000e+00
10       0.9320390859672263   0.0000e+00

Because we stored the values in an array, we can now plot our approximations.

close all;
plot(0:10,approx(:,1),'.-','markersize',30);
hold on;
plot([0 10],[sin(x) sin(x)],'k--');
xlim([0 10]);
title('Approximation to sin(x) using a Taylor series','fontsize',18);
xlabel('i','fontsize',16);
ylabel('Approximation i','fontsize',16);

Back to the top

Array concatenation for two dimensional arrays.

We already had a simple introduction to array concatenation for one-dimensional arrays. Now let's extend this idea to two dimensional arrays. First, it will be convenient to use the square brackets to build column vectors as well as row vectors. We have already seen that

v = [1,2,3]
v =
     1     2     3

builds a row vector. Using [] in a similar fashion, we can also create a column vector. This time, however, we must separate each entry by a semi-colon (;) to indicate that we want to "stack" the numbers on top of each other.

v = [1;2;3]
v =
     1
     2
     3

In Matlab, this way building of arrays from existing components (numbers, in this case), is called "concatenation". Concatenation can either be done horizontally (as was done in the first example above) or vertically (as in the second example).

This idea of array concatenation extends naturally to situations where the components are not just numbers, but are themselves arrays. For example, suppose we wanted to build an array by stacking existing row vectors on top of each other. This can easily be done using vertical concatenation.

% Three row vectors
a = [1,2,3];
b = [4,5,6];
c = [7,8,9];

% Build A by vertical concatenation
A = [a; b; c]
A =
     1     2     3
     4     5     6
     7     8     9

In a similar fashion, we can build an array from existing column vectors.

% Three column vectors
a = [1; 2; 3];
b = [4; 5; 6];
c = [7; 8; 9];

% Build A using horizontal concatenation
A = [a b c]
A =
     1     4     7
     2     5     8
     3     6     9

Of course, array concatenation can fail if you try to stack arrays that are not "conformable", i.e. their sizes don't match. Try the following :

A = [1; [2 3]]

Error using lab_5 (line 315)
Error using vertcat
CAT arguments dimensions are not consistent.

In this case, we are trying to stack a single number on top of a 1x2 row vector. The number of columns in the components we are trying to stack do not match, and Matlab complains.

The following, however, works

A = [1 [2 3]]
A =
     1     2     3

We can always horizontally concatenate two row vectors of different sizes.

Back to the top

Loading data files

Often, data will be stored in a local file on your harddrive. You can construct an array from this file by simply loading this file into Matlab using the load command. For example, suppose we have the file my_data.dat stored in the local working directory. We can load this file into an array called A using the command

A = load('my_data.dat');

The array A will then have the same number of rows and columns as the file. For example, suppose that the file 'A.dat' looks like this

% File A.dat
3.4  5.6
4.7  8.9
-5.1 6.7
-2.1 5.6

Then, we can load the file and assign the results to the variable A.

A = load('A.dat')
A =
   3.4000e+00   5.6000e+00
   4.7000e+00   8.9000e+00
  -5.1000e+00   6.7000e+00
  -2.1000e+00   5.6000e+00

The file name and the variable name do not have to match. Also, comments can be included in data files in the same way that they can be included in m-files.

Back to the top

Lab exercises

Construct the arrays described below, using Matlab functions, array assignment, or array concatenation.
  1. A $10\times1$ array of all 1s.
  2. A $2\times 9$ array in which the entries in the first row are all equal to $\pi$ and the entries in the second row are all equal to $e$.
  3. A $5\times3$ array of random numbers.
  4. A $5\times3$ array of random numbers between -1 and 1.
  5. A $3\times4$ array of all 1s, with the exception of the second row, which has been replaced by a row of -4s.
  6. A $7\times5$ array, in which the first 6 rows are random numbers between -1 and 1, and the last row is chosen so that the sum of all the rows is exactly a row of 0s.
  7. A $10\times 10$ array with 1s in the first columm, 2s in the second column, 3s in the third column and so on.
  8. A $7\times7$ array in which the outer 'layer' of values is 0, the next layer is all 1s, and the innermost entry is 3.


Using a for loop, demonstrate the convergence of the series expansions of the following functions. Evaluate each function at the indicated value.
  1. $$\cos(x) = \sum_{n=0}^{\infty}\frac{(-1)^{n}x^{2n}}{(2n)!}$$ at $x=5.4$.
  2. $$\exp(x) = \sum_{n=0}^{\infty} \frac{x^n}{n!}$$ at $x=0.2$.
  3. $$\ln(1+x) = \sum_{n=0}^{\infty} \frac{(-1)^{n-1}x^n}{n}$$ at $x=-0.5$.

Compare your answers with the solutions.

Back to the top

Get the code

Do you want to try the above code fragments on your own? Download the Matlab script that produces this page here. (lab_5.m)

Powered by MathJax

Published with MATLAB® 8.6