\documentclass[12pt,a4paper,pdftex]{exam} \newcommand{\exercisetopic}{Control flow} \newcommand{\exercisenum}{5} \newcommand{\exercisedate}{24. November, 2020} \input{../../exercisesheader} \firstpagefooter{Dr. Jan Grewe}{}{jan.grewe@uni-tuebingen.de} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} \input{../../exercisestitle} The exercises are meant for self-monitoring and revision of the lecture. You should try to solve them on your own. Your solution should be submitted as a single script (m-file) in the Ilias system. Each task should be solved in its own ``cell''. Each cell must be executable on its own. The file should be named according to the following pattern: ``variables\_datatypes\_\{lastname\}.m'' (e.g. variables\_datentypes\_mueller.m). \begin{questions} \question Implement \code{for} loops in which the \emph{running variable}: \begin{parts} \part ... assumes values from 0 to 10. Print (\code{disp}) the value of the running variable for each iteration step. \begin{solution} for i = 1:10 disp(i); end; \end{solution} \part ... assumes values from 10 to 0. Print out the value for each iteration. \part ... assumes values from 0 to 1 in steps of 0.1. Print out the value for each iteration. \end{parts} \question Indexing in vectors: \begin{parts} \part Define a vector \code{x} that contains values ranging from 101 to 200 in steps of 1. \part Use a \code{for} loop to print each element of \code{x}. Use the running variable for indexing. \begin{solution} \code{for i = 1:length(x); disp(x(i)); end} \end{solution} \part Do the same without using the running variable directly (not for indexing). \begin{solution} \code{for i : x; disp(i); end;} \end{solution} \end{parts} \question Create a vector \verb+x+ that contains 50 random numbers in the value range 0 --- 10. \begin{parts} \part Use a loop to calculate the arithmetic mean. The mean is defined as: $\overline{x}=\frac{1}{n}\sum\limits_{i=0}^{n}x_i $. \begin{solution} \begin{verbatim} x = rand(50, 1) .* 10; total = 0; for i = 1:length(x) total = total + x(i); end average = total / length(x); disp(average) \end{verbatim} \end{solution} \part Use a loop to estimate the standard deviation: $\sigma=\sqrt{\frac{1}{n}\sum\limits_{i=0}^{n}(x_i-\overline{x})^2}$. \begin{solution} \begin{verbatim} x = rand(50, 1) .* 10; total = 0; for i = 1:length(x) total = total + x(i); end average = total / length(x); deviation = 0 for i = 1:length(x) deviation = deviation + (x(i) - average)^2$; end standarddeviation = sqrt(deviation/length(x)); \end{verbatim} \end{solution} \part Search the MATLAB help for functions that do these calculations for you :-). \begin{solution} \verb+sqrt+ and \verb+mean+ do the job for you. \end{solution} \end{parts} \question Implement a \code{while} loop that iterates ... \begin{parts} \part ... 100 times and displays the current iteration number. \begin{solution} \begin{verbatim} max_iterations = 100; iteration_count = 0; while iteration_count < max_iterations disp(iteration_count); iteration_count = iteration_count + 1; end \end{verbatim} \end{solution} \part ... iterates endlessly. You can interrupt the execution with the command \code{Strg + C}. \begin{solution} \begin{verbatim} while true disp('i am still running'); end \end{verbatim} \end{solution} \end{parts} \question Use an endless \code{while} loop to individually display the elements of a vector that contains 10 elements. Stop the execution after all elements have been displayed on the command line. \begin{solution} \begin{verbatim} x = rand(10, 1); index = 0; while true disp(x(index); if index >= length(x) break; end index = index + 1; end \end{verbatim} \end{solution} \question Use the endless \verb+while+ loop to draw random numbers (\verb+randn+) until you hit one that is larger than 1.33. \begin{parts} \part Count the number of required iterations. \begin{solution} \begin{verbatim} count = 1; threshold = 1.33; while true x = randn(1); if x > threshold break; end count = count + 1; end \end{verbatim} \end{solution} \part Use a \code{for} loop to run the previous test 1000 times. Store all counts and calculate the mean of it. \begin{solution} \begin{verbatim} trials = 1000; threshold = 1.33; counts = zeros(trials, 1); for i = 1:trials while true x = randn(1); counts(i) = counts(i) + 1; if x > threshold break end end end \end{verbatim} \end{solution} \part Create a plot that shows for each of the 1000 trials, how often you had to draw. \begin{solution} \begin{verbatim} plot(counts) hold on plot([0, trials], [mean(counts), mean(counts)]) xlabel('trials') ylabel('number of samples') \end{verbatim} \end{solution} \part Play around with the threshold. What happens? \begin{solution} When lowering the threshold, the average number of counts is reduced, when increasing it, the counts increase! \end{solution} \end{parts} \question Create a vector \verb+x+ that contains 10 random numbers in the range 0:10. \begin{parts} \part Use a \code{for} loop to delete all those elements (\code{x(index) = [];}) that are less than 5. \begin{solution} \begin{verbatim} x = rand(10, 1) .* 10; for i = length(x):-1:1 if x(i) < 5 x(i) = []; end end \end{verbatim} \end{solution} \part Delete all elements that are less than 5 and greater than 2. \begin{solution} \begin{verbatim} x = rand(10, 1) .* 10; for i = length(x):-1:1 if x(i) < 5 & x(i) < 2 x(i) = []; end end \end{verbatim} \end{solution} \part Can you do the same without a loop? \begin{solution} \verb+x((x < 5) & (x > 2))) = [];+ \end{solution} \end{parts} \question Test the random number generator! To do so count the number of elements that fall into the classes defined by the edges [0.0, 0.2, 0.4, 0.6, 0.8, 1.0]. Store the results in a vector. Use a loop to draw 1000 random numbers with \verb+rand()+ (see help). What would be the expectation? What is the result? \begin{solution} We expect each catergory to contain the same amount of data points. \begin{verbatim} edges = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0]; counts = zeros(length(edges)-1, 1); trials = 1000; for i = 1:trials x = rand(1); for j = 2:length(edges) % using a nested for loop we can avoid a complicated if elseif construct if x > edges(j-1) & x < edges(j) counts(j-1) = counts(j-1) + 1; end end end \end{verbatim} \end{solution} \question String parsing: It is quite common to use the names of datasets to encode the conditions under which they were recorded. To find out the required information we have to \emph{parse} the name. \begin{parts} \part Create a variable \verb+filename = '2015-10-12_100Hz_1.25V.dat'+. Obviously, the underscore was used as a delimiter. \part Use a \verb+for+ loop to find the positions of the underscores and store these in a vector. \begin{solution} \begin{verbatim} positions = []; for i = 1:length(filename) if filename(i) == '_' positions(end + 1) = i end end \end{verbatim} \end{solution} \part Use a second loop to iterate over the previously filled `position' vector and use this information to cut \verb+filename+ appropriately and display the individual parts. \begin{solution} Tricky thing here, we need to catch the corner cases! \begin{verbatim} for i = 1:length(positions) if i == 1 disp(filename(1:positions(i))) elseif i == length(positions) disp(filename(positions(i-1):end)) else disp(filename(positions(i-1):positions(i))) end end \end{verbatim} \end{solution} \end{parts} \end{questions} \end{document}