|
|
|
@ -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
|
|
|
|
|