%% Loops and one dimensional arrays
%% Introduction
%
% So far, we have covered how to use linspace
% to construct a one-dimensional array useful for plotting. In this lab,
% we want to explore other ways to create one-dimensional arrays.
%
% We will also learn how to retrieve particular entries of an array, as
% well as how to use the for loop to control
% the flow execution of statements in a script.
%
%% Using the colon operator to construct arrays
%
% We have already seen how we can construct one dimensional arrays using
% the linspace command. We have also seen
% how to use square brackets to enclose a list of numbers:
%
x = [1 3 5 7 9]
%%
%
% Another method to construct an array that is very similar to the
% linspace makes use of the : operator. For example,
%
v = 1:10
%%
%
% constructs an array of 10 integers between 1 and 10. A more general use
% of the colon (:) operator allows us to
% specify the step size we wish to take.
%
v = 0:2:20
%%
%
% is a list of even numbers between 0 and 20. The step size can also be
% negative. For example,
%
v = 5:-1:-5
%%
%
% or
%
v = 50:-5:0
%%
%
% Querying the help documentation on the
% the colon operator gives us:
% % >> help colon
% : Colon.
% J:K is the same as [J, J+1, ..., K].
% J:K is empty if J > K.
% J:D:K is the same as [J, J+D, ..., J+m*D] where m = fix((K-J)/D).
% J:D:K is empty if D == 0, if D > 0 and J > K, or if D < 0 and J < K.
% .............
%
%
% Like linspace, the colon operator
% automatically fills in entries in an array with equally spaced points.
% However, we can get some unexpected results if the endpoints we specify
% are not evenly divided by the stepsize we specify. Consider the
% following example
%
v = 0:3:10
%%
%
% We notice that the endpoint 10 does not appear in the array. The reason
% for this is that 10 is not evenly divided by 3, so is not reached in
% steps of 3 starting from 0. Rather than shorten the last step size,
% Matlab only includes those values between the specified endpoints that
% are even multiples of the step size and shifted by the first endpoint.
%
% Carrying the above example further, we see that it is possible to
% construct an array that contains only a single element :
%
v = 10:15:20
%%
%
% In this case, one step already takes us beyond the specified endpoint,
% and so the vector only contains the starting point 10.
%
% What happens if the step size does not have the same sign as our end
% value minus our start value? In this case, Matlab will create an
% empty array. The following example illustrates this.
%
v = 0:-1:10
%%
%
% Here, 10-0 is positive, but our stepsize -1 is negative, and so an empty array is created. Any
% time we use a step size of 0, we will also get an empty array. The
% simplest empty array in Matlab is an empty pair of square brackets ([]).
%
v = []
%%
%
% The length of an empty array is 0.
%
length(v)
%% The colon operator and the linspace command
%
% We can use the colon operator to construct the same array that linspace creates. To describe how the colon
% operator and the linspace are related, we
% consider a vector with a start point a, end
% point b and n equally
% spaced entries. Using linspace, we create
% this vector as
%
a = -1; % start of the linspace vector
b = 1; % end of the linspace vector
n = 11; % Number of points in the linspace vector
x1 = linspace(a,b,n)
%%
%
% To construct the same same vector using the colon operator, we need to
% first compute the step size that linspace used.
%
step = (b - a)/(n-1) % Step size used by linspace
%%
%
% And then we can construct the same vector using the colon operator.
%
x2 = a:step:b
%%
%
% A word of warning : Whereas the linspace is guaranteed to have exactly a and b as endpoints, and
% exactly n entries, this is not guaranteed when
% using the colon operator. We have already seen above that the : operator will leave off the final entry if it
% cannot be expressed in terms of multiples of the stepsize. This can
% also happen, even when the step sizes are only nearly divide the
% interval.
%
step = (1+1e-15)/5;
v = 0:step:1
%%
%
% In this example, we divided an interval slightly larger than $1$ by the
% $5$, and then used this step size to construct an array. The final
% element in the array is not 1, as might be expected, but rather is a
% value very close to 0.8. To see why this is, we print out the value
% 5*step and see that it is in fact larger than
% 1, if only by a very small amount.
%
format long e
5*step
%% Indexing arrays
%
% To retrieve a single entry from a one-dimensional array, we can use the
% parenthesis operator () with an argument
% indicating the entry we want. First, we will create an array of random
% numbers using the rand function.
%
format short e
v = rand(1,10)
%%
%
% We can retrieve the second entry in v as
%
v(2)
%%
%
% We can also retrieve multiple elements of an array by using an array of
% index locations. Suppose we wanted to retrieve every other element in an
% array of 7 elements. We pass an integer sequence indicating the entries
% we want to the () operator.
%
v([1,3,5,7])
%%
%
% Alternatively, we could do the following.
%
v(1:2:7)
%%
%
% In both cases, we used an array of integers to specify the desired
% indices. We can also use the colon operator to reorder the entries in
% the array :
%
w = v(10:-1:1)
%%
%
% In fact we can choose entries in order, even duplicating entries :
%
w = v([5 7 2 9 9 3 2 2])
%%
%
% In Matlab, the first entry in an array is always 1. If we try to index the zero-th element of an
% array, we can expect an error
%
% v(0)
%
% % Subscript indices must either be real positive integers or logicals.
%
%
% If we use an index that is larger than the number of elements that we
% have, we can also expect an error:
%
% v(12)
%
% % Index exceeds matrix dimensions.
%
%
%%
%
% What if you want to get the last three entries in an array? Since the
% length of an array is often one of the variables in the script you are
% writing, you might consider doing the following.
%
n = length(v);
v([n-2 n-1 n])
%%
%
% Here, we used the Matlab length function
% to find out how long v is.
%
% The above situation arises so often, that Matlab has built into the
% language a way to get the last entries of a vector by allowing the use of
% the end keyword inside of arrays. This
% statement retrieves the last entry in an array
%
v(end)
%%
%
% To retrieve the last three entries in an array, you can use the end as if it were the actual variable or constant
% storing the length of the array. For example,
%
v([end-2 end-1 end])
%%
%
% or simply
%
v(end-2:end)
%% Simple array concatenation
%
% We can always construct a new array by glueing two arrays together. For example, suppose we have two row vectors u and v. We can construct a
% new array w by glueing, or
% concatenating u and v together using square brackets.
%
u = -5:-2
%%
v = 21:27
%%
w1 = [u v]
%%
w2 = [v u]
%%
%
% The resulting arrays w1 and w2 each have length equal to the sums of the lengths
% of u and v.
%
% Example : Approximating $\pi$
% Suppose we
% want to approximate the value of $\pi$ by
% computing the length of an n-sided the polygon whose vertices are on the
% quarter circle of radius 2, as shown below.
%
%
%
% To approximate $\pi$, we compute
% the perimeter of the polygon described by this quarter circle.
%
%
% We construct arrays x and y containing the coordinates of each vertex of the
% quarter of a circle (including the origin), and then compute the distance
% between each neighboring pair of vertices $(x_i,y_i)$ and $(x_{i+1},y_{i+1})$. For
% convenience, we use array concatenation to add the first point $(x_1,y_1)$ to the end of our vertex list so
% that we have $x_{n+1} = x_1$ and $y_{n+1} = y_1$. We can then compute the
% length of each side of the polygon with a single Matlab statement and
% then sum the lengths to get the perimeter of the polygon. By subtracting
% out the length of the edges that lie on the x and y axes, we can get an
% approximation to $\pi$.
%
% ---------------------------------------------------------
% Approximate pi by computing the perimeter of a semicircle
% ---------------------------------------------------------
n = 8; % Number of vertices on the polygon
R = 2; % Radius of the circle
th = pi*(0:n)/(2*n); % Angles 'theta' between 0 and pi/2
x = R*cos(th); % x-coordinates along the semicircle
y = R*sin(th); % y-coordinates along the semicircle
% Construct the vertex list, including the point (0,0). Wrap the first
% point around to the end of the list.
x = [x 0 x(1)];
y = [y 0 y(1)];
% Compute distances between each neighboring pair of points
d = sqrt((x(1:end-1) - x(2:end)).^2 + (y(1:end-1) - y(2:end)).^2);
% Approximate pi by adding up the lengths of the edges of the polygon, and
% and subtracting out the segments that lie along the x- and y-axis.
pi_approx = sum(d)-4;
% Print out the results
fprintf('Approximation to pi %24.16f\n',pi_approx);
fprintf('Matlab value ''pi'' %24.16f\n',pi);
fprintf('Error %24.8e\n',abs(pi_approx - pi));
%%
%
% This approximation uses the sum function
% which we will discuss in more detail below.
%
%% Introduction to the 'for' loop
%
% Up until now, commands in a script have been executed in the order in
% which they appear in a script. We can control this order of execution
% using flow control statements. The for loop is a type of flow control statement that
% allows us to execute a set of commands multiple times. For example, in
% the following code fragment, the statement fprintf('Hello, World\n') gets executed 10 times,
% even though it only appears once in the code fragment.
%
for i = 1:10,
fprintf('Hello, World!\n');
end
%%
%
% The for loop has three basic components :
% the enclosing keywords for and end which enclose the set of statements to be
% carried out multiple times by the loop (the statement
% fprintf('Hello, World\n'),
% in the above example), a loop index which is
% the variable that stores the current value of the loop counter (i in the above example), and an index array
% containing the range of values over which the loop index should vary (the
% array 1:10 in the above example).
% See below for the "Anatomy of a "for" loop"
%
%
% Anatomy of a for loop
%
%
% The number of times the loop executes the statements enclosed by the
% for and end
% is determined by the length of the array describing the loop range.
% Consider each of the following examples :
%
% Example 1
for i = 0:5:10,
fprintf('Three brown bears\n');
end
%%
% Example 2
for x = [3.1 5.6],
fprintf('A couple of ducks\n');
end
%%
% Example 3
for j = 10:-2:0,
fprintf('Six Simple Simons sitting on a stump\n');
end
%%
% Example 4
for j = 1:-1:10,
fprintf('I am being ignored (:-((\n');
end
%%
%
% In each case, the statement enclosed by for
% loop was executed once for each entry in the loop index array. In the
% last example, the loop index array is empty, and so the enclosed
% statement did not get executed at all.
%
%% The 'for' loop - using the loop index variable
%
% In the above examples, we did not make use of the actual values in the
% loop index array, only the length of the array. But in most cases, the
% statements enclosed by the for loop will
% actually involve the value of the loop index variable as well. Each of
% the following loop examples illustrates how we can make use of the loop
% index variable.
%
clear all;
%%
% Example 1 - Print out the value of the loop index
for i = 0:2:20,
fprintf('i = %d\n',i);
end
%%
% Example 2 - Print out the entries in an array 'x', in reverse order.
x = rand(1,10);
for k = 10:-1:1,
fprintf('x(%2d) = %8.4f\n',k, x(k));
end
%%
% Example 3 - Fill in entries in an array 'y' and print each value
for j = 1:8,
y(j) = sin(pi*(j-1)/2);
fprintf('y(%d) = %16.8f\n',j,y(j));
end
%%
% Example 4 - Cumulative sums of the integers 1 through 10.
s = 0;
for k = 1:10,
s = s + k;
fprintf('Sum of the numbers 1 to %2d : %5d\n',k, s);
end
%%
%
% In all of the above examples, the loop index is an integer. This
% is by far the most common loop index array for the for
% loop. However, there is nothing in Matlab to prevent us from trying the
% following unusual (and not particularly recommended) ways to use
% the loop index.
%
% Example 5 - A confusing example in which 'x' is an array and 'y' takes on
% different values in the array 'x'.
x = linspace(-1,1,7);
for y = x,
fprintf('y = %f\n',y);
end
%%
% Example 6 - Let's see what we can do with strings.
for c = ['Hello', 'Goodbye','See Ya!'],
fprintf('%s',c);
end
%%
%
% In the first case, the loop index array x is an
% array containing non-integer values, but the loop index y still takes on each value, and the print statement
% is executed the expected number of times, e.g. one time for each entry in
% x.
%
% The second example is less familar, but only because we have not worked
% with strings much. Here, the loop in index is the array of characters
%
s = ['Hello', 'Goodbye','See Ya!']
%%
%
% We can index into this array in exactly the same way as with numeric
% data. For example,
%
s(1:10)
%%
%
% We can also use the length function to get
% the length of s. This length tells us the
% number of times the statements in the for
% will be executed.
%
length(s)
%%
%
% So in this case as well, the for loop above
% is behaving exactly as expected. Notice that we did not put a new line
% character into the fprintf statement in the
% the loop. If we had, our output for the odd 'string' loop would look like
% the following. We have added a loop counter here as well to see that the
% in fact, the number of times that the code inside the loop is called is
% equal to the length of the loop index array. In this case, the variable
% k acts like the loop index variable and is
% incremented by 1 each time the code in the loop is executed.
%
% add a new line character to the fprintf statement.
k = 1;
for c = ['Hello', 'Goodbye','See Ya!'],
fprintf('%2d %s\n',k,c);
k = k + 1;
end
%%
%
% A final, entertaining example involves the use of a "cell" array. We
% will not discuss cell arrays in detail now, but suppose you really wanted to
% loop over a list of words. The following syntax will allow
% you to do this:
%
for word = {'Howdy', 'Later', 'Cheerio'},
fprintf('%s\n',word{:});
end
fprintf('The last word is ''%s''\n',word{:});
%%
%
% As this example illustrates, the value of the loop index after we
% have completed the loop is the last value in the loop index array.
%
%% Rules for using the 'for' loop
%
% Here are some basic principles to follow when using the
% for loop.
%
%
Rules and guidelines for the for loop.
%
% - The for loop may enclose
% multiple Matlab statements,
% - The number of times that enclosed statements get
% executed is equal to the length of the loop index array,
% - The loop index variable may be used by the enclosed
% statements,
% - One for loop may be
% nested inside of one another loop. Statements in the inner for loops may use the loop index variable from
% the outer loop.
%
- Loop index arrays most commonly contain
% integer values. Loop indices are often named i,
% j, k, m or n. Avoid the use of
% variable names x, y,
% z or w for loop
% indices.
%
%
%
% Example : Finding the maximum distance between pairs of
% points
% For a more complete example that requires the use of a for loop, we consider the problem of finding the
% maximum distance between all possible pairs of points with coordinates
% described by the arrays x and y. We will also include a loop in which we plot the
% line between a point in the array and each of the other points.
%
% -------------------------------------------------------------------
% Compute the maximum distance between all possible pairs of points
% in a set of points (xi,yi), i = 1,...n.
% -------------------------------------------------------------------
n = 15;
x = rand(1,n); % x-coordinates, chosen at random from [0,1]
y = rand(1,n); % y-coordinates, chosen at random from [0,1]
dmax = 0;
for i = 1:n,
% Compute the distance between the point (x(i),y(i)) and the
% array of points (x,y).
d = sqrt((x(i) - x).^2 + (y(i) - y).^2);
% Find the maximum value in the array [d dmax] (see 'max' function
% below).
dmax = max([d dmax]);
% Plot the line connecting the points (x(i),y(i)) each point in (x,y)
for j = 1:n,
plot([x(i) x(j)],[y(i),y(j)],'r-');
hold on;
end
end
fprintf('The maximum distance is %12.4e\n',dmax);
% Plot a symbol at each point and add a title and axes labels.
plot(x,y,'bp','markersize',15,'linewidth',2);
set(gca,'fontsize',16,'fontweight','bold')
title('Point star');
xlabel('x-coordinate','fontsize',16);
ylabel('y-coordinate','fontsize',16);
axis([0 1 0 1]);
% Fix aspect ratio so the plot is square.
axis square;
%% Simple array functions for one-dimensional arrays
%
% Matlab has several functions which operate on one-dimensional arrays. We
% have already see one such function, the length function, which returns the number of
% elements in the array.
%
x = 0:25:1000;
length(x)
%%
%
% Other such Matlab functions are convenient in that they allow us to avoid
% the use of for loops in many cases. A
% partial list of such functions include min,
% max, sum, prod, cumsum, cumprod, mean, median, std and sort. Below, we use an example to illustrate how
% each function works.
%
x = rand(1,1000);
v = 1:10;
%%
%
%
Example 1 : The minimum and maximum values of an array
%
fprintf('The minimum value in array x is %16.8f\n',min(x));
fprintf('The maximum value in array x is %16.8f\n',max(x));
%%
%
% Example 2 : The total sum and product of the entries
%
fprintf('The sum of the values in v is %16.8e\n',sum(v));
fprintf('The product of the values in v is %16.8e\n',prod(v));
%%
%
% Example 3 : The cumulative sums and products of the entries
%
fprintf('The array of cumulative sums of the entries of v are\n');
cumsum(v)
%%
fprintf('The array of cumulative products of v are\n');
format short e;
cumprod(v)
%%
%
% Example 4 : The mean, median and standard deviation
%
fprintf('The mean of the values of x : %16.8f\n',mean(x));
fprintf('The median of the values of x is : %16.8f\n',median(x));
fprintf('The standard deviation of the values of x is : %16.8f\n',std(x));
%%
%
% Example 5 : A sorted list of the numbers.
%
y = sort(x);
%%
%
% To see that we really have a sorted list, we will compare the first entry
% of y to the minimum value of x, and the last entry of y to
% the maximum value of x.
%
fprintf('The minimum value of x : %24.16f\n',min(x));
fprintf('The first entry of y : %24.16f\n',y(1));
%%
fprintf('The maximum value of x : %24.16f\n',max(x));
fprintf('The last entry of y : %24.16f\n',y(end));
%%
%
% Most of the functions illustrated above can be used in many ways, not
% just in the manner shown above. For example, the functions min and max can each
% take two array arguments, allowing us to easily compare the size of
% corresponding entries in two arrays.
%
% In the following example, we compare the entries in an array x of random values to the value 0.5 and create a new
% array in which the values in x larger than 0.5
% have been replaced by 0.5.
%
format short;
x = rand(1,10)
%%
y = min(0.5,x)
%% Lab exercises
%
%
% Associate each of the Matlab functions
%
min,
%
max,
%
sum,
%
prod,
%
cumsum,
%
cumprod,
%
mean,
%
median,
%
std
% with exactly one mathematical expression below. Then, compute the value
% of each mathematical expression by two different ways:
%
% - Using a single Matlab function
% - Using a for loop
%
% Compare your results to make sure you get the same result for each case.
%
% Put all of your commands into a script containing your solution to each
% problem. To start, first create an array
$x$ of 100 random values using the
rand function. For example,
%
%
% x = rand(100,1);
%
% You will use this array for each of the exercises.
%
%
Note: In most cases, it will be preferable to use the single
% Matlab command than the for loop!.
%
% -
% $\displaystyle{\sum_{k=1}^{n} x_k}$
% -
% $\displaystyle{\min_{1 \le k \le n} x_k}$
% -
% $\displaystyle{\frac{1}{n}\sum_{k=1}^n {x_k}}$
% -
% $\displaystyle{y_j = \prod_{k=1}^j {x_k}}$,
% for $j = 1,2,...,n$
% -
% $\displaystyle{\sqrt{\frac{1}{n-1}\sum_{k=1}^n (x_k - \mu)^2}}$,
% where $\displaystyle{\mu = \frac{1}{n}\sum_{k=1}^n
% x_k}$
% - $\displaystyle{n}$
%
- Find the value $\sigma$
% in $x$ such
% that half of the values $x_k$ are
% less than $\sigma$ and half are
% greater than $\sigma$.
% -
% $\displaystyle{\max_{1 \le k \le n} x_k}$
% -
% $\displaystyle{y_j = \sum_{k=1}^j {x_k}}$
% for $j = 1,2,...,n$
% -
% $\displaystyle{\prod_{k=1}^{n} x_k}$
%
%
%
% Example : Problem 1 below can be computing using the 'sum' function
% and a 'for' loop.
n = 100;
x = rand(1,n);
s = 0;
for i = 1:n,
s = s + x(i);
end
fprintf('Result from ''sum'' function : %24.16f\n',sum(x));
fprintf('Result from the ''for'' loop : %24.16f\n',s);
%%
%
% Compare your answers with the solutions.
%