%% The 'for-loop' and vectorizaton %% Introduction % % In this lab, you will learn how to control the flow of execution of % commands using a for loop. % %% 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! This is iteration %d\n',i); end %% The anatomy of the 'for' loop % % 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; i = %2d\n',i); end %% % Example 2 for x = [3.1 5.6], fprintf('A couple of ducks; x = %4.1f\n',x); end %% % Example 3 for j = 10:-2:0, fprintf('Six Simple Simons sitting on a stump; j = %2d\n',j); 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 most cases, the statements enclosed by the for loop will involve the value of the % loop index variable. 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.
%
    %
  1. The for loop may enclose % multiple Matlab statements,
  2. %
  3. The number of times that enclosed statements get % executed is equal to the length of the loop index array,
  4. %
  5. The loop index variable may be used by the enclosed % statements,
  6. %
  7. 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. %
  8. 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.
  9. %
%
% %% When to vectorize? % % Often in Matlab, loops can be avoided by vectorizing the % statements inside. In the following examples, a for loop can easily be replaced with a single % of vectorized code. Notice that the print statements have also been % vectorized. % %% % % Example

% % for-loop : y = 10*x + 1 x = rand(1,5); y = zeros(size(x)); % Avoid warnings! for i = 1:5, y(i) = 10*x(i) + 1; fprintf('x(%d) = %8.4f; y(%d) = %8.4f\n',i,x(i),i,y(i)); end %% % Vectorized equivalent (preferable!) y = 10*x + 1; % Vectorized print statement fprintf('x(%d) = %8.4f; y(%d) = %8.4f\n',[1:5; x; 1:5; y]); %% % % Example

% % for-loop : y = sin(pi*x/4) over [0,2*pi] for j = 1:9, y(j) = sin(pi*(j-1)/4); fprintf('y(%d) = %16.8f\n',j,y(j)); end %% % vectorized equivalent (preferable!) y = sin(pi*((0:8)/4)); % Parenthesis around (0:8) are important here! % Vectorized print statement fprintf('y(%d) = %16.8f\n',[1:9; y]); %% % % Example

% % for-loop : Cumulative summation s = 0; y = zeros(1,10); for k = 1:10, s = s + k; y(k) = s; fprintf('Sum of the numbers 1 to %2d : %5d\n',k, y(k)); end %% % vectorized equivalent y = cumsum(1:10); % Vectorized print statement fprintf('Sum of the numbers 1 to %2d : %5d\n',[1:10; y]); %% % % Example

% Sometimes, vectorization will be many times faster than an equivalent % loop. For example, % N = 1e7; th = linspace(0,2*pi,N); tic for i = 1:N, y(i) = sin(th(i)); end t1 = toc; %% % Vectorized statement tic y = sin(th); t2 = toc; fprintf('Time in loop : %8.4f\n',t1); fprintf('Time in vectorized statement : %8.4f\n',t2); fprintf('The vectorized statement is %6.2f times faster\n',t1/t2); %% % % There are many more examples of the above in which a vectorized statement % is far preferable to using a loop. % %% Advanced vectorization example % % While many common mathematical statements can be easily vectorized (and % should be!) some complex programming tasks are not so obviously % vectorizable. Below is an example of a programming task that is % sufficiently complex, that one is tempted to leave it in a loop. Inside % the loop, we are still using array vectorization, but there does not % seem to be an easy way to vectorize the outer loop. As we will see, % however, an advanced use of vectorization allows the computation to be % done without any loops, which ultimately leads to a faster version of % the code. % % ------------------------------------------------------------------- % Compute the minimum and maximum distance between all possible pairs of % points in a set of points (x(i),y(i), 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] tic; dmax = 0; dmin = 100; for i = 1:n, % Compute the distance between the point (x(i),y(i)) and the % array of points (x,y). first, remove x(i),y(i) from % list (so the minimum isn't just 0!). x1 = x; y1 = y; x1(i) = []; % Remove x(i) from list y1(i) = []; % Remove y(i) from list % This is a vectorized statement. d = sqrt((x(i) - x1).^2 + (y(i) - y1).^2); % Find the maximum value in the array [d dmax] dmax = max([d dmax]); % Find the minimum value in the array [d dmax] dmin = min([d dmin]); end t_loop = toc; fprintf('Elapsed time for loop version %8.4e\n',t_loop); for i = 1:n % Plot the line connecting the points (x(i),y(i)) each point in the % array (x,y). % This loop is "nested" inside of our outer loop. While we could % vectorize this loop, it might not be so easy to read, and probably % doesn't save us much time. for j = 1:n, plot([x(i) x(j)],[y(i),y(j)],'b-','linewidth',2); hold on; end end fprintf('The minimum distance is %8.4f\n',dmin); fprintf('The maximum distance is %8.4f\n',dmax); % Plot a symbol at each point and add a title and axes labels. plot(x,y,'r.','markersize',30,'linewidth',2); set(gca,'fontsize',16,'fontweight','bold') title('Point cloud'); 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; %% % % We can vectorize the part of the code that computes the minimum distance. % with the following code % fprintf('Vectorized version\n'); tic; e = ones(n,1); % Main part of the code dist = sqrt((e*x-(e*x).').^2 + (e*y-(e*y).').^2); dist = dist + diag(nan*e); dmax = max(dist(:)); dmin = min(dist(:)); t_vec = toc; fprintf('Elapsed time in vectorized version : %8.4e\n',t_vec); fprintf(['Vectorized version is about %4.0f%% faster \n',... 'than the non-vectorized version\n'],100*(t_loop-t_vec)/t_loop); fprintf('The minimum distance is %8.4f\n',dmin); fprintf('The maximum distance is %8.4f\n',dmax); %% % % Note : Timing results from Publish (used to % produce this webpage) are not truly reflective of actual timing results, % but relative timings for vectorized verses non-vectorized codes should be % approximately correct. % %% 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: %
    %
  1. Using a single Matlab function
  2. %
  3. 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!. %
    %
  1. % $\displaystyle{\sum_{k=1}^{n} x_k}$
  2. %
  3. % $\displaystyle{\min_{1 \le k \le n} x_k}$
  4. %
  5. % $\displaystyle{\frac{1}{n}\sum_{k=1}^n {x_k}}$
  6. %
  7. % $\displaystyle{y_j = \prod_{k=1}^j {x_k}}$, % for $j = 1,2,...,n$
  8. %
  9. % $\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}$
  10. %
  11. $\displaystyle{n}$ %
  12. Find the value $\sigma$ % in $x$ such % that half of the values $x_k$ are % less than $\sigma$ and half are % greater than $\sigma$.
  13. %
  14. % $\displaystyle{\max_{1 \le k \le n} x_k}$
  15. %
  16. % $\displaystyle{y_j = \sum_{k=1}^j {x_k}}$ % for $j = 1,2,...,n$
  17. %
  18. % $\displaystyle{\prod_{k=1}^{n} x_k}$
  19. % %
%

%
% 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. %
  3. $$\exp(x) = \sum_{n=0}^{\infty} % \frac{x^n}{n!}$$ at $x=0.2$.
  4. %
  5. $$\ln(1+x) = \sum_{n=0}^{\infty} % \frac{(-1)^{n-1}x^n}{n}$$ at $x=-0.5$.
  6. %
% % 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.

%