stub of the function scripts
This commit is contained in:
parent
5b8ff9b59c
commit
86978d4d41
@ -1,7 +1,7 @@
|
|||||||
% create a vector with a random numbers
|
% create a vector with random numbers
|
||||||
x = rand(1000000, 1);
|
x = rand(1000000, 1);
|
||||||
|
|
||||||
fprintf('time needed to manually filter elements smaller than 0.5 in a vector of length %i\n', length(x))
|
fprintf('Time needed to manually filter out elements smaller than 0.5 in a vector of length %i\n', length(x))
|
||||||
|
|
||||||
tic
|
tic
|
||||||
results = [];
|
results = [];
|
||||||
@ -14,7 +14,7 @@ for i = 1:length(x)
|
|||||||
end
|
end
|
||||||
toc
|
toc
|
||||||
|
|
||||||
fprintf('\ntime needed to do the same with logical indexing\n')
|
fprintf('\nTime needed to do the same with logical indexing\n')
|
||||||
|
|
||||||
tic
|
tic
|
||||||
results = x(x < 0.5);
|
results = x(x < 0.5);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
>> logicalIndexingBenchmark
|
>> logicalIndexingBenchmark
|
||||||
time needed to manually filter elements smaller than 0.5 in a vector of length 100000
|
Time needed to manually filter elements smaller than 0.5 in a vector of length 100000
|
||||||
Elapsed time is 0.008562 seconds.
|
Elapsed time is 0.008562 seconds.
|
||||||
|
|
||||||
time needed to do the same with logical indexing
|
Time needed to do the same with logical indexing
|
||||||
Elapsed time is 0.001543 seconds.
|
Elapsed time is 0.001543 seconds.
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
\subsection{Variablen}
|
\subsection{Variablen}
|
||||||
|
|
||||||
aEine Variable ist ein Zeiger auf eine Stelle im Speicher. Dieser
|
Eine Variable ist ein Zeiger auf eine Stelle im Speicher. Dieser
|
||||||
Zeiger hat einen Namen, den Variablennamen, und einen Datentyp
|
Zeiger hat einen Namen, den Variablennamen, und einen Datentyp
|
||||||
(Abbildung \ref{variablefig}). Im Speicher wird der Wert der Variablen
|
(Abbildung \ref{variablefig}). Im Speicher wird der Wert der Variablen
|
||||||
bin\"ar gespeichert. Wird auf den Wert der Variable zugegriffen, wird
|
bin\"ar gespeichert. Wird auf den Wert der Variable zugegriffen, wird
|
||||||
@ -758,6 +758,23 @@ nun die Werte an den Stellen zur\"uck, an denen der logische Vektor
|
|||||||
von (\code{x}) an den Stellen, an denen \code{x < 5} wahr ist.
|
von (\code{x}) an den Stellen, an denen \code{x < 5} wahr ist.
|
||||||
\end{exercise}
|
\end{exercise}
|
||||||
|
|
||||||
|
Logisches Indizieren wurde oben so benutzt, dass die Auswahl auf dem
|
||||||
|
Inhalt desselben Vektors beruhte. Ein sehr h\"auiger Fall ist
|
||||||
|
jedoch, dass man die Auswahl aus einem Vektor auf den Inhalt eines
|
||||||
|
zweiten Vektors basiert. Ein Beispiel ist, dass man \"uber einen
|
||||||
|
gewissen Zeitraum Daten aufnimmt und aus diesen die Daten eines
|
||||||
|
bestimmten Zeitraums ausw\"ahlen m\"ochte (Abbildung
|
||||||
|
\ref{logicalindexingfig}).
|
||||||
|
|
||||||
|
|
||||||
|
\begin{figure}[h]
|
||||||
|
\includegraphics[width= 0.9\columnwidth]{logicalIndexingTime}
|
||||||
|
\caption{\texbf{Beispiel f\"ur ``indirektes'' logisches Indizieren.}
|
||||||
|
Der rot markierte Abschnitt aus den Daten wurde ``indirekt''
|
||||||
|
anhand logischen Indizierens auf dem Zeitvektor
|
||||||
|
ausgew\"ahlt.}\label{logicalindexingfig}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
\begin{exercise}{logicalIndexingTime.m}{}
|
\begin{exercise}{logicalIndexingTime.m}{}
|
||||||
Angenommen es werden \"uber einen bestimmten Zeitraum Messwerte
|
Angenommen es werden \"uber einen bestimmten Zeitraum Messwerte
|
||||||
genommen. Bei solchen Messungen er\"alt man einen Vektor, der die
|
genommen. Bei solchen Messungen er\"alt man einen Vektor, der die
|
||||||
@ -773,9 +790,6 @@ nun die Werte an den Stellen zur\"uck, an denen der logische Vektor
|
|||||||
\item Benutze das logische Indizieren um die Messwerte
|
\item Benutze das logische Indizieren um die Messwerte
|
||||||
auszuw\"ahlen, die dem zeitlichen Abschnitt 5-6\,s entsprechen.
|
auszuw\"ahlen, die dem zeitlichen Abschnitt 5-6\,s entsprechen.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\begin{figure}
|
|
||||||
\includegraphics[width=0.6\textwidth]{logicalIndexing_time.png}
|
|
||||||
\end{figure}
|
|
||||||
\end{exercise}
|
\end{exercise}
|
||||||
|
|
||||||
|
|
||||||
@ -898,8 +912,8 @@ end
|
|||||||
|
|
||||||
\begin{exercise}{neverendingWhile.m}{}
|
\begin{exercise}{neverendingWhile.m}{}
|
||||||
Implementiere eine \textbf{while}-Schleife, die unendlich
|
Implementiere eine \textbf{while}-Schleife, die unendlich
|
||||||
l\"auft. Tipp: der Boolesche Ausdruck hinter dem \textbf{while} muss
|
l\"auft. Tipp: wenn der Boolesche Ausdruck hinter dem \textbf{while}
|
||||||
immer zu wahr ausgewertet werden.
|
zu wahr ausgewertet wird, wird die Schleife weiter ausgef\"uhrt.
|
||||||
\end{exercise}
|
\end{exercise}
|
||||||
|
|
||||||
|
|
||||||
@ -988,11 +1002,11 @@ auftreten k\"onnen, die einer unterschiedlichen Behandlung bed\"urfen.
|
|||||||
mynumber = input('Enter a number:');
|
mynumber = input('Enter a number:');
|
||||||
switch mynumber
|
switch mynumber
|
||||||
case -1
|
case -1
|
||||||
disp('negative eins');
|
disp('negative one');
|
||||||
case 1
|
case 1
|
||||||
disp('positive eins');
|
disp('positive one');
|
||||||
otherwise
|
otherwise
|
||||||
disp('etwas anderes');
|
disp('something else');
|
||||||
end
|
end
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
@ -1012,15 +1026,271 @@ switch-Anweisung und der case-Anweisung getestet wird.
|
|||||||
kann immer durch eine \code{if} Anweisung erstezt werden.
|
kann immer durch eine \code{if} Anweisung erstezt werden.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
|
\subsection{Die Schl\"usselworte \code{break} und \code{continue}}
|
||||||
|
|
||||||
|
Soll die Ausf\"uhrung einer Schleife abgebrochen oder \"ubersprungen
|
||||||
|
werden, werden die Schl\"usselworte \textbf{break} und
|
||||||
|
\textbf{continue} eingesetzt (Listing \ref{breakcontinuelisting}
|
||||||
|
zeigt, wie sie eingesetzt werden k\"onnen).
|
||||||
|
|
||||||
|
\begin{lstlisting}[caption={Ensatz der \code{continue} und \code{break} Schl\"usselworte um die Ausf\"uhrung von Abschnitte in Schleife zu \"uberspringen oder abzubrechen.}, label=breakcontinuelisting]
|
||||||
|
for x = 1:10
|
||||||
|
if(x > 2 & x < 5)
|
||||||
|
continue;
|
||||||
|
end
|
||||||
|
disp(x);
|
||||||
|
end
|
||||||
|
|
||||||
|
x = 1;
|
||||||
|
while true
|
||||||
|
if(x > 5)
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
disp(x);
|
||||||
|
x = x + 1
|
||||||
|
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.
|
||||||
|
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Benutze eine \code{for} Schleife um die Element auszuw\"ahlen.
|
||||||
|
\item Benutze logisches Indizieren.
|
||||||
|
\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.
|
||||||
|
\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.
|
||||||
|
\end{itemize}
|
||||||
|
\end{exercise}
|
||||||
|
|
||||||
\section{Skripte und Funktionen}
|
\section{Skripte und Funktionen}
|
||||||
|
|
||||||
|
\subsection{Was ist ein Programm?}
|
||||||
|
|
||||||
|
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\"r Zeile von oben nach unten ausgef\"uhrt.
|
||||||
|
|
||||||
|
\matlab{} kennt drei Arten von Programmen:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Skripte
|
||||||
|
\item Funktionen
|
||||||
|
\item Objekte (werden wir ignorieren)
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
Alle Programme werden in den sogenannten \textit{m-files} gespeichert
|
||||||
|
(z.B. \textit{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 erzuegt wurde im
|
||||||
|
\textit{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 \textbf{Funktionen}.
|
||||||
|
|
||||||
|
\subsection{Funktionen}
|
||||||
|
|
||||||
|
Eine Funktion in \matlab{} wird \"ahnlich zu einer mathematischen
|
||||||
|
Funktion definiert:
|
||||||
|
|
||||||
|
\[ y = f(x) \]
|
||||||
|
|
||||||
|
Die Funktion hat einen Namen $f$, sie h\"angt von einem Argument $x$
|
||||||
|
ab und liefert ein Ergebnis $y$ zur\"uck. Listing
|
||||||
|
\ref{functiondefinitionlisting} zeigt wie das in \matlab{} umgesetzt
|
||||||
|
wird.
|
||||||
|
|
||||||
|
\begin{lstlisting}[caption={Funktionsdefinition in \matlab{}}, label=functiondefinitionlisting]
|
||||||
|
function [y] = function_name(arg_1, arg_2)
|
||||||
|
% ^ ^ ^
|
||||||
|
% Rueckgabewert Argument_1, Argument_2
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Ein Funktion beginnt mit dem Schl\"usselwort \textbf{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 mit einem \textbf{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:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item Kapseln von Programmcode, der f\"ur sich eine Aufgabe l\"ost.
|
||||||
|
\item Definierte Schnittstelle.
|
||||||
|
\item Eigener G\"ultigkeitsbereich:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Variablen im Workspace sind in der Funktion \textbf{nicht} sichtbar.
|
||||||
|
\item Variablen, die in der Funktion definiert werden erscheinen
|
||||||
|
\textbf{nicht} im Workspace.
|
||||||
|
\end{itemize}
|
||||||
|
\item Erhöht die Wiederverwendbarkeit von Programmcode.
|
||||||
|
\item Erh\"oht die Lesbarkeit von Programmen, da sie
|
||||||
|
\"ubersichtlicher werden.
|
||||||
|
\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={Eine Beispielfunktion, die eine Reihe Sinus plottet.},label=badsinewavelisting]
|
||||||
|
function meine_erste_funktion() % 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);
|
||||||
|
plot(t, y)
|
||||||
|
hold on;
|
||||||
|
end
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Dieses schlechte Beispiel ist ein Paradebeispiel f\"ur eine schlechte
|
||||||
|
Funktion. Sie hat folgende Probleme:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Der Name ist nicht aussagekr\"aftig.
|
||||||
|
\item Die Funktion ist f\"ur genau einen Zweck gut.
|
||||||
|
\item Was sie tut, ist festgelegt und kann von au{\ss}en nicht
|
||||||
|
beeinflusst werden.
|
||||||
|
\item Sie tut drei Dinge aus einmal: Sinus berechnen \textbf{und}
|
||||||
|
Amplituden \"andern \textbf{und} graphisch darstellen.
|
||||||
|
\item Es ist nicht (einfach) m\"oglich an die berechneten Daten zu
|
||||||
|
kommen.
|
||||||
|
\item Keinerlei Dokumentation. Man muss den code lesen um zu
|
||||||
|
rekonstruieren, was sie tut.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Bevor wir anfangen die Funktion zu verbessern sollten wir uns Gedanken
|
||||||
|
\"uber das zu l\"osende Problem zu machen:
|
||||||
|
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Welches Problem soll gel\"ost werden?
|
||||||
|
\item Aufteilen in Teilprobleme.
|
||||||
|
\item Gute Namen finden.
|
||||||
|
\item Definieren der Schnittstellen --- Was muss die Funktion
|
||||||
|
wissen? Was möchte ich von ihr haben?
|
||||||
|
\item Daten zur\"uck geben (R\"uckgabewerte definieren).
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
Das Beispiel aus Listing \ref{badsinewavelisting} kann in drei
|
||||||
|
Teilprobleme aufgetrennt werden:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Berechnen der \textbf{einzelnen} Sinus.
|
||||||
|
\item Plotten der Daten.
|
||||||
|
\item Koordinieren von Berechung und Darstellung mit
|
||||||
|
unterschiedlichen Amplituden.
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
\begin{lstlisting}
|
||||||
|
function [t, y] = calculate_sinewave(frequency, amplitude, t_max, t_step)
|
||||||
|
x = (0:t_step:t_max);
|
||||||
|
y = sin(frequency * t * 2 * pi) * amplitude;
|
||||||
|
end
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
|
||||||
|
\textbf{2. Plotten einer einzelnen Schwingung:}
|
||||||
|
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Namen finden
|
||||||
|
\item Schnittstelle definieren: Was will ich von der Funktion?
|
||||||
|
Welche Information muss ich ihr geben?\pause
|
||||||
|
\begin{itemize}
|
||||||
|
\item Funktion muss wissen: Welche Daten soll sie plotten? Zeitachse,
|
||||||
|
y-Werte, einen Namen f\"ur die Legende?
|
||||||
|
\item Muss nichts zur\"uckgeben.
|
||||||
|
\end{itemize}
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
\begin{lstlisting}
|
||||||
|
function plot_sinewave(x_data, y_data, name)
|
||||||
|
plot(x_data, y_data, 'displayname', name)
|
||||||
|
end
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
|
||||||
|
\textbf{3. Erstellen eines \textbf{Skriptes} zur Koordinierung:}
|
||||||
|
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Namen finden
|
||||||
|
\item Definieren eins Vektors, f\"ur die Amplituden.
|
||||||
|
\item Definieren einer Variable f\"ur die Frequenz.
|
||||||
|
\item Definieren der Variablen f\"ur das Maximum und die
|
||||||
|
Schrittweite der x-Achse.
|
||||||
|
\item \"Offnen einer neuen Abbildung (\code{figure()}).
|
||||||
|
\item Setzen des \code{hold on}.
|
||||||
|
\item \code{for}-Schleife, die über die Amplituden iteriert, die
|
||||||
|
Sinus berechnen l\"asst und die Resultate an die Plot-Funktion
|
||||||
|
weiterreicht.
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
Skript: \verb+plot_sinewaves.m+
|
||||||
|
\begin{lstlisting}
|
||||||
|
amplitudes = 0.25:0.25:1.25;
|
||||||
|
frequency = 2;
|
||||||
|
t_max = 10;
|
||||||
|
t_step = 0.01;
|
||||||
|
|
||||||
|
figure()
|
||||||
|
hold on
|
||||||
|
|
||||||
\section{Graphische Darstellung von Daten}
|
for a = amplitudes
|
||||||
%%% Wuerde ich als eigenes Kapitel machen! JB
|
name = num2str(a);
|
||||||
%%% In einem separaten Verzeichnis...
|
[x_data, y_data] = calculate_sinewave(frequency, a, t_max, t_step);
|
||||||
|
plot_sinewave(x_data, y_data, name)
|
||||||
|
end
|
||||||
|
legend('show')
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\begin{exercise}{}{}
|
||||||
|
Erweitert das Programm so, dass auch ein Satz von Frequenzen benutzt
|
||||||
|
wird.
|
||||||
|
\end{exercise}
|
||||||
|
|
||||||
|
\subsection{Fazit}
|
||||||
|
|
||||||
|
Funktionen sind kleine Code Fragmente, die
|
||||||
|
\begin{enumerate}
|
||||||
|
\item ... genau eine Aufgabe erledigen.
|
||||||
|
\item ... Argumente entgegennehmen k\"onnen.
|
||||||
|
\item ... R\"uckgabewerte haben k\"onnen.
|
||||||
|
\item ... ihren eigenen G\"ultigkeitsbereich haben.
|
||||||
|
\item ... Skripten fast immer vorzuziehen sind.
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
Die vorangegangene Diskussion klingt, alsob Skripte zu verteufeln und
|
||||||
|
zu vermeiden w\"aren. Dem ist nicht so. In Wahrheit sind sie daf''ur
|
||||||
|
gemacht, Hand in Hand ein Probelm zu l\"osen. W\"ahrend die Funktionen
|
||||||
|
relativ kleine ``verdauliche'' Teilprobleme l\"osen. Sind die Skripte
|
||||||
|
daf\"ur gemacht den Rahmen zu bilden und den Ablauf zu koordinieren.
|
||||||
|
Ein m\"ogliches Programmlayout k\"onnte so aussehen:
|
||||||
|
|
||||||
\begin{figure}
|
\begin{figure}
|
||||||
\includegraphics[width=0.9\columnwidth]{convincing}
|
\includegraphics[width=0.5\columnwidth]{./images/simple_program.pdf}
|
||||||
\caption{Die Folgen schlecht annotierter
|
|
||||||
Plots. \url{www.xkcd.com}} \label{xkcdplotting}
|
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user