Homework 2
Homework 2
1. Semilog plot. Over the past 5 years, the number of students in 6.094 has been
15, 25, 55,115,
144. Class size seems like it’s growing exponentially. To verify this, plot these
values on a plot with a log y scale and label it (semilogy, xlabel, ylabel, title).
Use magenta square symbols of marker size 10 and line width 4, and no line
connecting them. You may have to change the x limits to see all 5 symbols
(xlim). If the relationship really is exponential, it will look linear on a log plot.
% plotClassSize
% plots the number of students in 6.094 over 5 years on a
semilog plot
% open a figure and plot the data
figure
semilogy([1 2 3 4 5],[15 25 55 115
144],'ms','markersize',10,'linewidth',4);
% change x limits and label it
xlim([0.5 5.5]);
xlabel('Year');
ylabel('Number of Students')
title('Number of students per year in 6.094');
% randomSurface
% plots a random surface plot
% make the random values and the corresponding X and Y
grids
Z0=rand(5);
[X0,Y0]=meshgrid(1:5,1:5);
% make the new X and Y grids using a finer spacing
[X1,Y1]=meshgrid(1:.1:5,1:.1:5);
% interpolate
Z1=interp2(X0,Y0,Z0,X1,Y1,'cubic');
% draw the surface, specify hsv colormap and interpolated
shading
figure
surf(X1,Y1,Z1)
colormap(hsv)
shading interp
% plot the contour plot on the same figure
hold on
contour(X1,Y1,Z1,15);
% add colorbar and set caxis
colorbar
caxis([0 1]);
To get the smooth ‘interpolated’ colors to show up when the figure is copied and
pasted into a
document, use the ‘bitmap’, and ‘force white background’ options in ‘copy options’.
5. Fun with find. Write a function to return the index of the value that is nearest to a
desired value. The function declaration should be: ind=findNearest(x, desiredVal). x is a
vector or matrix of values, and desiredVal is the scalar value you want to find. Do not
assume that desiredVal exists in x, rather find the value that is closest to desiredVal. If
multiple values are the same distance from desiredVal, return all of their indices. Test
your function to make sure it works on a few vectors and matrices. Useful functions
are abs, min, and find. Hint: You may have some trouble using minwhen xis a matrix.
To convert a matrix Q into a vector you can do something like y=Q(:). Then, doing
m=min(y) will give you the minimum value in Q. To find where this minimum occurs in
Q, do inds=find(Q==m);.
function ind=findNearest(x,desiredVal)
% calculate the difference from each value in x and the
desired value
differences=abs(x-desiredVal);
minDiff=min(differences(:));
% find the index (or indices) where the difference of x and
desiredVal is
% at a minimum
ind=find(differences==minDiff);
To test the function, we did the following
6. Loops and flow control. Make function called loopTest(N) that loops through the
values 1 through N and for each number n it should display ‘n is divisible by 2’, ‘n is
divisible by 3’, ‘n is divisible by 2 AND 3’ or ‘n is NOT divisible by 2 or 3’. Use a for loop,
the function mod or rem to figure out if a number is divisible by 2 or 3, and num2str to
convert each number to a string for displaying. You can use any combination of if, else,
and elseif.
% loopTest(N)
%
% loops through the values 1 to N and for each number,
displays whether the
% number is divisible by 2, 3, both 2 and 3, or neither
function loopTest(N)
% loop through the numbers
for n=1:N
if ~rem(n,2) % if divisible by 2
if ~rem(n,3) % if also divisible by 3
disp([num2str(n) ' is divisible by 2 and 3'])
else % divisible by 2 but not 3
disp([num2str(n) ' is divisible by 2'])
end
elseif ~rem(n,3) % if divisible by 3 but not 2
disp([num2str(n) ' is divisible by 3']);
else % not divisible by either
disp([num2str(n) ' is NOT divisible by 2 or 3']);
end
end
7. and 10. The rectFilt.m code below contains all the functionality required for
problem 7, as well as
the optional problem 10. By reading through the if/else statements, you can figure out
which parts are
required for question 7 only.
% y= rectFilt(x,width)
%
% filters data with a rectangular filter (moving average),
and fixes edge
% effects
%
% inputs
% x - a vector of data
% width - the width of the desired rectangle in samples,
must be an ODD
integer.
%
% outputs
% y - the filtered version of x
%
% Y= rectFilt(X,width)
% X can be an Nx2 matrix, where the first column are the x
values and the
% second column are the y values (for nonuniformly sampled
data). in this
% case, width needs to be in the units of the x values and
does not need to
% be an integer or odd. Y will also be Nx2 where the first
column is again
the
% x values and the second column is the smoothed y values
function x= rectFilt(x,width)
% don't do anything if x is a scalar
if length(x)>1
% if x is a vector, just filter it with a rectangle
if size(x,1)==1 || size(x,2)==1
% if not odd, then display warning
if rem(width+1,2)
% width must be odd, so make it odd
side=floor(width/2);
width=(side*2)+1;
disp(['Width should be odd, using ' num2str(width) '
instead']);
else
side=floor(width/2); % calculate side for later
end
% convolve the mask with the signal
mask=1/width*ones(1,width);
x=conv(mask,x);
% get rid of extra values
if nargin==2
x=x(ceil(width/2):end-floor(width/2));
% fix edge effects
leftEdge=(side+1)/width:1/width:1;
rightEdge=1:-1/width:(side+1)/width;
end
Jan. 26, 2010 Homework 2 Solutions 6.094: Introduction to Matlab
8
% fix the orientation of these if necessary
if size(x,1)>size(x,2)
leftEdge=leftEdge';
rightEdge=rightEdge';
end
x(1:length(leftEdge))=x(1:length(leftEdge))./leftEdge;
x(end-length(rightEdge)+1:end)=x(endlength(
rightEdge)+1:end)./rightEdge;
else
% it's not uniformly sampled, so pull out the x and y
values and
% smooth accordingly. sortrows first to get all the x
values in
% increasing order
x=sortrows(x);
y=x(:,2);
x=x(:,1);
temp=zeros(size(y));
for n=1:length(temp)
% find the points that are within the width from the
current
% point
start=find(x>x(n)-width/2,1);
stop=find(x<x(n)+width/2,1,'last');
temp(n)=mean(y(start:stop));
end
% assign temp to x since x is what's returned
x=[x temp];
end
end
The script below runs the rectFilt.m program on the data in noisyData.mat and
plots the results.
% testRectFilt
% loads the noisy data and filters it using rectFilt, and
then plots the
% data and smooth curve
% load the data
load noisyData
% smooth it
smoothed=rectFilt(x,11);
% plot the data and smooth line
figure
plot(x,'.');
hold on
plot(smoothed,'r')
legend('Original Data','Smoothed')
xlabel('Index')
ylabel('Value')
title('Smoothing Illustration')
The figure of noisyData and the smoothed data generated by the script
8. The getCircle.m code is pasted below:
% [x,y]=getCircle(center,r)
%
% returns the x and y coordinates of a circle with its
center at center
% (2 element vector) and radius r
function [x,y]=getCircle(center,r)
% make the time vector and evaluate at sin and cos to get a
circle
t=linspace(0,2*pi,100);
x=center(1)+r*cos(t);
y=center(2)+r*sin(t);
11. Optional: Buy and sell a stock. Write the following function:
endValue=tradeStock(initialInvestment, price, buy, sell) The weekly price of
Google stock from 8/23/2004 until 1/11/2010 is saved in the file
googlePrices.mat. This file also contains two other vectors: peaks and lows. The
peaks vector contains indices into the price vector when the stock peaked, and
the lows vector contains indices into the price vector when the stock hit a low.
Run your program so that it buys stock when it’s low, and sell it when it’s high.
Below is a list of specifications.
% endValue=tradeStock(initialInvestment,price,buy,sell)
%
% calculates the total value of an investment in a
particular stock
% initialInvestment - dollar amount of initial cash
% price - a vector of prices as a function of time
% buy - a vector of indices at which the stock should be
bought
% sell - a vector of indices at which the stock should be
sold
%
% endValue - the value of the initial investment at the end
of the
% specified buys and sells
function
endValue=tradeStock(initialInvestment,price,buy,sell)
% this is the cost of each transaction
transactionCost=12.95;
% initially, all your money is cash, and you have 0 shares
cash=initialInvestment;
shares=0;
lastBuyPrice=0; % remember the price at which you last
bought it
% sort all the transaction days. put a 1 next to all the
buys and a -1 next
% to all the sells
transactionDays=[[buy(:) ones(length(buy),1)];[sell(:) -
1*ones(length(sell),1)]];
transactionDays=sortrows(transactionDays);
% now all the transaction days are sorted so we can go
through them
for n=1:size(transactionDays,1)
% see what day it is
day=transactionDays(n,1);
% get if it's a buy or sell day
kindOfTransaction=transactionDays(n,2);
% get the current price
currentPrice=price(day);
% if it's a buy day, then buy as much as you can,
accounting for the
% transaction cost
if kindOfTransaction==1
numToBuy=floor((cash-transactionCost)/currentPrice);
if numToBuy>0 % only buy if you can buy some
% buy them
cash=cash-numToBuy*currentPrice-transactionCost;
shares=shares+numToBuy;
% remember the price you paid
lastBuyPrice=currentPrice;
end
else % it's a sell day
if shares>0 % only sell if you have shares to sell
% profit is the money you get by selling minus the money
you