Вы находитесь на странице: 1из 18

Introduction to Programming with

MATLAB
by Vanderbilt University

Exercises:
-------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------
Taxi fare
Write a function called taxi_fare that computes the fare of a taxi ride. It takes two inputs: the
distance in kilometers (d) and the amount of wait time in minutes (t). The fare is calculated like this:

 the first km is $5

 every additional km is $2

 and every minute of waiting is $0.25.


Once a km is started, it counts as a whole (Hint: consider the ceil built-in function). The same rule
applies to wait times. You can assume that d >0 and t >= 0 but they are not necessarily integers.
The function returns the fare in dollars. For example, a 3.5-km ride with 2.25 minutes of wait costs
$11.75. Note that loops and if-statements are neither necessary nor allowed.

Solution:

function fare = taxi_fare (d,t)

m = ceil(d)
n = ceil(t)
fare= 5+( m-1)*2 + n*0.25
end
--------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------------------------
function isvalid = valid_date(y, m, d)
% Check if the inputs are valid
% Check that they are scalars
if ~(isscalar(y) && isscalar(m) && isscalar(d))
isvalid = false;
% Check that inputs are positive
elseif ~all([y, m, d] > 0)
isvalid = false;
% Check that inputs are integers (not the data type)
elseif any(rem([y, m, d], 1))
isvalid = false;
% Check that m and d are below the max possible
elseif (m > 12) || (d > 31)
isvalid = false;
% The inputs could be a valid date, let's see if they actually are
else
% Vector of the number of days for each month
daysInMonth = [31 28 31 30 31 30 31 31 30 31 30 31];
% If leap year, change days in Feb
if isequal(rem(y, 4), 0) && (~isequal(rem(y, 100), 0) || isequal(rem(y,
400), 0))
daysInMonth(2) = 29;
end
maxDay = daysInMonth(m);
if d > maxDay
isvalid = false;
else
isvalid = true;
end

end
end

----------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
function [summa, ind] = max_sum(v,n)
% If n is greater than v return the specified values
% Using return keyword exits the function so no further code is
% evaluated
if n > length(v)
summa = 0;
ind = -1;
return;
end

% Initialize summa to -inf.


% Then work through the vector, checking if each sum is larger than the
% current value of summa

summa = -inf;
ind = -1;
% Once we get to length(v)-n+1 we stop moving through the vector
for ii = 1:length(v)-n+1
currentV = v(ii:(ii+n-1));
currentSumma = sum(currentV);
% If currentSumma greater than summa, update summa and ind
if currentSumma > summa
summa = currentSumma;
ind = ii;
end
end
end

------------------------------------------------------------------------------------------------------------------------------------------
function txt = caesar(txt,key)
txt = double(txt) + key;
first = double(' ');
last = double('~');
% use mod to shift the characters - notice the + 1
% this is a common error and results in shifts
% being off by 1
txt = char(mod(txt - first,last - first + 1) + first);
end

------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------

function charnum=char_counter(fname,character)
fid=fopen(fname,'rt');
if fid<0 || ~ischar(character) %checks if the file is valid and if it is a
visible character or not using OR operator
charnum=-1;
return;
end
x=fscanf(fid,'%c'); %fscanf scans the entire file and stores it in a column
vector x
charnum=length(find(x==character)); %find() finds all the characters that are
required and stores the indices in a vector. The length of this vector gives the
number of characters
end
---------------------------------------------------------------------------------------------------------------------------------------
function in=saddle(M)
[m,n]=size(M); %%SIZE CALCULATED
in=[]; %%'in' IS INITIALIZED AS AN EMPTY MATRIX
for ii=1:m
for jj=1:n
if (M(ii,jj)==max(M(ii,:))&& M(ii,jj)==min(M(:,jj)))
in=[in; ii,jj]; %%INDICES CALCULATION AND STORING TO 'in'
end
end
end

indices=in; %%FINAL INDICES AS OUTPUT ARGUMENT


end

Solution guide 1:
function s = saddle(M)
[r, c] = size(M);
% Initialize the saddle points to an empty array
s = [];
% Check the dimensions to see if input is a row or column vector
if r > 1
cols = min(M); % find the min value in each column if more than 1
row
else
cols = M; % vector is a special case, min would give a
single value
end
if c > 1
rows = max(M'); % find the max value in each row
else
rows = M; % vector is a special case, max would give a
single value
end
for ii = 1:c % visit each column
for jj = 1:r % and each row, that is, each element of M
if M(jj,ii) == cols(ii) && M(jj,ii) == rows(jj) % if both conditions
hold
s = [s; jj ii]; % saddle point! Let's
add it!
end
end
end

solution guide 2:
function s = saddle(M)
% Create logical vector that are true for each saddle condition separately
minLocs = M <= min(M, [], 1);
maxLocs = M >= max(M, [], 2);
% Find the indices where both conditions are true!
[row, col] = find(minLocs & maxLocs);
% If the input is a row vector, row and col returned from the find
% function need to be transposed to fit the output format
if isrow(M)
s = [row', col'];
else
s = [row, col];
end
end
---------------------------------------------------------------------------------
Write a function called blur that blurs the input image. The function is to be called like this:
output = blur(img,w);
where img, the input image is a two-dimensional matrix of grayscale pixel values between 0 and
255. Blurring is to be carried out by averaging the pixel values in the vicinity of every pixel.
Specifically, the output pixel value is the mean of the pixels in a square submatrix of size 2w+1
where the given pixel sits in the center. For example, if w is 1, then we use a 3x3 matrix, that is, we
average all the neighboring pixels of the given pixel and itself. Only use valid pixels when portions of
the blurring matrix fall outside the image. For example, the blurred value corresponding to w = 1 at
index (1,1) would be the mean of of elements (1,1), (1, 2), (2,1) and (2, 2). Both input img and output
output are of type uint8.
You can download the test image here

function out = blur(img,w)


% convert to double for doing calculations
imgD = double(img);
[row, col] = size(img);
out = zeros(row, col);
for ii = 1:row
for jj = 1:col
% Get the indices for a submatrix
r1 = ii-w;
r2 = ii+w;
c1 = jj-w;
c2 = jj+w;
% Test that indices are valid
% If not, set to min/max that is valid
if r1 < 1
r1 = 1;
end
if r2 > row
r2 = row;
end
if c1 < 1
c1 = 1;
end
if c2 > col
c2 = col;
end
% Get the submatrix and assign the mean to the output pixel
m = imgD(r1:r2, c1:c2);
out(ii,jj) = mean(m(:));
end
end
% convert back to uint8
out = uint8(out);
end

solution guide:
function out = blur(img,w)
% convert to double for doing calculations
imgD = double(img);
[row, col] = size(img);
out = zeros(row, col);
for ii = 1:row
for jj = 1:col
% Get the indices for a submatrix
r1 = ii-w;
r2 = ii+w;
c1 = jj-w;
c2 = jj+w;
% Test that indices are valid
% If not, set to min/max that is valid
if r1 < 1
r1 = 1;
end
if r2 > row
r2 = row;
end
if c1 < 1
c1 = 1;
end
if c2 > col
c2 = col;
end
% Get the submatrix and assign the mean to the output pixel
m = imgD(r1:r2, c1:c2);
out(ii,jj) = mean(m(:));
end
end
% convert back to uint8
out = uint8(out);
end
-----------------------------------------------------------------------------------------------------------------------------
ECHO GENERATOR
I have to write a function called echo_gen that adds an echo effect to an audio recording. The
function is to be called like this:
output = echo_gen(input, fs, delay, amp);
where input is a column vector with values between -1 and 1 representing a time series of digitized
sound data. The input argument fs is the sampling rate. The sampling rate specifies how many
samples we have in the data each second. For example, an audio CD uses 44,100 samples per
second. The input argument delay represent the delay of the echo in seconds. That is, the echo
should start after delay seconds have passed from the start of the audio signal. Finally, amp
specifies the amplification of the echo which normally should be a value less than 1, since the echo
is typically not as loud as the original signal.
The output of the function is a column vector containing the original sound with the echo
superimposed. The output vector will be longer than the input vector if the delay is not zero (round to
the nearest number of points needed to get the delay, as opposed to floor or ceil). A sound recording
has values between -1 and 1, so if the echo causes some values to be outside of this range, you will
need to normalize the entire vector, so that all values adhere to this requirement.

Valid code 1:
function output = echo_gen(s, Fs, delay, amp)
% Find the time between points using Fs
dt = 1/Fs;
% Calculate the number of points for the given delay
N = round(delay/dt);
% Pad the original signal with zeros to make room for the echo
s1 = [s; zeros(N, 1)];
% Create an echo signal that starts with 0's
s2 = [zeros(N, 1); s.*amp];
% Add the echo to the original signal
output = s1 + s2;
% the abs of all values must be < 1. Rescale if necessary
if max(abs(output)) > 1
output = output./max(abs(output));
end
% Note: This only works with column vectors - can you make the
% function more robust so that it works with column or row vectors?
end

valid code 2:
function output = echo_gen(in,fs,delay,gain)
samples = round(fs*delay) ;
ds = floor(samples);
signal = zeros(length(in)+ds,1);
signal(1:length(in))=in;
echo_signal =zeros(length(in)+ds,1);
echo_signal(ds+(1:length(in*gain)))=in*gain;
output= signal + echo_signal;
p= max(abs(output));
if p>1
output=output ./ p;
else
output = output;
end
end

solution guide:
function output = echo_gen(s, Fs, delay, amp)
% Find the time between points using Fs
dt = 1/Fs;
% Calculate the number of points for the given delay
N = round(delay/dt);
% Pad the original signal with zeros to make room for the echo
s1 = [s; zeros(N, 1)];
% Create an echo signal that starts with 0's
s2 = [zeros(N, 1); s.*amp];
% Add the echo to the original signal
output = s1 + s2;
% the abs of all values must be < 1. Rescale if necessary
if max(abs(output)) > 1
output = output./max(abs(output));
end

% Note: This only works with column vectors - can you make the
% function more robust so that it works with column or row vectors?
end

Вам также может понравиться