diff --git a/programming/exercises/control_flow.tex b/programming/exercises/control_flow.tex index 99984f2..2dd88fd 100644 --- a/programming/exercises/control_flow.tex +++ b/programming/exercises/control_flow.tex @@ -1,4 +1,4 @@ -\documentclass[12pt,a4paper,pdftex]{exam} +\documentclass[12pt,a4paper,pdftex, answers]{exam} \usepackage[german]{babel} \usepackage{natbib} @@ -58,7 +58,7 @@ following pattern: ``variables\_datatypes\_\{lastname\}.m'' \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 the indexing. + \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} @@ -68,38 +68,161 @@ following pattern: ``variables\_datatypes\_\{lastname\}.m'' \end{solution} \end{parts} - \question Create a vector \verb+x+ that contains 50 random numbers in the value range 0 - 10. + \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}$). - \part Search the MATLAB help for functions that do the calculations for you :-). + $\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 + \question Implement a \code{while} loop that iterates ... \begin{parts} - \part ... that iterates 100 times. Print out the current iteration number. + \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 smaller than 5. - \part Delete all elements that are smaller than 5 and larger than 2. - \part Can you do the same without a loop? + (\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 @@ -107,6 +230,22 @@ following pattern: ``variables\_datatypes\_\{lastname\}.m'' [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} @@ -114,9 +253,32 @@ following pattern: ``variables\_datatypes\_\{lastname\}.m'' \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. - \part Print out the individual parts. + 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}