Merge branch 'master' of whale.am28.uni-tuebingen.de:scientificComputing
This commit is contained in:
commit
6c210a8901
@ -22,6 +22,9 @@
|
||||
plots haben, die wir machen!
|
||||
\item subplot
|
||||
\item Uebersicht zu wichtigen plot Befehlen (plot, scatter, bar, step, ...)
|
||||
\item Funktionenplotten (siehe auch Design patterns) und untersampleter Sinus
|
||||
\item Verschiedene Stile fuer Achsenbeschriftung (gross/kleinschreibungen, Kalmmertyp fuer Einheiten), stay with one style!
|
||||
\item Stay with a coherent style (font type/style/size, colors schemes, line styles/thickness, point styles)
|
||||
\end{itemize}
|
||||
|
||||
\end{document}
|
||||
|
@ -198,7 +198,7 @@ voneinander ausf\"uhrbar sein. Das Skript sollte nach dem Muster:
|
||||
\part Einer dritte Variable \code{c} soll der Wert \code{a+1e-16}
|
||||
zugewiesen werden. Was ist das Ergebnis von \code{c-a} ? Warum?
|
||||
\begin{solution}
|
||||
Das Ergebnis ist 0! Auch die doble Werte haben nur eine endliche
|
||||
Das Ergebnis ist 0! Auch die double Werte haben nur eine endliche
|
||||
P\"azision in den Nachkommastellen.
|
||||
\end{solution}
|
||||
\part Berechne \verb=(2^52 + 1) - 2^52= sowie
|
||||
|
@ -29,6 +29,10 @@
|
||||
\item Doppelte for-Schleife
|
||||
\item File output and input (load, save, fprintf, scanf) (extra chapter?)
|
||||
\item help() und doc()
|
||||
\item A box about sampling of contiunous data.
|
||||
\item A box about foo and bar?
|
||||
\item function arguments, order does matter, names do as well.
|
||||
\item function return values. order does not matter, names do
|
||||
\end{itemize}
|
||||
|
||||
\end{document}
|
||||
|
@ -15,7 +15,7 @@ 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 a 8-bit integer type (numeric value 38) or as a
|
||||
ampersand (&) character. In \matlab{} data types are of only minor
|
||||
ampersand (\&) character. In \matlab{} data types are of only minor
|
||||
importance but there are occasions where it becomes important to know
|
||||
the type of a variable and we will come back to them later on.
|
||||
|
||||
@ -261,7 +261,7 @@ c =
|
||||
The length of a vector, that is the number of elements, can be
|
||||
requested using the \code{length()} or \code{numel()}
|
||||
functions. \code{size()} provides the same information in a slightly,
|
||||
yet more powerful way (listing~\ref{vectorsizelisting}). The above
|
||||
yet more powerful way (listing~\ref{vectorsizeslisting}). The above
|
||||
used vector \varcode{a} has the following size:
|
||||
|
||||
\begin{lstlisting}[label=vectorsizeslisting, caption={Size of a vector.}]
|
||||
@ -937,9 +937,10 @@ The basic concept is that applying a Boolean operation on a vector
|
||||
results in a \code{logical} vector of the same size (see
|
||||
listing~\ref{booleanexpressions}. This logical vector is then used to
|
||||
select only those values for which the logical vector is true. Line 14
|
||||
in listing~\ref{logicalindexing} can be read: ``Give me all those
|
||||
in listing~\ref{logicalindexing1} can be read: ``Select all those
|
||||
elements of \varcode{x} where the Boolean expression \varcode{x < 0}
|
||||
evaluates to true''.
|
||||
evaluates to true and store the result in the variable
|
||||
\emph{x\_smaller\_zero}''.
|
||||
|
||||
\begin{lstlisting}[caption={Logical indexing.}, label=logicalindexing1]
|
||||
>> x = randn(1, 6) % a vector with 6 random numbers
|
||||
@ -1019,7 +1020,9 @@ major classes of such statements:
|
||||
\end{enumerate}
|
||||
|
||||
\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 five has been calculated as depicted in listing~\ref{facultylisting}.
|
||||
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
|
||||
five has been calculated as depicted in listing~\ref{facultylisting}.
|
||||
|
||||
\begin{lstlisting}[caption={Calculation of the faculty of 5 in five steps}, label=facultylisting]
|
||||
>> x = 1;
|
||||
@ -1089,115 +1092,112 @@ purpose. The \code{for} loop is closed with the keyword
|
||||
|
||||
\subsubsection{The \varcode{while} --- loop}
|
||||
|
||||
Eine weiterer Schleifentyp, der weniger h\"aufig eingesetzt wird, ist
|
||||
die \code{while}-Schleife. Auch sie hat ihre Entsprechungen in fast
|
||||
allen Programmiersprachen. \"Ahnlich zur \code{for} Schleife wird
|
||||
auch hier der in der Schleife definierte Programmcode iterativ
|
||||
ausgef\"uhrt. Der Schleifenkopf beginnt mit dem Schl\"usselwort
|
||||
\code{while} gefolgt von einem booleschen Ausdruck. Solange dieser zu
|
||||
\code{true} ausgewertet werden kann, wird der Code im
|
||||
Schleifenk\"orper ausgef\"uhrt. Die Schleife wird mit dem
|
||||
Schl\"usselwort \code{end} beendet.
|
||||
|
||||
|
||||
\begin{lstlisting}[caption={Grundstruktur einer \varcode{while} Schleife.}, label=whileloop]
|
||||
while x == true
|
||||
% fuehre diesen sinnvollen Code aus ...
|
||||
The \code{while}--loop is the second type of loop that is available in
|
||||
almost all programming languages. Other, than the \code{for} -- loop,
|
||||
that iterates with the running variable over a vector, the while loop
|
||||
uses a Boolean expression to determine when to execute the code in
|
||||
it's body. The head of the loop starts with the keyword \code{while}
|
||||
that is followed by a Boolean expression. If this can be evaluated to
|
||||
true, the code in the body is executed. The loop is closed with an
|
||||
\code{end}.
|
||||
|
||||
\begin{lstlisting}[caption={Basic structure of a \code{while} loop.}, label=whileloop]
|
||||
while x == true % head with a Boolean expression
|
||||
% execute this code if the expression yields true
|
||||
end
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{exercise}{facultyWhileLoop.m}{}
|
||||
Implementiere die Fakult\"at mit einer \code{while}-Schleife.
|
||||
Implement the faculty of a number \varcode{n} using a \code{while}
|
||||
-- loop.
|
||||
\end{exercise}
|
||||
|
||||
|
||||
\begin{exercise}{neverendingWhile.m}{}
|
||||
Implementiere eine \code{while}-Schleife, die unendlich
|
||||
l\"auft. Tipp: wenn der boolesche Ausdruck hinter dem \code{while}
|
||||
zu wahr ausgewertet wird, wird die Schleife weiter ausgef\"uhrt.
|
||||
Das Programm kann mit \keycode{Ctrl+C} abgebrochen werden.
|
||||
Implement a \code{while}--loop that is never-ending. Hint: the body
|
||||
is executed as long as the Boolean expression in the head is
|
||||
true. You can escape the loop by pressing \keycode{Ctrl+C}.
|
||||
\end{exercise}
|
||||
|
||||
|
||||
\subsubsection{Vergleich \varcode{for} -- und \varcode{while}--Schleife}
|
||||
\subsubsection{Comparison \varcode{for} -- and \varcode{while} -- loop}
|
||||
|
||||
\begin{itemize}
|
||||
\item Beide f\"uhren den Code im Schleifenk\"orper iterativ aus.
|
||||
\item Der K\"orper einer \code{for} Schleife wird mindestens 1 mal
|
||||
betreten (au{\ss}er wenn der Vektor im Schleifenkopf leer ist).
|
||||
\item Der K\"orper einer \code{while} Schleife wird nur dann betreten,
|
||||
wenn die Bedingung im Kopf \code{true} ist. \\$\rightarrow$ auch
|
||||
``Oben-abweisende'' Schleife genannt.
|
||||
\item Die \code{for} Schleife eignet sich f\"ur F\"alle in denen f\"ur
|
||||
jedes Element eines Vektors der Code ausgef\"uhrt werden soll.
|
||||
\item Die \code{while} Schleife ist immer dann gut, wenn nicht klar
|
||||
ist wie h\"aufig etwas ausgef\"uhrt werden soll. Sie ist
|
||||
speichereffizienter.
|
||||
\item Jedes Problem kann mit beiden Typen gel\"ost werden.
|
||||
\item Both execute the code in the body iterative.
|
||||
\item When using a \code{for} -- loop the body of the loop is executed
|
||||
at least once (except when the vector used in the head is empty).
|
||||
\item In a \code{while} -- loop, the body is not necessarily
|
||||
executed. It is entered only if the Boolean expression in the head
|
||||
yields true.
|
||||
\item The \code{for} -- loop is best suited for cases in which the
|
||||
elements of a vector have to be used for a computation or when the
|
||||
number of iterations is known.
|
||||
\item The \code{while} -- loop is best suited for cases when it is not
|
||||
known in advance how often a certain piece of code has to be
|
||||
executed.
|
||||
\item Any problem that can be solved with one type can also be solve
|
||||
with the other type of loop.
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\subsection{Bedingte Anweisungen und Verzweigungen}
|
||||
\subsection{Conditional expressions}
|
||||
|
||||
Bedingte Anweisungen und Verzweigungen sind Kontrollstrukturen, die
|
||||
regeln, dass der in ihnen eingeschlossene Programmcode nur unter
|
||||
bestimmten Bedingungen ausgef\"uhrt wird.
|
||||
The conditional expression are used to control that the enclosed code
|
||||
is only executed under a certain condition.
|
||||
|
||||
\subsubsection{Die \varcode{if} -- Anweisung}
|
||||
\subsubsection{The \varcode{if} -- statement}
|
||||
|
||||
Am h\"aufigsten genutzter Vertreter ist die \code{if} -
|
||||
Anweisung. Sie wird genutzt um Programmcode nur unter bestimmten
|
||||
Bedingungen auszuf\"uhren.
|
||||
The most prominent representative of the conditional expressions is
|
||||
the \code{it} statement (sometimes also called \code{if - else}
|
||||
statement). It constitutes a kind of branching point. It allows to
|
||||
control which code is executed.
|
||||
|
||||
Der Kopf der \code{if} - Anweisung beginnt mit dem Schl\"usselwort \code{if}
|
||||
welches von einem booleschen Ausdruck gefolgt wird. Wenn
|
||||
dieser zu \code{true} ausgewertet werden kann, wird der Code im
|
||||
K\"orper der Anweisung ausgef\"uhrt. Optional k\"onnen weitere
|
||||
Bedingungen mit dem Schl\"usselwort \code{elseif} folgen. Ebenfalls
|
||||
optional ist die Verwendung eines finalen \code{else} - Falls. Dieser
|
||||
wird immer dann ausgef\"uhrt wenn alle vorherigen Bedingungen nicht
|
||||
erf\"ullt wurden. Die \code{if} - Anweisung wird mit \code{end}
|
||||
beendet. Listing \ref{ifelselisting} zeigt den Aufbau einer
|
||||
\code{if} - Anweisung.
|
||||
Again, the statement consists of the head and the body. The head
|
||||
begins with the keyword \code{if} followed by a Boolean expression
|
||||
that controls whether or not the body is entered. Optionally the body
|
||||
can be either ended by the \code{end} keyword or followed by
|
||||
additional statements \code{elseif}, which allows to add another
|
||||
Boolean expression and to catch a certain condition or the \code{else}
|
||||
the provide a default case. The last body of the \code{if - elseif -
|
||||
else} statement has to be finished with the \code{end}
|
||||
(listing~\ref{ifelselisting}).
|
||||
|
||||
|
||||
\begin{lstlisting}[label=ifelselisting, caption={Grundger\"ust einer \varcode{if} Anweisung.}]
|
||||
if x < y
|
||||
% fuehre diesen code aus wenn x < y
|
||||
\begin{lstlisting}[label=ifelselisting, caption={Structure of an \code{if} statement.}]
|
||||
if x < y % head
|
||||
% body I, executed only if x < y
|
||||
elseif x > y
|
||||
% etwas anderes soll getan werden fuer x > y
|
||||
% body II, executed only if the first condition did not match and x > y
|
||||
else
|
||||
% wenn x == y, wieder etwas anderes
|
||||
% body III, executed only if the previous conditions did not match
|
||||
end
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{exercise}{ifelse.m}{}
|
||||
Ziehe eine Zufallszahl und \"uberpr\"ufe mit einer geeigneten \code{if} Anweisung, ob sie
|
||||
Draw a random number and check with an appropriate \code{if}
|
||||
statement whether it is
|
||||
\begin{enumerate}
|
||||
\item kleiner als 0.5 ist.
|
||||
\item kleiner oder gr\"o{\ss}er-gleich 0.5 ist.
|
||||
\item (i) kleiner als 0.5, (ii) gr\"o{\ss}er oder gleich 0.5 aber kleiner
|
||||
als 0.75 oder (iii) gr\"o{\ss}er oder gleich 0.75 ist.
|
||||
\item less than 0.5.
|
||||
\item less or greater-or-equal 0.5.
|
||||
\item (i) less than 0.5, (ii) greater-or-equal 0.5 but less than
|
||||
0.75 or (iii) greater-or-equal to 0.75.
|
||||
\end{enumerate}
|
||||
\end{exercise}
|
||||
|
||||
\subsubsection{Die \varcode{switch} -- Verzweigung}
|
||||
|
||||
Die \code{switch} Verzweigung wird eingesetzt wenn mehrere F\"alle
|
||||
auftreten k\"onnen, die einer unterschiedlichen Behandlung bed\"urfen.
|
||||
\subsubsection{The \varcode{switch} -- statement}
|
||||
|
||||
Sie wird mit dem Schl\"usselwort \code{switch} begonnen, gefolgt von der
|
||||
\codeterm{switch Anweisung} (Zahl oder String). Jeder Fall, auf den diese
|
||||
Anweisung \"uberpr\"uft werden soll, wird mit dem Schl\"usselwort
|
||||
\code{case} eingeleitet. Dieses wird gefolgt von der \codeterm{case
|
||||
Anweisung}, die definiert gegen welchen Fall auf
|
||||
Gleichheit getestet wird. F\"ur jeden Fall wird der
|
||||
Programmcode angegeben, der ausgef\"uhrt werden soll. Optional k\"onnen
|
||||
mit dem Schl\"usselwort \code{otherwise} alle nicht explizit genannten
|
||||
F\"alle behandelt werden. Die \code{switch} Anweisung wird mit
|
||||
\code{end} beendet (z.B. in Listing \ref{switchlisting}).
|
||||
The \code{switch} statement is used whenever a set of conditions
|
||||
requires separate treatment. The statement is initialized with the
|
||||
\code{switch} keyword that is followed by \emph{switch expression} (a
|
||||
number or string). It is followed by a set of \emph{case expressions}
|
||||
which start with the keyword \code{case} followed by the condition
|
||||
that defines against which the \emph{switch expression} is tested. It
|
||||
is important to note that the case expression always checks for
|
||||
equality! Optional the case expressions may be followed by the keyword
|
||||
\code{otherwise} which catches all cases that were not explicitly
|
||||
stated above (listing~\ref{switchlisting}).
|
||||
|
||||
|
||||
\begin{lstlisting}[label=switchlisting, caption={Grundger\"ust einer \varcode{switch} Anweisung.}]
|
||||
\begin{lstlisting}[label=switchlisting, caption={Structure of a \varcode{switch} statement.}]
|
||||
mynumber = input('Enter a number:');
|
||||
switch mynumber
|
||||
case -1
|
||||
@ -1209,31 +1209,29 @@ switch mynumber
|
||||
end
|
||||
\end{lstlisting}
|
||||
|
||||
Wichtig ist hier, dass in jedem \code{case} auf Gleichheit der
|
||||
switch-Anweisung und der case-Anweisung getestet wird.
|
||||
|
||||
|
||||
\subsubsection{Vergleich \varcode{if} -- Anweisung und \varcode{switch} -- Verzweigung}
|
||||
\subsubsection{Comparison \varcode{if} and \varcode{switch} -- statements}
|
||||
\begin{itemize}
|
||||
\item Mit der \code{if} Anweisung k\"onnen beliebige F\"alle
|
||||
unterschieden und entsprechender Code ausgef\"uhrt werden.
|
||||
\item Die \code{switch} Anweisung leistet \"ahnliches allerdings wird in
|
||||
jedem Fall auf Gleichheit getestet.
|
||||
\item Die \code{switch} Anweisung ist etwas kompakter, wenn viele F\"alle
|
||||
behandelt werden m\"ussen.
|
||||
\item Die \code{switch} Anweisung wird deutlich seltener benutzt und
|
||||
kann immer durch eine \code{if} Anweisung erstezt werden.
|
||||
\item Using the \code{if} statement one can test for arbitrary cases
|
||||
and treat them separately.
|
||||
\item The \code{switch} statement does something similar but is always
|
||||
checks for the equality of \emph{switch} and \emph{case}
|
||||
expressions.
|
||||
\item The \code{switch} is a little bit more compact and nicer to read
|
||||
if many different cases have to be handled.
|
||||
\item The \code{switch} is used less often and can always be replaced
|
||||
by an \code{if} statement.
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\subsection{Die Schl\"usselworte \code{break} und \code{continue}}
|
||||
\subsection{The keywords \code{break} and \code{continue}}
|
||||
|
||||
Soll die Ausf\"uhrung einer Schleife abgebrochen oder \"ubersprungen
|
||||
werden, werden die Schl\"usselworte \code{break} und
|
||||
\code{continue} eingesetzt (Listings \ref{continuelisting}
|
||||
und \ref{continuelisting} zeigen, wie sie eingesetzt werden k\"onnen).
|
||||
Whenever the execution of a loop should be ended or if you want to
|
||||
skip the execution of the body under certain circumstances, one can
|
||||
use the keywords \code{break} and \code{continue}
|
||||
(listings~\ref{continuelisting} and \ref{continuelisting}).
|
||||
|
||||
\begin{lstlisting}[caption={Abbrechen von Schleifen mit \varcode{break}.}, label=breaklisting]
|
||||
\begin{lstlisting}[caption={Stop the execution of a loop using \varcode{break}.}, label=breaklisting]
|
||||
>> x = 1;
|
||||
while true
|
||||
if (x > 3)
|
||||
@ -1248,7 +1246,7 @@ und \ref{continuelisting} zeigen, wie sie eingesetzt werden k\"onnen).
|
||||
3
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{lstlisting}[caption={\"Uberspringen von Code-Abschnitten in Schleifen mit \varcode{continue}.}, label=continuelisting]
|
||||
\begin{lstlisting}[caption={Skipping iterations using \varcode{continue}.}, label=continuelisting]
|
||||
for x = 1:5
|
||||
if(x > 2 & x < 5)
|
||||
continue;
|
||||
@ -1262,176 +1260,184 @@ end
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{exercise}{logicalIndexingBenchmark.m}{logicalIndexingBenchmark.out}
|
||||
Vergleich von logischem Indizieren und ``manueller'' Auswahl von
|
||||
Elementen aus einem Vektor. Es wurde oben behauptet, dass die
|
||||
Auswahl von Elementen mittels logischem Indizieren effizienter
|
||||
ist. Teste dies indem ein Vektor mit vielen (100000) Zufallszahlen
|
||||
erzeugt wird aus dem die Elemente gefiltert und gespeichert werden,
|
||||
die kleiner $0.5$ sind. Umgebe den Programmabschnitt mit den
|
||||
Br\"udern \code{tic} und \code{toc}. Auf diese Weise misst \matlab{}
|
||||
die zwischen \code{tic} und \code{toc} vergangene Zeit.
|
||||
Above we claimed the logical indexing is faster and much more
|
||||
convenient than the manual selection of elements of a vector. By now
|
||||
we have all the tools at hand to test this. \\
|
||||
For this test create a large vector with 100000 (or more) random
|
||||
numbers. Filter from this vector all numbers that are less than 0.5
|
||||
and copy them to a second vector. Surround you code with the brother
|
||||
\code{tic} and \code{toc} to have \matlab{} measure the time that
|
||||
has passed between the calls of \code{tic} and \code{toc}.
|
||||
|
||||
\begin{enumerate}
|
||||
\item Benutze eine \code{for} Schleife um die Elemente auszuw\"ahlen.
|
||||
\item Benutze logisches Indizieren.
|
||||
\item Use a \code{for} loop to select the matching values.
|
||||
\item Use logical indexing.
|
||||
\end{enumerate}
|
||||
\end{exercise}
|
||||
|
||||
\begin{exercise}{simplerandomwalk.m}{}
|
||||
Programmiere einen 1-D random walk. Ausgehend von der Startposition
|
||||
$0$ ``l\"auft'' ein Agent zuf\"allig in die eine oder andere
|
||||
Richtung.
|
||||
Implement a 1-D random walk: Starting from the initial position $0$
|
||||
the agent takes a step in a random direction.
|
||||
\begin{itemize}
|
||||
\item In dem Programm sollen 10 Realisationen eines random walk mit
|
||||
jeweils 1000 Schritten durchgef\"uhrt werden.
|
||||
\item Die Position des Objektes ver\"andert sich in jedem Schritt zuf\"allig um
|
||||
$+1$ oder $-1$.
|
||||
\item Merke Dir alle Positionen.
|
||||
\item Plotte die Positionen als Funktion der Schrittnummer.
|
||||
\item The program should do 10 random walks with 1000 steps each.
|
||||
\item With each step decide randomly whether the position is changed
|
||||
by $+1$ or $-1$.
|
||||
\item Store all positions.
|
||||
\item Create a figure in which you plot the position as a function
|
||||
of the steps.
|
||||
\end{itemize}
|
||||
\end{exercise}
|
||||
|
||||
\section{Skripte und Funktionen}
|
||||
\section{Scripts and functions}
|
||||
|
||||
\subsection{Was ist ein Programm?}
|
||||
\subsection{What is a program?}
|
||||
|
||||
Ein Programm ist eine Sammlung von Anweisungen, die in einer Datei auf
|
||||
dem Rechner abgelegt sind. Wenn es durch den Aufruf zum Leben erweckt
|
||||
wird, dann wird es Zeile f\"ur Zeile von oben nach unten ausgef\"uhrt.
|
||||
A program is little more than a collection of statement stored in a
|
||||
file on the computer. When it is \emph{called}, it is brought to life
|
||||
and executed line-by-line from top to bottom.
|
||||
|
||||
\matlab{} kennt drei Arten von Programmen:
|
||||
\matlab{} knows three types of programs:
|
||||
\begin{enumerate}
|
||||
\item \codeterm[Skript]{Skripte}
|
||||
\item \codeterm[Funktion]{Funktionen}
|
||||
\item \codeterm[Objekt]{Objekte} (werden wir hier nicht behandeln)
|
||||
\item \codeterm[Script]{Scripts}
|
||||
\item \codeterm[Function]{Functions}
|
||||
\item \codeterm[Object]{Objects} (not covered here)
|
||||
\end{enumerate}
|
||||
Alle Programme werden in den sogenannten \codeterm{m-files} gespeichert
|
||||
(z.B. \file{meinProgramm.m}). Um sie zu benutzen werden sie von der
|
||||
Kommandozeile aufgerufen oder in anderen Programmen
|
||||
verwendet. Programme erh\"ohen die Wiederverwertbarkeit von
|
||||
Programmcode. Bislang haben wir ausschlie{\ss}lich Skripte
|
||||
verwendet. Dabei wurde jede Variable, die erzeugt wurde im
|
||||
\codeterm{Workspace} abgelegt und konnte wiederverwendet werden. Hierin
|
||||
liegt allerdings auch eine Gefahr. In der Regel sind Datenanalysen auf
|
||||
mehrere Skripte verteilt und alle teilen sich den gemeinsamen
|
||||
Workspace. Verwendet nun ein aufgerufenes Skript eine bereits
|
||||
definierte Variable und weist ihr einen neuen Wert zu, dann kann das
|
||||
erw\"unscht und praktisch sein. Wenn es aber unbeabsichtigt passiert
|
||||
kann es zu Fehlern kommen, die nur sehr schwer erkennbar sind, da ja
|
||||
jedes Skript f\"ur sich enwandtfrei arbeitet. Eine L\"osung f\"ur
|
||||
dieses Problem bieten die \codeterm[Funktion]{Funktionen}.
|
||||
|
||||
\subsection{Funktionen}
|
||||
|
||||
Eine Funktion in \matlab{} wird \"ahnlich zu einer mathematischen
|
||||
Funktion definiert:
|
||||
\[ y = f(x) \]
|
||||
Die Funktion hat einen Namen $f$, sie \"uber das Argument $x$
|
||||
einen Input und liefert ein Ergebnis in $y$ zur\"uck. Listing
|
||||
\ref{functiondefinitionlisting} zeigt wie das in \matlab{} umgesetzt
|
||||
wird.
|
||||
|
||||
\begin{lstlisting}[caption={Funktionsdefinition in \matlab{}}, label=functiondefinitionlisting]
|
||||
|
||||
Programs are stored in so called \codeterm{m-files}
|
||||
(e.g. \file{myProgram.m}). To use them they have to be \emph{called}
|
||||
from the command line of within another program. Storing your code in
|
||||
programs increases the re-usability. So far we have used
|
||||
\emph{scripts} to store the solutions of the exercises. Any variable
|
||||
that was created appeared in the \codeterm{workspace} and existed even
|
||||
after the program was finished. This is very convenient but also bears
|
||||
some risks. Consider the case that \file{script\_a.m} creates a
|
||||
certain variable and assigns a value to it for later use. Now it calls
|
||||
a second program (\file{script\_b.m}) that, by accident, uses the same
|
||||
variable name and assigns a different value to it. When
|
||||
\file{script\_b.m} is done, the control returns to \file{script\_a.m}
|
||||
and if it now wants to read the previously stored variable, it will
|
||||
contain a different value than expected. Bugs like this are hard to
|
||||
find since each of the programs alone is perfectly fine and works as
|
||||
intended. A solution for this problem are the
|
||||
\codeterm[Function]{functions}.
|
||||
|
||||
\subsection{Functions}
|
||||
|
||||
Functions in \matlab{} are similar to mathematical functions
|
||||
\[ y = f(x) \] Here, the mathematical function has the name $f$ and it
|
||||
has one \codeterm{argument} $x$ that is transformed into the
|
||||
function's output value $y$. In \matlab{} the syntax of a function
|
||||
declaration is very similar (listing~\ref{functiondefinitionlisting}).
|
||||
|
||||
\begin{lstlisting}[caption={Declaration of a function in \matlab{}}, label=functiondefinitionlisting]
|
||||
function [y] = functionName(arg_1, arg_2)
|
||||
% ^ ^ ^
|
||||
% Rueckgabewert Argument_1, Argument_2
|
||||
% return value argument_1, argument_2
|
||||
\end{lstlisting}
|
||||
|
||||
Ein Funktion beginnt mit dem Schl\"usselwort \code{function} gefolgt
|
||||
von den R\"uckgabewerte(n), dem Funktionsnamen und (in Klammern) den
|
||||
Argumenten. Auf den Funktionskopf folgt der auszuf\"uhrende
|
||||
Programmcode im Funktionsk\"orper. Die Funktionsdefinition wird
|
||||
% optional %XXX es ist vielleicht optional, aber gute stil ware es immer hinzuschreiben, oder?
|
||||
mit einem \code{end} abgeschlossen. Jede Funktion, die vom
|
||||
Nutzer direkt verwendet werden soll, ist in einer eigenen Datei
|
||||
definiert. \"Uber die Definition/Benutzung von Funktionen wird folgendes erreicht:
|
||||
The keyword \code{function} is followed by the return value(s) (it can
|
||||
be a list \code{[]} of values), the function name and the
|
||||
argument(s). The function head is then followed by the function's
|
||||
body. A function is ended by and \code{end} (this is in fact optional
|
||||
but we will stick to this). Each function that should be directly used
|
||||
by the user (or called from other programs) should reside in an
|
||||
individual \code{m-file} that has the same name as the function. By
|
||||
using functions instead of scripts we gain several advantages:
|
||||
\begin{itemize}
|
||||
\item Kapseln von Programmcode, der f\"ur sich eine Aufgabe l\"ost.
|
||||
\item Definierte Schnittstelle.
|
||||
\item Eigener G\"ultigkeitsbereich:
|
||||
\item Encapsulation of program code that solves a certain task. It can
|
||||
be easily re-used in other programs.
|
||||
\item There is a clear definition of the function's interface. What
|
||||
does the function need (the arguments) and what does it return (the
|
||||
return values).
|
||||
\item Separated scope:
|
||||
\begin{itemize}
|
||||
\item Variablen im Workspace sind in der Funktion \emph{nicht} sichtbar.
|
||||
\item Variablen, die in der Funktion definiert werden erscheinen
|
||||
\emph{nicht} im Workspace.
|
||||
\item Variables that are defined within the function do not appear
|
||||
in the workspace and cannot cause any harm there.
|
||||
\item Variables that are defined in the workspace are not visible to
|
||||
the function.
|
||||
\end{itemize}
|
||||
\item Erh\"oht die Wiederverwendbarkeit von Programmcode.
|
||||
\item Erh\"oht die Lesbarkeit von Programmen, da sie
|
||||
\"ubersichtlicher werden.
|
||||
\item Functions increase re-usability.
|
||||
\item Increase the legibility of programs since they are more clearly
|
||||
arranged.
|
||||
\end{itemize}
|
||||
|
||||
Das Folgende Beispiel (Listing \ref{badsinewavelisting}) zeigt eine
|
||||
Funktion, die eine Reihe von Sinusschwingungen unterschiedlicher
|
||||
Frequenzen berechnet und graphisch darstellt.
|
||||
|
||||
\begin{lstlisting}[caption={Ein schlechtes Beispiel einer Funktion, die eine Reihe Sinusse plottet.},label=badsinewavelisting]
|
||||
function meineErsteFunktion() % Funktionskopf
|
||||
t = (0:0.01:2); % hier faengt der Funktionskoerper an
|
||||
frequenz = 1.0;
|
||||
amplituden = [0.25 0.5 0.75 1.0 1.25];
|
||||
for i = 1:length(amplituden)
|
||||
y = sin(frequenz * t * 2 * pi) * amplituden(i);
|
||||
The following listing (\ref{badsinewavelisting}) shows a function that
|
||||
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
|
||||
t = (0:0.01:2);
|
||||
frequency = 1.0;
|
||||
amplitudes = [0.25 0.5 0.75 1.0 1.25];
|
||||
for i = 1:length(amplitudes)
|
||||
y = sin(frequency * t * 2 * pi) * amplituden(i);
|
||||
plot(t, y)
|
||||
hold on;
|
||||
end
|
||||
end
|
||||
\end{lstlisting}
|
||||
Das obige Beispiel ist ein Paradebeispiel f\"ur eine schlechte
|
||||
Funktion. Sie hat folgende Probleme:
|
||||
|
||||
\code{myFirstFunction} (listing~\ref{badsinewavelisting}) is a
|
||||
prime-example of a bad function. There are several issues with it's
|
||||
design:
|
||||
|
||||
\begin{itemize}
|
||||
\item Der Name ist nicht aussagekr\"aftig.
|
||||
\item Die Funktion ist f\"ur genau einen Zweck geeignet.
|
||||
\item Was sie tut, ist festgelegt und kann von au{\ss}en nicht
|
||||
beeinflusst oder bestimmt werden.
|
||||
\item Sie tut drei Dinge auf einmal: Sinus berechnen \emph{und}
|
||||
Amplituden \"andern \emph{und} graphisch darstellen.
|
||||
\item Es ist nicht (einfach) m\"oglich an die berechneten Daten zu
|
||||
kommen.
|
||||
\item Keinerlei Dokumentation. Man muss den Code lesen und rekonstruieren, was sie tut.
|
||||
\item The function's name does not tell anything about it's purpose.
|
||||
\item The function is made for exactly one use-case (frequency of
|
||||
1\,Hz and five amplitudes).
|
||||
\item The function's behavior is \enterm{hard-coded} within it's body
|
||||
and cannot be influenced without changing the function itself.
|
||||
\item It solves three tasks at the same time: calculate sine
|
||||
\emph{and} change the amplitude \emph{and} plot the result.
|
||||
\item There is no way to access the calculated data.
|
||||
\item No documentation. One has to read and understand the code to
|
||||
learn what is does.
|
||||
\end{itemize}
|
||||
|
||||
Bevor wir anfangen die Funktion zu verbessern mu{\ss} definiert werden
|
||||
was das zu l\"osende Problem ist:
|
||||
Before we can try to improve the function the task should be clearly
|
||||
defined:
|
||||
\begin{enumerate}
|
||||
\item Welches Problem soll gel\"ost werden?
|
||||
\item Aufteilen in Teilprobleme.
|
||||
\item Gute Namen finden.
|
||||
\item Definieren der Schnittstellen --- Was m\"ussen die beteiligten Funktionen
|
||||
wissen? Was sollen sie zur\"uckliefern?
|
||||
\item Daten zur\"uck geben (R\"uckgabewerte definieren).
|
||||
\item Which problem should be solved?
|
||||
\item Can the problem be subdivided into smaller tasks?
|
||||
\item Find good names for each task.
|
||||
\item Define the interface. Which information is necessary to solve
|
||||
each task and which results should be returned to the caller
|
||||
(e.g. the user of another program that calls a function)?
|
||||
\end{enumerate}
|
||||
Das Beispielproblem aus Listing \ref{badsinewavelisting} kann in drei
|
||||
Teilprobleme aufgetrennt werden. (i) Berechnen der \emph{einzelnen}
|
||||
Sinusse. (ii) Plotten der jeweils berechneten Daten und (iii)
|
||||
Koordination von Berechnung und Darstellung mit unterschiedlichen
|
||||
Amplituden.
|
||||
|
||||
\paragraph{I. Berechnung eines einzelnen Sinus}
|
||||
As indicated above the \code{myFirstFunction} does three things at
|
||||
once, it seems natural, that the task should be split up into three
|
||||
parts. (i) Calculation of the individual sine waves defined by the
|
||||
frequency and the amplitudes (ii) graphical display of the data and
|
||||
(iii) coordination of calculation and display.
|
||||
|
||||
\paragraph{I. Calculation of a single sine wave}
|
||||
|
||||
Die Berechnung eines einzelnen Sinus ist ein typischer Fall f\"ur eine
|
||||
Funktion. Wiederum macht man sich klar, (i) wie die Funktion
|
||||
hei{\ss}en soll, (ii) welche Information sie ben\"otigt und (iii)
|
||||
welche Daten sie zur\"uckliefern soll.
|
||||
Before we start coding it is best to again think about the task and
|
||||
define (i) how to name the function, (ii) which information it needs
|
||||
(arguments), and (iii) what it should return to the caller.
|
||||
|
||||
\begin{enumerate}
|
||||
\item \codeterm[Funktion!Name]{Name}: der Name sollte beschreiben, was
|
||||
die Funktion tut. In diesem Fall berechnet sie einen Sinus. Ein
|
||||
geeigneter, kurzer Name w\"are also \code{sinewave()}.
|
||||
\item \codeterm[Funktion!Argumente]{Argumente}: die zu brechnende
|
||||
Sinusschwingung sei durch ihre Frequenz und die Amplitude
|
||||
bestimmt. Des Weiteren soll noch festgelegt werden, wie lang der
|
||||
Sinus sein soll und mit welcher zeitlichen Aufl\"osung gerechnet
|
||||
werden soll. Es werden also vier Argumente ben\"otigt, sie k\"onnten
|
||||
hei{\ss}en: \varcode{amplitude}, \varcode{frequency},
|
||||
\varcode{t\_max}, \varcode{t\_step}.
|
||||
\item \codeterm[Funktion!R{\"u}ckgabewerte]{R\"uckgabewerte}: Um den
|
||||
Sinus korrekt darstellen zu k\"onnen brauchen wir die Zeitachse und
|
||||
die entsprechenden Werte. Es werden also zwei Variablen
|
||||
zur\"uckgegeben: \varcode{time}, \varcode{sine}
|
||||
\item \codeterm[Function!Name]{Name}: the name should be descriptive
|
||||
of the function's purpose, i.e. the calculation of a sine wave. A
|
||||
appropriate name might be \code{sinewave()}.
|
||||
\item \codeterm[Function!Arguments]{Arguments}: What information does
|
||||
the function need to do the calculation? There are obviously the
|
||||
frequency as well as the amplitude. Further we may want to be able
|
||||
to define the duration of the sine wave and the temporal
|
||||
resolution. We thus need four arguments which should also named to
|
||||
describe their content: \code{amplitude, frequency, t\_max,} and
|
||||
\code{t\_step} might be good names.
|
||||
\item \codeterm[Function!Return values]{Return values}: For a correct
|
||||
display of the data we need two vectors. The time, and the sine wave
|
||||
itself. We just need two return values: \varcode{time}, \varcode{sine}
|
||||
\end{enumerate}
|
||||
Mit dieser Information ist es nun gut m\"oglich die Funktion zu
|
||||
implementieren (Listing \ref{sinefunctionlisting}).
|
||||
|
||||
\begin{lstlisting}[caption={Funktion zur Berechnung eines Sinus.}, label=sinefunctionlisting]
|
||||
Having defined this we can start coding
|
||||
(listing~\ref{sinefunctionlisting}).
|
||||
|
||||
\begin{lstlisting}[caption={Function that calculates a sine wave.}, label=sinefunctionlisting]
|
||||
function [time, sine] = sinewave(frequency, amplitude, t_max, t_step)
|
||||
% Calculate a sinewave of a given frequency, amplitude,
|
||||
% duration and temporal resolution.
|
||||
@ -1447,23 +1453,36 @@ function [time, sine] = sinewave(frequency, amplitude, t_max, t_step)
|
||||
% time: vector of the time axis
|
||||
% sine: vector of the calculated sinewave
|
||||
time = (0:t_step:t_max);
|
||||
sine = sin(frequency .* time .* 2 * pi) .* amplitude;
|
||||
sine = sin(frequency .* time .* 2 .* pi) .* amplitude;
|
||||
end
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\paragraph{II. Plotten einer einzelnen Schwingung}
|
||||
Das Plotten der berechneten Sinuschwingung kann auch von einer
|
||||
Funktion \"ubernommen werden. Diese Funktion hat keine andere Aufgabe,
|
||||
als die Daten zu plotten. Ihr Name sollte sich an dieser Aufgabe
|
||||
orientieren (z.B. \code{plotFunction()}). Um einen einzelnen Sinus
|
||||
zu plotten werden im Wesentlichen die x-Werte und die zugeh\"origen
|
||||
y-Werte ben\"otigt. Da mehrere Sinus geplottet werden sollen ist es
|
||||
auch sinnvoll eine Zeichenkette f\"ur die Legende an die Funktion zu
|
||||
\"ubergeben. Da diese Funktion keine Berechnung durchf\"uhrt wird kein
|
||||
R\"uckgabewert ben\"otigt (Listing \ref{sineplotfunctionlisting}).
|
||||
|
||||
\begin{lstlisting}[caption={Funktion zur graphischen Darstellung der Daten.}, label=sineplotfunctionlisting]
|
||||
\paragraph{II. Plotting a single sine wave}
|
||||
The display of the sine waves can also be delegated to a function. We
|
||||
can now decide whether we want the function to plot all sine waves at
|
||||
once, or if we want design a function that plots a single sine wave
|
||||
and that we then call repeatedly for each frequency/amplitude
|
||||
combination. The most flexible approach is the latter and we will
|
||||
thus implement it this way. We might come up with the following
|
||||
specification of the function:
|
||||
|
||||
\begin{enumerate}
|
||||
\item It should plot a single sine wave. But it is not limited to sine
|
||||
waves. It's name is thus: \code{plotFunction()}.
|
||||
\item What information does it need to solve the task? The
|
||||
to-be-plotted data as there is the values \code{y\_data} and the
|
||||
corresponding \code{x\_data}. As we want to plot series of sine
|
||||
waves we might want to have a \code{name} for each function to be
|
||||
displayed in the figure legend.
|
||||
\item Are there any return values? No, this function is just made for
|
||||
plotting, we do not need to return anything.
|
||||
\end{enumerate}
|
||||
|
||||
With this specification we can start to implement the function
|
||||
(listing~\ref{sineplotfunctionlisting}).
|
||||
|
||||
\begin{lstlisting}[caption={Function for the graphical display of data.}, label=sineplotfunctionlisting]
|
||||
function plotFunction(x_data, y_data, name)
|
||||
% Plots x-data against y-data and sets the display name.
|
||||
%
|
||||
@ -1478,31 +1497,41 @@ end
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\paragraph{III. Erstellen eines Skriptes zur Koordinierung}
|
||||
Die letzte Aufgabe ist die Koordinierung der Berechung und des
|
||||
Plottens f\"ur mehrere Amplituden. Das ist die klassische Aufgabe
|
||||
f\"ur ein \codeterm{Skript}. Auch hier gilt es einen ausdrucksvollen
|
||||
Name zu finden. Da es keine Argumente und R\"uckgabewerte gibt,
|
||||
m\"ussen die ben\"otigten Informationen direkt in dem Skript
|
||||
defniniert werden. Es werden ben\"otigt: ein Vektor f\"ur die
|
||||
Amplituden, je eine Variable f\"ur die gew\"unschte Frequenz, die
|
||||
maximale Zeit auf der x-Achse und die zeitliche Aufl\"osung. Das
|
||||
Skript \"offnet schlie{\ss}lich noch eine neue Abbildung mit
|
||||
\code{figure()} und setzt das \code{hold on} da nur das Skript
|
||||
wei{\ss}, das mehr als ein Plot erzeugt werden soll. Das Skript ist in
|
||||
Listing \ref{sinesskriptlisting} dargestellt.
|
||||
|
||||
\begin{lstlisting}[caption={Kontrollskript zur Koordination von Berechnung und graphischer Darstellung.},label=sinesskriptlisting]
|
||||
\paragraph{III. One script to rule them all}
|
||||
|
||||
The last task is to write a script to control the calculations and the
|
||||
plotting of the sine waves. Classically, such controlling of sub-tasks
|
||||
is handled in a script. It could be done with a function but if
|
||||
there is a reason for the existence of scripts then it is this.
|
||||
|
||||
Again, we need to specify what needs to be done:
|
||||
\begin{enumerate}
|
||||
\item The task is to display multiple sine waves. We want to have a
|
||||
fixed frequency but there should be various amplitudes displayed. An
|
||||
appropriate name for the script (that is the name of the m-file)
|
||||
might be \file{plotMultipleSinewaves.m}.
|
||||
\item What information do we need? we need to define the
|
||||
\code{frequency}, the range of \code{amplitudes}, the
|
||||
\code{duration} of the sine waves, and the temporal resolution given
|
||||
as the time between to points in time, i.e. the \code{stepsize}.
|
||||
\item We then need to create an empty figure, and work through the
|
||||
rang of \code{amplitudes}. We must not forget to switch \code{hold
|
||||
on} if we want to see all the sine waves in one plot.
|
||||
\end{enumerate}
|
||||
|
||||
The implementation is shown in listing~\ref{sinesskriptlisting}.
|
||||
|
||||
\begin{lstlisting}[caption={Control script for the plotting of sine waves.},label=sinesskriptlisting]
|
||||
amplitudes = 0.25:0.25:1.25;
|
||||
frequency = 2.0;
|
||||
t_max = 10.0;
|
||||
t_step = 0.01;
|
||||
duration = 10.0; % seconds
|
||||
stepsize = 0.01; % seconds
|
||||
|
||||
figure()
|
||||
hold on
|
||||
for i = 1:length(amplitudes)
|
||||
[x_data, y_data] = sinewave(frequency, amplitudes(i), ...
|
||||
t_max, t_step);
|
||||
duration, stepsize);
|
||||
plotFunction(x_data, y_data, sprintf('freq: %5.2f, ampl: %5.2f',...
|
||||
frequency, amplitudes(i)))
|
||||
end
|
||||
@ -1511,34 +1540,45 @@ legend('show')
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{exercise}{plotMultipleSinewaves.m}{}
|
||||
Erweiter das Programm so, dass die Sinusse f\"ur einen Satz von
|
||||
Frequenzen geplottet wird.
|
||||
Extend the program to plot also a range of frequencies.
|
||||
\pagebreak[4]
|
||||
\end{exercise}
|
||||
|
||||
\subsection{Einsatz von Funktionen und Skripten}
|
||||
|
||||
Funktionen sind kleine Codefragmente, die im Idealfall genau eine
|
||||
Aufgabe erledigen. Sie besitzen einen eigenen
|
||||
\determ{G\"ultigkeitsbereich}, das hei{\ss}t, dass Variablen aus dem
|
||||
globalen Workspace nicht verf\"ugbar sind und Variablen, die lokal in
|
||||
der Funktion erstellt werden nicht im globalen Workspace sichtbar
|
||||
werden. Dies hat zur Folge, dass Funktionen all die Informationen, die
|
||||
sie ben\"otigen, von au{\ss}en erhalten m\"ussen. Sie nehmen
|
||||
\determ{Argumente} entgegen und k\"onnen \determ{R\"uckgabwerte}
|
||||
zur\"uckliefern.
|
||||
|
||||
Die Verwendung von Funktionen ist der Verwendung von Skripten fast
|
||||
immer vorzuziehen sind. Das hei{\ss}t aber nicht, das Skripte zu
|
||||
verteufeln w\"aren und und vermieden werden sollten. In Wahrheit sind
|
||||
beide daf\"ur gemacht, Hand in Hand ein Problem zu l\"osen. W\"ahrend
|
||||
die Funktionen relativ kleine ``verdauliche'' Teilprobleme l\"osen,
|
||||
werden Skripte eingesetzt um den Rahmen zu bilden und den Ablauf zu
|
||||
koordinieren (Abbildung \ref{programlayoutfig}).
|
||||
|
||||
\begin{figure}
|
||||
\includegraphics[width=0.5\columnwidth]{simple_program.pdf}
|
||||
\titlecaption{Ein typisches Programmlayout.}{Das Kontrollskript
|
||||
koordiniert den Aufruf der Funktionen, \"ubergibt Argumente und
|
||||
nimmt R\"uckgabewerte entgegen.}\label{programlayoutfig}
|
||||
\end{figure}
|
||||
\begin{ibox}[t]{\label{whenscriptsbox}When to use scripts and functions}
|
||||
|
||||
It is easily possible to solve any programming problem only with
|
||||
functions. Avoiding functions is also possible but ends very messy
|
||||
and extremely hard to debug when the project grows. The effort for
|
||||
avoiding naming conflicts or cleaning up the workspace increases
|
||||
with the size of the project. Generally, functions should be
|
||||
preferred over scripts in almost all cases. There are, however,
|
||||
situations when a script offers advantages.
|
||||
|
||||
|
||||
\begin{minipage}{0.5\textwidth}
|
||||
\includegraphics[width=0.9\columnwidth]{simple_program}
|
||||
\end{minipage}
|
||||
\begin{minipage}{0.5\textwidth}
|
||||
\textbf{Controlling a task.} Solving tasks that involve calling
|
||||
sub-routines, as we did above, is one of these situations (see
|
||||
figure). The script calls functions and takes care of passing the
|
||||
correct arguments and storing the return values. \linebreak
|
||||
\textbf{Interactive development.} During the development phase a
|
||||
script grows as one \emph{interactively} works on the command
|
||||
line. Commands that have been tested are then transferred to the
|
||||
script.
|
||||
\end{minipage}\vspace{0.25cm}
|
||||
|
||||
Interactive programming is one of the main strengths of
|
||||
\matlab{}. Interactive refers to the interaction between the
|
||||
commands executed on the command line and the variables stored in
|
||||
the workspace. The immediate feedback if a certain operation works
|
||||
on the data stored in a variable or if the returned results are
|
||||
correct speeds up the developmental progress.
|
||||
|
||||
\textbf{Special solutions.} Program code that is only valid one very
|
||||
specific problem may reside in a script. As soon as there is code
|
||||
duplication or it grows too large, it is high time to consider
|
||||
extracting features into separate functions.
|
||||
\end{ibox}
|
||||
|
Reference in New Issue
Block a user