[programming] lots of tiny fixes

This commit is contained in:
Jan Grewe 2018-10-14 17:53:22 +02:00
parent 6497a7e171
commit 8a5abf5f73
5 changed files with 106 additions and 80 deletions

View File

@ -2,7 +2,7 @@
We may count the ability of adequately presenting scientific data to
the core competences needed to do science. We need to present data in
a meaningful way that fosters understanding of the data and the
a meaningful way that supports understanding of the data and the
results.
\begin{figure}[hb!]

View File

@ -1,22 +1,41 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Programming in \matlab}\label{programming}
In this chapter we will cover the basics of programming in
\matlab{}. Starting with the concept of simple variables and data
types, we introduce basic data structures, such as vecotrs and
matrices and show how one can work with them. Then we will address the
structures used to control the flow of the program and how to write
scripts and functions. Only a few of the concepts discussed in this
chapter are really \matlab{}-specific. Despite a few language-specific
details the same structures are found in most other programming
languages. Switching to another language (e.g. Python) is rather
simple.
\section{Variables and data types}
The ultimate goals of scientific computing is to analyze gathered
data, correlate it with e.g. stimulus conditions and infer rules and
dependencies. These may be used to constrain model that allow us to
understand and predict a system's behavior. In order to work with data
we need to store it somehow. For this purpose we use \emph{variables}
that allow us to store the data and give it a name for easy recognition
and to provide semantic meaning.
\subsection{Variables}
A \enterm{variable} is a pointer to a certain address in the
Technically speaking, a \enterm{variable} is a pointer to a certain address in the
computer's memory. This pointer is characterized by it's name and the
\enterm{data type} (figure~\ref{variablefig}). In the computer's
memory the value of the variable is stored in binary form, that is, as
a sequence of zeros and ones (\enterm[Bit]{Bits}). When the variable
is read from the memory, this binary pattern is interpreted according
to the data type. The example shown in figure~\ref{variablefig} shows
that the very same bit pattern is either interpreted as an 8-bit
a sequence of zeros and ones (\enterm[bit]{bits}). When the variable
is read from memory, this binary pattern is interpreted according
to the data type. \Figref{variablefig} shows
that the very same binary pattern is either interpreted as an 8-bit
integer type (numeric value 38) or as the ampersand (\&) character. In
\matlab{} data types are of only minor importance but there are
occasions in which it becomes important to know the type of a variable.
occasions in which it becomes important to know the data type of a
variable.
\begin{figure}
\centering
@ -28,7 +47,7 @@ occasions in which it becomes important to know the type of a variable.
\includegraphics[width=.8\textwidth]{variableB}
\label{variable:b}
\end{subfigure}
\titlecaption{Variables.}{Variables point to a memory
\titlecaption{Variables} point to a memory
address. They further are described by their name and
data type. The variable's value is stored as a pattern of binary
values (0 or 1). When reading the variable this pattern is
@ -40,7 +59,7 @@ occasions in which it becomes important to know the type of a variable.
\subsection{Creating variables}
In \matlab{} variables can be created at any time on the command line
or any place in a script or function. Listing~\ref{varListing1} shows
three different possibilities:
three different ways of creating a variable:
\begin{lstlisting}[label=varListing1, caption={Creating variables.}]
>> x = 38
x =
@ -63,7 +82,7 @@ variables will have the \codeterm{double} (a numeric data type, see
below) data type. In line 9, however, we create a variable \varcode{z}
and assign the character ``A'' to it. Accordingly, \varcode{z} does
not have the numeric \codeterm{double} data type but is of the type
\codeterm{character}.
\codeterm{character}. \textbf{Note:} \matlab{} uses single quotes for characters or strings of characters.
There are two ways to find out the actual data type of a variable: the
\code{class()} and the \code{whos} functions. While \code{class()}
@ -137,7 +156,7 @@ z =
Note: in lines 2 and 10 the variables have been used without changing
their values. Whenever the value of a variable should change, the
\code[Operator!Assignment!=]{=} operator has to be used (lines 14 and
\code[Operator!Assignment!=]{=} operator must be used (lines 14 and
18). Line 23, finally shows how to delete a variable.
\subsection{Data types}
@ -177,15 +196,15 @@ represented (table~\ref{dtypestab}).
\end{table}
By default \matlab{} uses the \codeterm{double} data type whenever
numerical values have to be stored. Nevertheless there are use-cases
numerical values are stored. Nevertheless, there are use-cases
in which different data types are better suited. Box~\ref{daqbox}
exemplifies such a case.
exemplifies one of such cases.
\begin{ibox}[t]{\label{daqbox}Digitizing measurements}
Scenario: The electric activity (e.g. the membrane potential) of a
nerve cell is recorded. The measurements are digitized and stored on
the hard disk of a computer for later analysis. This is done using a
Data Acquisition system (DAQ) that converts the analog measurements
Data Acquisition (DAQ) system that converts the analog measurements
into computer digestible digital format. Typically these systems
have a working range of $\pm 10$\,V. This range is usually resolved
with a precision of 16 bit. This means that the full potential range
@ -230,7 +249,8 @@ dimension).
In contrast to variables that store just a single value
(\enterm{scalar}) a vector can store multiple values of the same data
type (figure~\ref{vectorfig}). The variable \varcode{a} for example stores four integer values.
type (figure~\ref{vectorfig} B). The variable \varcode{test} in
\figref{vectorfig} for example stores four integer values.
\begin{figure}[ht]
\includegraphics[width=0.8\columnwidth]{scalarArray}
@ -379,7 +399,7 @@ ans =
could you find out the size of the \varcode{a} in the 2nd dimension?
\end{exercise}
\subsubsection{Operations with vectors}
\subsubsection{Operations on vectors}
Similarly to the scalar variables discussed above we can work with
vectors and do calculations. Listing~\ref{vectorscalarlisting} shows
@ -389,7 +409,7 @@ how vectors and scalars can be combined with the operators \code[Operator!arithm
\code[Operator!arithmetic!4div@/]{/}
\code[Operator!arithmetic!5powe@.\^{}]{.\^}.
\begin{lstlisting}[caption={Cancluating with vectors and scalars.},label=vectorscalarlisting]
\begin{lstlisting}[caption={Calculating with vectors and scalars.},label=vectorscalarlisting]
>> a = (0:2:8)
a =
0 2 4 6 8
@ -415,7 +435,7 @@ ans =
0 4 16 36 64
\end{lstlisting}
When calculating with scalars and vectors the same mathematical
When doing calculations with scalars and vectors the same mathematical
operation is done to each element of the vector. In case of, e.g. an
addition this is called an element-wise addition.
@ -447,8 +467,8 @@ Error using +
Matrix dimensions must agree.
\end{lstlisting}
Element-wise multiplication and division and exponentiation requires a
different operator with preceding '.'. \matlab{} defines the
Element-wise multiplication and division to raise a vector to a given power requires a
different operator with a preceding '.'. \matlab{} defines the
following operators for element-wise operations on vectors
\code[Operator!arithmetic!3mule@.*]{.*},
\code[Operator!arithmetic!4dive@./]{./} and
@ -554,10 +574,10 @@ Dimensions of matrices being concatenated are not consistent.
>> a(1:3) = [5 6 7] % assign new values to elements of the vector
a =
5 6 7 1
>> a(1:3) = [1 2 3 4]; % range of elements and number of new values must match
>> a(1:3) = [1 2 3 4]; % range of indices and list of new values must match
In an assignment A(I) = B, the number of elements in B and I must be the same.
>> a(3:6) = [1 2 3 4] % extending a vector by assigning beyond its bounds
>> a(3:6) = [1 2 3 4] % extending by assigning beyond vector bounds
a =
5 6 1 2 3 4
\end{lstlisting}
@ -568,7 +588,7 @@ a =
Vectors are a special case of the more general data structure,
i.e. the matrix. Vectors are matrices in which one dimension is a
singleton dimension (length of 1). While matrices can have an almost
arbitrary number of dimensions the most common matrices are 2-3
arbitrary number of dimensions the most common matrices are two- to three
dimensional (figure~\ref{matrixfig} A, B).
\begin{figure}
@ -578,8 +598,8 @@ dimensional (figure~\ref{matrixfig} A, B).
matrix. Arrows indicate the rank across the dimensions.}\label{matrixfig}
\end{figure}
Matrices can be created similarly to vectors
(listing~\ref{matrixlisting}). The definition of a matrix is enclosed
Matrices can be created in similar ways as the vectors
(listing~\ref{matrixlisting}). The definition of a 2-D matrix is enclosed
into the square braces \code[Operator!Matrix!{[]}]{[]} the semicolon
operator \code[Operator!Matrix!;]{;} separates the individual rows of
a matrix.
@ -610,7 +630,7 @@ matrix). The function \code{cat()} allows to concatenate n-dimensional
matrices.
To request the length of a vector we used the function
\code{length()}. This function is no longer suited to request
\code{length()}. This function is \tetbf{not} suited to request
information about the size of a matrix. As mentioned above,
\code{length()} would return the length of the largest dimension. The
function \code{size()} however, returns the length in each dimension
@ -625,16 +645,15 @@ and should be always preferred over \code{length()}.
etc. }\label{matrixindexingfig}
\end{figure}
Analogous to the element access in vectors we can address individual
Analogous to the data access in vectors we can address individual
elements of a matrix by it's index. Similar to a coordinate system
each element is addressed using a n-tuple whit n the number of
each element is addressed using a n-tuple with $n$ the number of
dimensions (figure~\ref{matrixindexingfig},
listing~\ref{matrixIndexing}). This type of indexing is called
\codeterm{subscript indexing}. The first coordinate refers always to
the row, the second to the column, the third to the page, and so on.
\begin{lstlisting}[caption={Indexing in matrices,
Indizierung.}, label=matrixIndexing]
\begin{lstlisting}[caption={Accessing elements in matrices, indexing.}, label=matrixIndexing]
>> x=rand(3, 4) % 2-D matrix filled with random numbers
x =
0.8147 0.9134 0.2785 0.9649
@ -662,14 +681,17 @@ ans =
\end{lstlisting}
Subscript indexing is very intuitive but offers not always the most
straight-forward solution to the problem. Consider for example that
you have a 3-D matrix and you want the minimal number in that
matrix. An alternative way is the so called \emph{linar indexing} in
which each element of the matrix is addressed by a single number. The
linear index thus ranges from 1 to \code{numel(matrix)}. The linear
index increases first along the 1st, 2nd, 3rd etc. dimension
(figure~\ref{matrixlinearindexingfig}). It is not as intuitive but can
be really helpful (listing~\ref{matrixLinearIndexing}).
straight-forward or efficient solution to the problem. Consider for
example that you have a 3-D matrix and you want the minimal number in
that matrix. One could try to first find the minimum in each column,
then compare it to the elements on each page, and so on. An
alternative way is to make use of the so called \emph{linar indexing}
in which each element of the matrix is addressed by a single
number. The linear index thus ranges from 1 to
\code{numel(matrix)}. The linear index increases first along the 1st,
2nd, 3rd etc. dimension (figure~\ref{matrixlinearindexingfig}). It is
not as intuitive since one would need to know the shape of the matrix and perform a remapping, but can be really helpful
(listing~\ref{matrixLinearIndexing}).
\begin{figure}
@ -699,6 +721,8 @@ ans =
4
\end{lstlisting}
\matlab{} defines functions that convert subscript indices to linear indices and back (\code{sub2ind()} and \code{ind2sub()}).
\begin{ibox}[tp]{\label{matrixmultiplication} The matrix--multiplication.}
The matrix--multiplication from linear algebra is \textbf{not} an
element--wise multiplication of each element in a matrix \varcode{A}
@ -707,12 +731,13 @@ ans =
matrix--multiplication is one of the most common mistakes in
\matlab{}. \linebreak
The matrix--multiplication is only possible if the number of columns
in the first matrix agrees with the number of rows in the other. More
formal: $\mathbf{A}$ and $\mathbf{B}$ can be multiplied $(\mathbf{A}
\cdot \mathbf{B})$, if $\mathbf{A}$ has the size $(m \times n)$ and
$\mathbf{B}$ the size $(n \times k)$. The multiplication is possible
if the \enterm{inner dimensions} $n$ agree.
The matrix--multiplication of two 2-D matrices is only possible if
the number of columns in the first matrix agrees with the number of
rows in the other. More formal: $\mathbf{A}$ and $\mathbf{B}$ can be
multiplied $(\mathbf{A} \cdot \mathbf{B})$, if $\mathbf{A}$ has the
size $(m \times n)$ and $\mathbf{B}$ the size $(n \times k)$. The
multiplication is possible if the \enterm{inner matrix dimensions} $n$
agree.
Then, the elements $c_{i,j}$ of the product $\mathbf{C} = \mathbf{A}
\cdot \mathbf{B}$ are given as the scalar product (dot-product) of
@ -738,11 +763,11 @@ ans =
= \begin{pmatrix} -5 & 12 \\ -13 & 30 \\ -4 & 11\end{pmatrix} \; . \]
The product of $\mathbf{B} \cdot \mathbf{A}$, however, is not
defined since the inner dimensions do not agree ($(2 \times 2) \cdot
defined since the inner matrix dimensions do not agree ($(2 \times 2) \cdot
(3 \times 2)$).
\end{ibox}
Calculations on matrices apply the same rules as the calculations with
Calculations on matrices apply the same rules as the calculations on
vectors. Element-wise computations are possible as long as the
matrices have the same dimensionality. It is again important to
distinguish between the element-wise
@ -751,7 +776,7 @@ distinguish between the element-wise
matrix-multiplication (\code[Operator!arithmetic!3mul@*]{*},
listing~\ref{matrixOperations} lines 14, 17 and 21,
box~\ref{matrixmultiplication}). To do a matrix-multiplication the
inner dimensions of the matrices have to agree
inner dimensions of the matrices must agree
(box~\ref{matrixmultiplication}).
\pagebreak[4]
@ -788,7 +813,7 @@ ans =
Boolean expressions are instructions that can be evaluated to
\varcode{true} or \varcode{false}. In the context of programming they
are used to test the relations between entities, i.e. are entities the
same, greater or less than? Accordingly, programming languages defines
same, greater or less than? Accordingly, programming languages define
operators for such instructions. The following \codeterm{relational
operators} are defined: (\code[Operator!relational!>]{>},
\code[Operator!relational!<]{<}, \code[Operator!relational!==]{==},
@ -797,11 +822,11 @@ and not. Using so called \codeterm[Operator!logical]{logical
operators} allows to join single Boolean expressions to more complex
constructs (\code[Operator!logical!and1@\&]{\&},
\code[Operator!logical!or1@{"|} {}]{|}, AND, OR). These expressions
are important e.g. to control which parts of the code should be
evaluated under a certain condition (conditional statements,
Section~\ref{controlstructsec}) but also for accessing only certain
elements of a vector or matrix (logical indexing,
Section~\ref{logicalindexingsec}).
are important e.g. to control which parts of the code are evaluated
under certain conditions (conditional statements,
Section~\ref{controlstructsec}) but also for accessing only those
elements of a vector or matrix that match a certain condition (logical
indexing, Section~\ref{logicalindexingsec}).
Truth tables (\ref{logicalandor}) are used to visualize the results of
Boolean expressions. A and B are statements that can be evaluated to
@ -816,21 +841,21 @@ the statements but not both are True. There is no operator for XOR in
\titlecaption{Truth tables for logical AND, OR and XOR.}{}\label{logicalandor}
\begin{tabular}{llll}
\multicolumn{2}{l}{\multirow{2}{*}{}} & \multicolumn{2}{c}{\textbf{B}} \\
& \sffamily{\textbf{und}} & \multicolumn{1}{|c}{true} & false \\ \cline{2-4}
& \sffamily{\textbf{AND}} & \multicolumn{1}{|c}{true} & false \\ \cline{2-4}
\multirow{2}{*}{\textbf{A}} & \multicolumn{1}{l|}{true} & \multicolumn{1}{c}{\textcolor{mygreen}{true}} & \textcolor{red}{false} \erb \\
& \multicolumn{1}{l|}{false} & \multicolumn{1}{l}{\textcolor{red}{false}} & \textcolor{red}{false}
\end{tabular}
\hfill
\begin{tabular}{llll}
\multicolumn{2}{l}{\multirow{2}{*}{}} & \multicolumn{2}{c}{\textbf{B}} \\
& \sffamily{\textbf{oder}} & \multicolumn{1}{|c}{true} & false \\ \cline{2-4}
& \sffamily{\textbf{OR}} & \multicolumn{1}{|c}{true} & false \\ \cline{2-4}
\multirow{2}{*}{\textbf{A}} & \multicolumn{1}{l|}{true} & \multicolumn{1}{c}{\textcolor{mygreen}{true}} & \textcolor{mygreen}{true} \erb \\
& \multicolumn{1}{l|}{false} & \multicolumn{1}{l}{\textcolor{mygreen}{true}} & \textcolor{red}{false}
\end{tabular}
\hfill
\begin{tabular}{llll}
\multicolumn{2}{l}{\multirow{2}{*}{}} & \multicolumn{2}{c}{\textbf{B}} \\
& \sffamily{\textbf{xor}} & \multicolumn{1}{|c}{true} & false \\ \cline{2-4}
& \sffamily{\textbf{XOR}} & \multicolumn{1}{|c}{true} & false \\ \cline{2-4}
\multirow{2}{*}{\textbf{A}} & \multicolumn{1}{l|}{true} & \multicolumn{1}{c}{\textcolor{red}{false}} & \textcolor{mygreen}{true} \erb \\
& \multicolumn{1}{l|}{false} & \multicolumn{1}{l}{\textcolor{mygreen}{true}} & \textcolor{red}{false}
\end{tabular}
@ -848,7 +873,7 @@ cannot become true. For example assume that the two statements A and B
are joined using a AND. The whole expression can only be true if A is
already true. This means, that there is no need to evaluate B if A is
false. Since the statements may be arbitrarily elaborated computations
this saves processing time.
this can save processing time.
\begin{table}[t]
\titlecaption{\label{logicalrelationaloperators}
@ -928,15 +953,16 @@ ans = 1 0 1 1 0
\section{Logical indexing}\label{logicalindexingsec}
We have introduced how one can select elements of a vector or matrix
by using their index. This is fine when we know the indices. There
are, however, many situations in which a selection is based on the
value of the stored elements and the indices are not known. Such
selections are one of the major places where we need Boolean
expressions. The selection based on the result of a Boolean expression
is called \enterm{logical indexing}. With this approach we can easily
filter based on the values stored in a vector or matrix. It is very
powerful and, once understood, very intuitive.
With subscript or linear indexing one can select elements of a vector
or matrix by using their index. This is fine when we know the
indices. There are, however, many situations in which a selection is
based on the value of the stored elements and the indices are not
known in advance. Such selections are one of the major situations in
which Boolean expressions are employed. The selection based on the
result of a Boolean expression is called \enterm{logical
indexing}. With this approach we can easily filter based on the
values stored in a vector or matrix. It is very powerful and, once
understood, very intuitive.
The basic concept is that applying a Boolean operation on a vector
results in a \code{logical} vector of the same size (see
@ -1022,7 +1048,7 @@ segment of data of a certain time span (the stimulus was on,
\textbf{Structures} Arrays of named fields that each can contain
arbitrary data types. \codeterm{Structures} can have sub-structures
and thus can build a trees. Structures are often used to combine
data and mtadata in a single variable.
data and metadata in a single variable.
\textbf{Cell arrays} Arrays of variables that contain different
types. Unlike structures, the entries of a \codeterm{Cell array} are
@ -1067,8 +1093,8 @@ ans =
\section{Control flow}\label{controlstructsec}
Generally, a program is executed line by line from top to
bottom. Sometimes this behavior is not wanted, or the other way round,
it is needed to skip certain parts or execute others
bottom. Sometimes this is not the desired behavior, or the other way
round, it is needed to skip certain parts or execute others
repeatedly. High-level programming languages like \matlab{} offer
statements that allow to manipulate the control flow. There are two
major classes of such statements:
@ -1080,10 +1106,10 @@ major classes of such statements:
\subsection{Loops}
As the name already suggests loops are used to execute the same parts
of the code repeatedly. In one of the earlier exercises the faculty of
of the code repeatedly. In one of the earlier exercises the factorial of
five has been calculated as depicted in listing~\ref{facultylisting}.
\begin{lstlisting}[caption={Calculation of the faculty of 5 in five steps}, label=facultylisting]
\begin{lstlisting}[caption={Calculation of the factorial of 5 in five steps}, label=facultylisting]
>> x = 1;
>> x = x * 2;
>> x = x * 3;
@ -1104,7 +1130,7 @@ a matter of taste but there are severe drawbacks to this style:
example above). \shortquote{Copy and paste is a design error.}{David
Parnas}
\item Flexibility: The aforementioned program does exactly one thing,
it cannot be used for any other other purpose (such as the faculty
it cannot be used for any other other purpose (such as the factorial
of 6) without a change.
\item Maintenance: If there is an error, it has to be fixed in all
repetitions. It is easy to forget a single change.
@ -1143,9 +1169,9 @@ purpose. The \code{for} loop is closed with the keyword
\end{lstlisting}
\begin{exercise}{facultyLoop.m}{facultyLoop.out}
Can we solve the faculty with a for-loop? Implement a for loop that
calculates the faculty of a number \varcode{n}.
\begin{exercise}{factorialLoop.m}{factorialLoop.out}
Can we solve the factorial with a for-loop? Implement a for loop that
calculates the factorial of a number \varcode{n}.
\end{exercise}
@ -1166,8 +1192,8 @@ while x == true % head with a Boolean expression
end
\end{lstlisting}
\begin{exercise}{facultyWhileLoop.m}{}
Implement the faculty of a number \varcode{n} using a \code{while}
\begin{exercise}{factorialWhileLoop.m}{}
Implement the factorial of a number \varcode{n} using a \code{while}
-- loop.
\end{exercise}
@ -1425,7 +1451,7 @@ calculates and displays a bunch of sine waves with different amplitudes.
\begin{lstlisting}[caption={Bad example of a function that displays a series of sine waves.},label=badsinewavelisting]
function meineFirstFunction() % function head
function myFirstFunction() % function head
t = (0:0.01:2);
frequency = 1.0;
amplitudes = [0.25 0.5 0.75 1.0 1.25];