diff --git a/.gitignore b/.gitignore index 2c353b4..94ae568 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,4 @@ *.vrb __* pointprocesses/lecture/pointprocessscetch*.tex - +*.DS_Store diff --git a/programming/exercises/boolean_logical_indexing.tex b/programming/exercises/boolean_logical_indexing.tex index c7a22dd..fa75aef 100644 --- a/programming/exercises/boolean_logical_indexing.tex +++ b/programming/exercises/boolean_logical_indexing.tex @@ -18,8 +18,8 @@ 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). +following pattern: ``boolean\_logical\_indexing\_\{lastname\}.m'' +(e.g. boolean\_logical\_indexing\_mueller.m). \section{Boolean expressions} diff --git a/programming/exercises/control_flow.tex b/programming/exercises/control_flow.tex index f6d8de7..29ba300 100644 --- a/programming/exercises/control_flow.tex +++ b/programming/exercises/control_flow.tex @@ -18,13 +18,13 @@ 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). +following pattern: ``control\_flow\_\{lastname\}.m'' +(e.g. control\_flow\_mueller.m). \begin{questions} - \question Implement \code{for} loops in which the \emph{running variable}: + \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. + \part ... assumes values from 0 to 10. Display (\code{disp}) the value of the running variable for each iteration of the loop. \begin{solution} for i = 1:10 disp(i); end; \end{solution} @@ -229,7 +229,7 @@ following pattern: ``variables\_datatypes\_\{lastname\}.m'' \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. + \part Use a \verb+for+ loop to find the positions of the underscores and store these positions in a vector. \begin{solution} \begin{verbatim} positions = []; diff --git a/programming/exercises/matrices.tex b/programming/exercises/matrices.tex index 3825486..79b5b4c 100644 --- a/programming/exercises/matrices.tex +++ b/programming/exercises/matrices.tex @@ -31,11 +31,11 @@ following pattern: \begin{solution} \code{x = [7 3 5; 1 8 3; 8 6 4];\\disp(size(x))} \end{solution} - \part Use the help to figure out how to get only the size along a certain dimension. Display the sizes of each dimension. + \part Use the help to figure out how to get only the size along a certain dimension. Display the sizes of each dimension separately. \begin{solution} \code{disp(size(x, 1))}\\\code{disp(size(x, 2))} \end{solution} - \part Copy the content at the position 3rd line, 2nd column to a new variable. + \part Copy the content at the position 3rd line, 2nd column into a new variable. \begin{solution} \code{c = x(3, 2)} \end{solution} @@ -86,7 +86,7 @@ following pattern: \code{y = M(:, [2:2:size(M,2)])} \end{solution} - \part Calculate the averages of lines 1, 3, and 5 (use the function \verb+mean+}, see help). + \part Calculate the averages of lines 1, 3, and 5 (use the function \verb+mean+, see help). \begin{solution} \code{mean(M([1 3 5],:), 2)} \end{solution} diff --git a/programming/exercises/plotsinewave.m b/programming/exercises/plotsinewave.m index f2960da..25667a3 100644 --- a/programming/exercises/plotsinewave.m +++ b/programming/exercises/plotsinewave.m @@ -2,12 +2,12 @@ function plotsinewave(time, sine) % plot precomputed sinewave % time: vector with timepoints % sine: corresponding vector with sinewave -if time(end)-time(1) <= 1.0 - plot(1000.0*time, sine); +if time(end) - time(1) <= 1.0 + plot(1000.0 * time, sine); xlabel('Time [ms]'); else plot(time, sine); xlabel('Time [s]'); end -ylim([1.2*min(sine) 1.2*max(sine)]); +ylim([1.2 * min(sine) 1.2 * max(sine)]); ylabel('Sinewave'); diff --git a/programming/exercises/scripts_functions.tex b/programming/exercises/scripts_functions.tex index d02c5c9..f5fbf50 100644 --- a/programming/exercises/scripts_functions.tex +++ b/programming/exercises/scripts_functions.tex @@ -26,7 +26,7 @@ to the pattern: ``scripts\_functions\_\{surname\}.zip''. \begin{parts} \part{} Version 1: Write a script that calculates the factorial of 5 and - prints out the result. + displays the result on the command line. \begin{solution} \lstinputlisting{factorialscripta.m} \end{solution} @@ -41,8 +41,8 @@ to the pattern: ``scripts\_functions\_\{surname\}.zip''. \part{} Version 3: like version 2, but the calculated result should not be - printed on the command line but returned by the function. Write a - script that calls the function and prints out the result. + displayed on the command line but returned by the function. Write a + script that calls the function, accepts the returned value and then displays the result. \begin{solution} \lstinputlisting{myfactorial.m} \lstinputlisting{factorialscriptc.m} @@ -71,7 +71,7 @@ to the pattern: ``scripts\_functions\_\{surname\}.zip''. \part{} Write a script that calls the function and controls the - plotting. Change the function in a way that it returns a proper + plotting. Change the function in a way that it returns time-axis and the calculated sinwave. \begin{solution} \lstinputlisting{sinewave.m} @@ -103,10 +103,11 @@ to the pattern: ``scripts\_functions\_\{surname\}.zip''. \begin{parts} \part{} - Read the exercise completely before starting the implementation - and then come up with a proper program layout of scripts and - functions. What would be a suitable function to solve the task? Which - arguments should it take? Which results should it return? + Read the exercise instructions completely before you start + implementing a solution. Analyze the requirements and then come up with a + program layout of scripts and functions. What would be a + suitable function to solve the core task? Which arguments should it + take? Which results should it return? \begin{solution} One function that computes one realisation of a random walk. Scripts for plotting and analysis. diff --git a/programming/lecture/programming-chapter.tex b/programming/lecture/programming-chapter.tex index 2a76f64..941c688 100644 --- a/programming/lecture/programming-chapter.tex +++ b/programming/lecture/programming-chapter.tex @@ -19,7 +19,7 @@ \section{TODO} \begin{itemize} \item Ausgabeformat: \varcode{format} ? -\item Expliziter die \varcode{(a:b:c)} Notation einf\"uhren! +\item Expliziter die \varcode{(a:b:c)} Notation einf\"uhren! Done! \item Mathematische Funktionen sin(), cos(), exp() \item Rundungsfunktionen round(), floor(), ceil() \item Zeitvektoren, deltat, Umrechnung Zeit und Index. diff --git a/programming/lecture/programming.tex b/programming/lecture/programming.tex index b657d6b..b75cc0d 100644 --- a/programming/lecture/programming.tex +++ b/programming/lecture/programming.tex @@ -174,11 +174,12 @@ As mentioned above, the data type associated with a variable defines how the sto part. \item \enterm{logical}: Boolean values that can be evaluated to \code{true} or \code{false}. -\item \enterm{character}: ASCII characters. +\item \enterm{character}: Unicode characters. +\item \enterm{string}: Strings of unicode characters, i.e. text. \end{itemize} There is a variety of numeric data types that require different amounts of memory and have different ranges of values that can be -represented (table~\ref{dtypestab}). +represented (table~\ref{dtypestab}). There are also more advanced data types which will not be used in this chapter but see box~\ref{box:advanced_dtypes} and box about strings \ref{box:strings}. \begin{table}[t] \centering @@ -360,8 +361,8 @@ number of elements irrespective of the type of vector. Listings~\ref{vectorelementslisting} and~\ref{vectorrangelisting} show how the index is used to access elements of a vector. One can access individual values by providing a single index or use the -\code[Operator!Matrix!:]{:} notation to access multiple values with a -single command. +\code[Operator!Matrix!:]{:} operator to access multiple values with a +single command (see also the info box below \ref{important:colon_operator}). \begin{pagelisting}[label=vectorelementslisting, caption={Access to individual elements of a vector.}] >> a = (11:20) % generate a vector @@ -401,13 +402,14 @@ ans = \end{exercise} \begin{important}[The : (colon) operator] - The colon \code[Operator!colon@:]{:} operator is often used when working with vectors. It has multiple purposes.\vspace{-1ex} + \label{important:colon_operator} + The colon \code[Operator!colon@:]{:} operator is often used when working with vectors. It has multiple purposes. \begin{enumerate} - \item In the simplest form, \code{x = a:b} with \code{a} and \code{b} being two numbers, it generates - a vector \code{x} containing the numbers \code{a} to \code{b} inclusively in integer steps. - \item In the form \code{x = a:c:b} the vector \code{x} uses a \emph{stepsize} of \code{c} to generate the range of numbers. - \item As vectors are often used for indexing in other vectors one use the colon operator to create such vectors implicitely, e.g. \varcode{x(1:2:end)} to access every seond element of \code{x}. - \item Indexing with a single colon, e.g. \code{x(:)}, returns all elements of the vector \code{x} as a row vector. + \item In the simplest form, \code{x = a:b} with \code{a} and \code{b} being two numbers, it creates + a vector \code{x} containing the numbers \code{a} to \code{b} in integer steps. In \matlab{} the borders $a$ and $b$ are included $[a, b]$ or $a\leq x \leq b$. + \item In the form \code{x = a:c:b} the vector \code{x} uses a \emph{stepsize} of \code{c} to create the range of numbers ranging from $a$ to $b$ in steps of $c$. + \item When used in the context of indexing such as \code{x(:)} all elements of the vector x are accessed. + \item Vectors are often used for indexing in other vectors. To do so the colon operator is used to create such vectors implicitely, e.g. \varcode{x(1:2:end)} to access every second element of \code{x}. \end{enumerate} \end{important} @@ -1148,7 +1150,7 @@ segment of data of a certain time span (the stimulus was on, \end{itemize}\vspace{-1ex} \end{exercise} -\begin{ibox}[ht]{\label{advancedtypesbox}Advanced data types} +\begin{ibox}[!ht]{\label{advancedtypesbox}Advanced data types} Thoughout this script and the exercises we will limit ourselves to the basic data types introduced above (int, double, char, scalars, vectors, matrices and strings). There are, however, \matlab{}- @@ -1204,6 +1206,50 @@ ans = \end{ibox} +\begin{ibox}[!ht]{\label{box:string_dtype}The \enterm[string]{string} data type} + With release 2017a \matlab{} introduced the string data type which offers more convenience for handling text. A string scalar is created using double quotes: \varcode{s = "Hello world!";}. + The string object \varcode{s} now offers several methods to work on the stored information. Some of the most commonly used methods are listed below. Refer to the documentation for complete descriptions. + \begin{enumerate} + \item \varcode{append} -- appends another string to the string and returns the new string. As with the other functions the original is not affected.\vspace{-0.5em} + \item \varcode{contains} -- searches the string for the occurence of a another string, which is passed as an argument. Returns a logical that is true if the pattern was found.\vspace{-0.5em} + \item \varcode{split} -- splits the string into substrings. By default a blank is used as delimiter. You can pass any other string as an argument to spilt the string at each occurence of the passed pattern. Returns a vector of substrings.\vspace{-0.5em} + \item \varcode{join} -- The opposite of spilt. \varcode{join} takes a vector of strings and concatenates them to a single string. By default a blank is used as delimiter.\vspace{-0.5em} + \item \varcode{lower} -- returns a version of the string in which all characters are lower case. This is particularly useful when one compares user input or string arguments in a function in an case insensitive way.\vspace{-0.5em} + \item \varcode{upper} -- as above but all characters are converted to upper case. + \end{enumerate} + \paragraph{Example:} + A dataset is recorded on a specific recording date using an experimental subject and applying certain stimulus conditions. The recorded data should be stored in a file that contains this information separated by undersores. + + \begin{lstlisting}[basicstyle=\ttfamily\scriptsize, caption={Using \varcode{join} to combine strings.}, label=usingjoin] +date = "2020-12-24"; +subject = "subjectA"; +condition = "control"; +file_extension = ".dat"; + +filename = join([date, subject, condition], "_"); +filename = filename.append(file_extension) + +disp(filename) + +ans = + "2020-12-24_subjectA_control.dat" + \end{lstlisting} + + When reading the dataset during the analysis, we may want to extract the stimulus condtion or the subject name. + + \begin{lstlisting}[basicstyle=\ttfamily\scriptsize, caption={Using \varcode{split} to cut a string at a delimiter.}, label=usingsplit] +disp(filename) +ans = + "2020-12-24_subjectA_control.dat" + +filename = filename.erase(".dat"); % remove file extension +string_parts = filename.split("_"); % split at the underscore +% string_parts is a vector of the substrings +date = string_parts(1); +subject = string_parts(2); +condition = string_parts(3); + \end{lstlisting} +\end{ibox} \section{Control flow}\label{controlstructsec} Generally, a program is executed line by line from top to @@ -1696,6 +1742,36 @@ function plotFunction(x_data, y_data, name) end \end{pagelisting} +\begin{ibox}[!ht]{\label{box:sprintf}\enterm[Format strings]{Formatted strings} with \mcode{sprintf}.} + We can use \varcode{disp} to dispaly the content of a variable on the command line. But how can we embed variable contents nicely into a text and store it in a variable or show it on the command line? \varcode{sprintf} is the standard function to achieve this. We introduce only a fraction of its real might here. For a more complete description visit the \matlab{} help or e.g. \url{https://en.wikipedia.org/wiki/Printf_format_string}. + + Consider the following code: + \begin{lstlisting}[commentstyle=\color{black}, basicstyle=\ttfamily\scriptsize, caption={Using sprintf.}] +n = 100; +numbers = randn(n, 1); + +sprintf("Drawing %i random numbers yields an average of %.3f and a standard deviation of %.3f.", n, mean(numbers), std(numbers)) + +ans = + "Drawing 100 random numbers yields an average of -0.121 and a standard deviation of 0.921." + + \end{lstlisting} + \varcode{sprintf} takes a variable number of arguments. The first one is the string that contains placehoders for the variable content. Here we used three placehoders (two different types, \varcode{\%i, \%.2f}). Accordingly, \varcode{sprintf} expects three additional arguments (\varcode{n, mean(numbers), std(numbers)}). These are the content we want to show in the text. The function will try to convert the variable content and format is according to the placehoder type: + + \footnotesize + \begin{tabular}{l||p{4cm}|p{7.5cm}} + type & purpose & example \\ \hline \hline + \%i & integer values & \varcode{sprintf("I drew \%i numbers", 100)}\\ \hline + \%s & string values & \varcode{name = "John Doe";} \varcode{sprintf("My name is \%s", name)}\\ \hline + \%f & double values, accepts width and precision arguments & \varcode{sprintf("Number pi is \%.2f", pi)}\\ \hline + \%g & double values, uses exponential style when appropriate& \varcode{sprintf("Large int \%g", 1000000)} + \end{tabular} + \normalsize + + Simplified, the placehoder has the form \varcode{\%[width][.precision]type}. Square brackets indicates optional parameters. \varcode{width} controls the total number of characters used for the content. \varcode{.precision} controls how many of the total characters may de devoted to the positions after the decimal point. The example above (\varcode{\%.2f}) limits the output of the $\pi$ to 2 positions after the decimal point. + + Many programming languages offer versions of \varcode{sprintf} that work essentially in the same way. +\end{ibox} \paragraph{III. One script to rule them all} @@ -1721,7 +1797,7 @@ Again, we need to specify what needs to be done: The implementation is shown in listing~\ref{sinesskriptlisting}. -\begin{pagelisting}[caption={Control script for the plotting of sine waves.},label=sinesskriptlisting] +\begin{pagelisting}[caption={Control script for the plotting of sine waves. Note the use of \varcode{sprintf} in the function call in line 11. This function creates a so called formatted string based on the passed string which contains placeholders for variables. For some more details see~\ref{box:sprintf}.},label=sinesskriptlisting] amplitudes = 0.25:0.25:1.25; frequency = 2.0; duration = 10.0; % seconds @@ -1732,7 +1808,7 @@ hold on for i = 1:length(amplitudes) [x_data, y_data] = sinewave(frequency, amplitudes(i), ... duration, stepsize); - plotFunction(x_data, y_data, sprintf('freq: %5.2f, ampl: %5.2f',... + plotFunction(x_data, y_data, sprintf("freq: %5.2f, ampl: %5.2f",... frequency, amplitudes(i))) end hold off