Solutions to review questions ------------------------------------------- 1. (Lecture 27/28) Efficient implementation of Update given the property of P. function w = Update(P,v) % P is an n-by-n array of transition probabilities WITH THE % PROPERTY THAT P(i,j) IS ZERO IF |i-j|>1 . % v is an n-by-1 state vector. % w is the update of v. n = length(v); w = zeros(n,1); for i=1:n % Compute the i-th component of the new state vector.. if i==1 w(1) = P(1,1)*v(1) + P(1,2)*v(2); elseif i==n w(n) = P(n,n-1)*v(n-1) + P(n,n)*v(n); else w(i) = P(i,i-1)*v(i-1) + P(i,i)*v(i) + P(i,i+1)*v(i+1); end end 2. (Lectures 25 and 26) Consider the following function: function y = mergeSort(x) % x is a column n-vector. % y is a column n-vector consisting of the values in x sorted % from smallest to largest. n = length(x); if n==1 y = x; else m = floor(n/2); % Sort the first half.. y1 = mergeSort(x(1:m)); % Sort the second half... y2 = mergeSort(x(m+1:n)); % merge... disp(’Call merge’) y = merge(y1,y2); end How many lines of output are produced by the call y = mergeSort(rand(7,1))? Everytime there is a merge, the message is printed. In the following schematic, we show how the n=7 problem subdivides. The notation a:b means "the subproblem involving positions a to b of the original vector." We put < > around each subproblem that involves a merge. So the answer is 6. <1:7> / \ / \ / \ <1:3> <4:7>_____ / \ | \ / \ | \ 1:1 <2:3> <4:5> <6:7> / \ / \ / \ 2:2 3:3 4:4 5:5 6:6 7:7 3. (Lecture 26) Consider the function function MeshTriangle(x,y,L) % x and y are 3-vectors. L is a nonnegative integer. % Adds to the current figure window a level-L partitioning of the % triangle whose vertices are specified by the 3-vectors x and y. % Assumes that hold is on. if L==0 % No subdivision required... fill(x,y,'y','linewidth',1.5) else % A subdivision is called for... % Determine the side midpoints (a(1),b(1)), (a(2),b(2)), and (a(3),b(3)) a = [(x(1)+x(2))/2 (x(2)+x(3))/2 (x(3)+x(1))/2]; b = [(y(1)+y(2))/2 (y(2)+y(3))/2 (y(3)+y(1))/2]; % Color the interior triangle magenta... fill(a,b,'m','linewidth',1.5) % Apply the process to the three "outer" triangles... MeshTriangle([x(1) a(1) a(3)],[y(1) b(1) b(3)],L-1) MeshTriangle([x(2) a(2) a(1)],[y(2) b(2) b(1)],L-1) MeshTriangle([x(3) a(3) a(2)],[y(3) b(3) b(2)],L-1) end Assume that the length-3 vectors x and y define an equilateral triangle and that MeshTriangle(x,y,2) is executed. What fraction of the original triangle is displayed yellow? Assume that the original triangle has area 1. The original triangle is partitioned into four sub-triangles, each with area 0.25. (The interior triangle is colored mauve.) Each of the corner triangles is subdivided just one more time so each of these smaller triangle's area is 0.25*0.25. The interior triangle is colored mauve while the corner triangles are colored yellow. There are 3*3 of these yellow triangles. Thus, the final fraction is (3*3)*(.25*.25) = 9/16 4. (Lecture 23) Consider the following script: % Sampling rate. This many numbers/sec in the digital signal: Fs = 32768; % Duration of the tone is .25 sec. So these are the sample times... t = 0:(1/Fs):.25; % The touchtone phone pad frequencies for the rows... fR = [ 697 770 852 941]; % The touchtone phone pad frequencies for the columns... fC = [ 1209 1336 1477]; Buttons = { ’1’, ’2’, ’3’; ’4’, ’5’, ’6’; ’7’, ’8’, ’9’; ’*’, ’0’, ’#’}; for i = 1:4 for j = 1:3 % Play tone associated with Buttons{i,j} % Select the two frequencies and add... yR = sin(2*pi*fR(i)*t); yC = sin(2*pi*fC(j)*t); y = (yR + yC)/2; sound(y,Fs); pause(1) end end Now write a script that plays the tones associated with the random phone number T = floor(rand(7,1)*10). Fs = 32768; t = 0:(1/Fs):.25; fR = [ 697 770 852 941]; fC = [ 1209 1336 1477]; Buttons = { ’1’, ’2’, ’3’; ’4’, ’5’, ’6’; ’7’, ’8’, ’9’; ’*’, ’0’, ’#’}; T = floor(rand(7,1)*10) for k=1:7 m = T(k); % Determine the row and column of the button... if m==0 i=4; j = 2; else i = ceil(m/3); r = rem(m,3); if r==0 j=3; else j=r; end end yR = sin(2*pi*fR(i)*t); yC = sin(2*pi*fC(j)*t); y = (yR + yC)/2; sound(y,Fs); pause(1) end 5. (Lecture 22) Modify the given script so that it plays a randomly selected one-second excerpt from each of the .wav files. (You may assume that start to finish, each file plays for longer than one second.) % Here are the names of some .wav files PlayList = {’austin’,’noCry’,’Casablanca’}; for k=1:length(PlayList) [y,rate] = wavread(PlayList{k}); sound(y, rate) % Let the soundbite play out and add a second... pause(1) end % Solution % Plays a sequence of sound bites % Here are the names of some .wav files PlayList = {’austin’,’noCry’,’Casablanca’}; for k=1:length(PlayList) [y,rate] = wavread(PlayList{k}); L = length(y); % A random integer between and including 1 and L-rate+1 start = ceil(rand*(L-rate+1)) sound(y(start:start+rate-1),rate) % Let the soundbite play out and add a second... pause(1) end 6. (Lecture 26/27) Suppose z = MyF(x) is a function that accepts a real value x and returns a real value y. Assume that MyF is very expensive to evaluate. Write a script that sets up an n-by-n array Z with the property that Z(i,j) is assigned the value of MyF(1+abs(i-j)). Assume that n is initialized. % Note that there are only n distinct x-values at which we need to % evaluate MyF given the property of matrix Z. for k=1:n w(k) = MyF(k); end for i=1:n for j=1:n Z(i,j) = w(abs(i-j)+1); end end 7. (Lecture 25) Assume that insertSort(x) is faster than mergeSort(x) if the length of the input vector is less than 500. How would you modify the mergeSort function to make it more efficient? function y = mergeSort(x) % x is a column n-vector. % y is a column n-vector consisting of the values in x sorted % from smallest to largest. n = length(x); if n<500 y = insertSort(x); else m = floor(n/2); % Sort the first half.. y1 = mergeSort(x(1:m)); % Sort the second half... y2 = mergeSort(x(m+1:n)); % Merge... y = merge(y1,y2); end 8. (Lecture 27/28) % Let A be a connectivity matrix, i.e., % if A(i,j) is one, then there is a link on webpage j % to webpage i. Write a fragment that prints "yes" if it is % possible to go from web page #100 to webpage #200 in one or two clicks. % Assume that the number of webpages is >=200. % Thus, if A(101,100) = 1 and A(200,101) = 1 then "yes". [n,m]= size(A); if A(200,100)==1 % One click away... disp(’yes’) else % See if it is possible to reach in two clicks. % Quit as soon as success. Found = 0; k =0; while k (R.top - R.bot) ) Square = MakeRect(R.left,R.left + R.top - R.bot, R.bot, R.top); LeftOver = MakeRect(R.left + R.top - R.bot, R.right, R.bot, R.top); else Square = MakeRect(R.left, R.right, R.bot, R.bot + R.right - R.left); LeftOver = MakeRect(R.left, R.right, R.bot + R.right - R.left, R.top); end %Chapter 10 Sec 2 #8 function LittleRs = Subdivide(R) % Divide rectangle R into four equal rectangles by connecting the midpoints % of the opposite sides. % R is a rectangle structure; LittleRs is a length 4 array of rectangles. len1 = R.right - R.left; len2 = R.top - R.bot; LittleRs(1) = MakeRect(R.left, R.left + len1 / 2, R.bot, R.bot + len2 /2); LittleRs(2) = MakeRect(R.left + len1 / 2, R.right, R.bot, R.bot + len2 /2); LittleRs(3) = MakeRect(R.left + len1 / 2, R.right, R.bot + len2 / 2, R.top); LittleRs(4) = MakeRect(R.left, R.left + len1 / 2, R.bot + len2 / 2, R.top); %Chapter 10 Sec 2 #10 function area = OverlapArea(R1, R2) % Return the area of the intersection of rectangles R1 and R2. R1_Is_Above = R1.bot > R2.top; R1_Is_Below = R2.bot > R1.top; R1_Is_Right = R1.left > R2.right; R1_Is_Left = R2.left > R1.right; if (R1_Is_Above || R1_Is_Below || R1_Is_Left || R1_Is_Right) area = 0; else area = (min(R2.top, R1.top) - max(R2.bot, R1.bot)) * ... (min(R2.right, R1.right) - max(R1.left, R2.left)); end %Chapter 10 Sec 3 #1 function A = TriangleArea(T) % A is the area of triangle T. a = GetDist(T.A, T.B); b = GetDist(T.C, T.B); c = GetDist(T.C, T.A); s = (a + b + c) /2; A = sqrt(s * (s - a) * (s - b) * (s - c)); %Chapter 10 Sec 3 #5 function A = PolygonArea(V) % V is a length n structure array of points with the property that % V(1), . . . ,V(n) are arranged clockwise around the unit circle. % Return the area of polygon P, which is the n-sided polygon obtained by % connecting the neighboring points. A = 0; cx = 0; cy = 0; for i=1:length(V) cx = cx + V(i).x; cy = cy + V(i).y; end cx = cx / length(V); cy = cy / length(V); C = MakePoint(cx, cy); for i=1:length(V) j = i + 1; if j > length(V) j = 1; end T = MakeTriangle(V(i), V(j), C); A = A + TriangleArea(T); end %Chapter 14 Sec 1 #2 % Author: Chin Isradisaikul function m=FactorialR(n) % Return the factorial of n. % n is a nonnegative integer. % m is the factorial of n. % base case: 0!=1 if n==0 m=1; else % recursive case m=n*FactorialR(n-1); end %Chapter 14 Sec 1 #3 % Author: Chin Isradisaikul function t=Reverse(s) % Nonrecursive version of string reversion. % s is the string to be reversed. % t is the reverse of s. % determine the length of s len=length(s); % Initialize the reverse as the empty string. t=''; % Use a for loop to reverse s by starting at the end of s, work backward to % In general, if the position of s is i, then the position of t is len-i+1; for i=len:-1:1 t(len-i+1)=s(i); end function t=ReverseR(s) % Recursive version of string reversion. % s is the string to be reversed. % t is the reverse of s. % determine the length of s n=length(s); % base case: (n==1) s is the reverse of itself if n==1 % simply assign s (which is the reverse of s) to t t=s; else % obtain the reverse of the last n-1 characters of s recursively subReverse=ReverseR(s(2:n)); % append the first character of s to the reverse t=[subReverse s(1)]; end % Script to compare reverse and reverseR: % To compare the execution times for both versions of string reversion, we % will reverse a long string many times and take the average of the total % execution time. % generate a long string N=100; % number of strings % print table header fprintf(' len Nonrecursive Recursive\n'); fprintf('-------------------------------------\n'); for n=1:N s=''; len=n*10; % length of string is 10 times the string number for i=1:len % simply assign a to each position of the string % s will be a long string of a's s(i)='a'; end numIter=100; % number of iterations % time the nonrecursive version tic % reverse s repeatedly for i=1:numIter Reverse(s); % ignore the result end timeN=toc; % time the recursive version tic % reverse s repeatedly for i=1:numIter Reverse(s); % ignore the result end timeR=toc; % display execution time fprintf('%5d %15.5f %15.5f\n',len,timeN/numIter,timeR/numIter); end % The recursive version is a little bit faster than the nonrecursive % version. However, if we used vectorized code in the nonrecursive % version, then the nonrecursive versioin should be faster.