programming part done

This commit is contained in:
Jan Grewe 2015-11-06 22:20:06 +01:00
parent 573bb58ac9
commit cc1ce11fe9
2 changed files with 154 additions and 113 deletions

View File

@ -0,0 +1,17 @@
amplitudes = 0.25:0.25:1.25;
frequencies = (2:2:10);
t_max = 10;
t_step = 0.01;
figure()
hold on
for i = 1:length(amplitudes)
for j = i:length(frequencies)
[x_data, y_data] = calculate_sinewave(frequencies(j), ...
amplitudes(i), t_max, t_step);
plot_sinewave(x_data, y_data, sprintf('freq: %5.2f, ampl: %5.2f',...
frequencies(j), amplitudes(i)))
end
end
legend('show')

View File

@ -582,13 +582,12 @@ ODER ) verkn\"upft. Sie sind f\"ur uns nicht nur wichtig um
Codeabschnitte bedingt auszuf\"uhren (Verzweigungen,
\ref{controlstructsec}) sondern auch um aus Vektoren und Matrizen
bequem Elemente auszuw\"ahlen (logisches Indizieren,
\ref{logicalindexingsec}).
Die folgenden Tabellen zeigen die Wahrheitstabellen f\"ur das logische
UND (\ref{logicalandor}, links) aund das logische ODER
(\ref{logicalandor}, rechts). Es werden die Aussagen A und B mit dem
Operator verkn\"upft. Beim logischen UND ist der gesamte Ausdruck nur
dann wahr, wenn beide Ausdr\"ucke sich zu wahr auswerten lassen.
\ref{logicalindexingsec}). Die folgenden Tabellen zeigen die
Wahrheitstabellen f\"ur das logische UND (\ref{logicalandor}, links)
aund das logische ODER (\ref{logicalandor}, rechts). Es werden die
Aussagen A und B mit dem Operator verkn\"upft. Beim logischen UND ist
der gesamte Ausdruck nur dann wahr, wenn beide Ausdr\"ucke sich zu
wahr auswerten lassen.
\begin{table}[]
@ -611,20 +610,19 @@ dann wahr, wenn beide Ausdr\"ucke sich zu wahr auswerten lassen.
\end{minipage}
\end{table}
Anders ist das beim logischen ODER. Hier ist der gesamte Ausdruck
wahr, wenn sich der eine \textit{oder} der andere Ausdruck zu wahr
auswerten l\"a{\ss}t.
Tabelle \ref{logicaloperators} zeigt die logischen Operatoren, die in
\matlab{} definiert sind. Zu bemerken sind hier noch die \code{\&\&} und
\code{||} Operatoren. Man kann beliebige Ausdr\"ucke verkn\"upfen und
h\"aufig kann schon anhand des ersten Ausdrucks entschieden werden, ob
der gesamte Boolesche Ausdruck zu wahr oder falsch ausgewertet werden
wird. Wenn zwei Aussagen mit einem UND verkn\"upft werden und der
erste zu falsch ausgewerte wird, dann muss der zweite gar nicht mehr
gepr\"uft werden. Die Verwendung der ``short-circuit'' Versionen spart
Rechenzeit. Das auschliessende ODER (XOR) ist in \matlab{} nur als Funktion
\code{xor(A, B)} verf\"ugbar.
\noindent Anders ist das beim logischen ODER. Hier ist der gesamte
Ausdruck wahr, wenn sich der eine \textit{oder} der andere Ausdruck zu
wahr auswerten l\"a{\ss}t. Tabelle \ref{logicaloperators} zeigt die
logischen Operatoren, die in \matlab{} definiert sind. Zu bemerken
sind hier noch die \code{\&\&} und \code{||} Operatoren. Man kann
beliebige Ausdr\"ucke verkn\"upfen und h\"aufig kann schon anhand des
ersten Ausdrucks entschieden werden, ob der gesamte Boolesche Ausdruck
zu wahr oder falsch ausgewertet werden wird. Wenn zwei Aussagen mit
einem UND verkn\"upft werden und der erste zu falsch ausgewerte wird,
dann muss der zweite gar nicht mehr gepr\"uft werden. Die Verwendung
der ``short-circuit'' Versionen spart Rechenzeit. Das auschliessende
ODER (XOR) ist in \matlab{} nur als Funktion \code{xor(A, B)}
verf\"ugbar.
\begin{table}[th]
\caption{\label{logicaloperators}
@ -643,7 +641,7 @@ Rechenzeit. Das auschliessende ODER (XOR) ist in \matlab{} nur als Funktion
\end{center}
\end{table}
Um Werte miteinander zu vergleichen gibt es die \textit{relationalen
\noindent Um Werte miteinander zu vergleichen gibt es die \textit{relationalen
Operatoren} (Tabelle \ref{relationaloperators}). Mit ihnen kann man
auf Dinge wie Gleicheit (\code{==}) gr\"o{\ss}er oder kleiner als
(\code{>, <}) testen.
@ -666,7 +664,7 @@ auf Dinge wie Gleicheit (\code{==}) gr\"o{\ss}er oder kleiner als
\end{center}
\end{table}
Das Ergebnis eines Booleschen Ausdrucks ist immer vom Datentyp
\noindent Das Ergebnis eines Booleschen Ausdrucks ist immer vom Datentyp
\textit{logical}. Man kann jede beliebige Variable zu wahr oder falsch
auswerten indem man in den Typ \textit{logical} umwandelt. Dabei
werden von \matlab{} alle Werte, die nicht 0 sind als wahr
@ -727,7 +725,6 @@ Filteroperationen auf Vektoren und Matrizen effizient durchgef\"uhrt
werden. Es ist sehr m\"achtig und, wenn es einmal verstanden wurde,
sehr intuitiv zu benuzten.
Das Grundkonzept hinter der logischen Indizierung ist, dass man durch
die Verwendung eines Booleschen Ausdrucks auf z.B. einen Vektor einen
logischen Vektor gleicher Gr\"o{\ss}e erh\"alt. Dieser wird nun
@ -758,8 +755,8 @@ 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.
\end{exercise}
Logisches Indizieren wurde oben so benutzt, dass die Auswahl auf dem
Inhalt desselben Vektors beruhte. Ein sehr h\"auiger Fall ist
\noindent 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
@ -824,7 +821,7 @@ x =
120
\end{lstlisting}
Im Prinzip ist das obige Programm v\"ollig in Ordnung. Es f\"allt
\noindent Im Prinzip ist das obige Programm v\"ollig in Ordnung. Es f\"allt
jedoch auf, dass die Zeilen 2 bis 5 sehr \"ahnlich sind; bis auf die
Multiplikation mit einer ansteigenden Zahl \"andert sich nichts. Die
Verwendung von mehr oder weniger exakten Klonen einzelner Zeilen oder
@ -846,7 +843,7 @@ einen \"asthetischen Aspekt sondern vielmehr darum, dass es schwerwiegende Nacht
den entscheidenden Teil verpasst.
\end{enumerate}
Alle Programmiersprachen bieten zur L\"osung dieses Problems die
\noindent Alle Programmiersprachen bieten zur L\"osung dieses Problems die
Schleifen. Eine Schleife wird immer dann eingesetzt, wenn man
Abschnitte wiederholt ausf\"uhren will.
@ -855,17 +852,15 @@ Abschnitte wiederholt ausf\"uhren will.
Der am h\"aufigsten benutzte Vertreter der Schleifen ist die
\textit{for-Schleife}. Sie besteht aus dem \textit{Schleifenkopf} und
dem \textit{Schleifenk\"orper}. Der Kopf regelt, wie h\"aufig der Code
im K\"orper ausgef\"uhrt wird.
\begin{definition}
Der Schleifenkopf beginnt mit dem Schl\"usselwort \textbf{for} auf
welches folgend die \textit{Laufvariable} definiert wird. In \matlab
``l\"auft''/iteriert eine for-Schleife immer(!) \"uber einen
Vektor. Die \textit{Laufvariable} nimmt mit jeder Iteration einen
Wert dieses Vektors an. Im Schleifenk\"orper k\"onnen beliebige
Anweisungen ausgef\"uhrt werden. Die Schleife wird durch das
Schl\"usselwort \textbf{end} beendet. Listing \ref{looplisting}
\end{definition}
im K\"orper ausgef\"uhrt wird. Der Schleifenkopf beginnt mit dem
Schl\"usselwort \textbf{for} auf welches folgend die
\textit{Laufvariable} definiert wird. In \matlab ``l\"auft''/iteriert
eine for-Schleife immer(!) \"uber einen Vektor. Die
\textit{Laufvariable} nimmt mit jeder Iteration einen Wert dieses
Vektors an. Im Schleifenk\"orper k\"onnen beliebige Anweisungen
ausgef\"uhrt werden. Die Schleife wird durch das Schl\"usselwort
\textbf{end} beendet. Listing \ref{looplisting} zeigt das
Grundger\"ust einer for-Schleife.
\begin{lstlisting}[caption={Beispiel einer \textbf{for} Schleife. Die Laufvariable \code{x} nimmt mit jeder Iteration der Schleife einen Wert des Vektors \code{1:5} an.}, label=looplisting]
for x = 1:5
@ -887,15 +882,11 @@ Eine weiterer Schleifentyp, der weniger h\"aufig eingesetzt wird, ist
die \textot{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.
\begin{definition}
Der Schleifenkopf beginnt mit dem Schl\"usselwort \textbf{while}
gefolgt von einem \underline{Booleschen Ausdruck}. Solange dieser zu
\textit{true} ausgewertet werden kann, wird der Code im
Schleifenk\"orper ausgef\"uhrt. Die Schleife wird mit dem
Schl\"usselwort \textbf{end} beendet.
\end{definition}
ausgef\"uhrt. Der Schleifenkopf beginnt mit dem Schl\"usselwort
\textbf{while} gefolgt von einem \underline{Booleschen
Ausdruck}. Solange dieser zu \textit{true} ausgewertet werden kann,
wird der Code im Schleifenk\"orper ausgef\"uhrt. Die Schleife wird
mit dem Schl\"usselwort \textbf{end} beendet.
\begin{lstlisting}[caption={Grundstruktur einer \textbf{while} Schleife.}, label=whileloop]
@ -1097,7 +1088,7 @@ wird, dann wird es Zeile f\"r Zeile von oben nach unten ausgef\"uhrt.
\item Objekte (werden wir ignorieren)
\end{enumerate}
Alle Programme werden in den sogenannten \textit{m-files} gespeichert
\noindent 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
@ -1120,7 +1111,7 @@ Funktion definiert:
\[ y = f(x) \]
Die Funktion hat einen Namen $f$, sie h\"angt von einem Argument $x$
\noindent 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.
@ -1131,7 +1122,7 @@ 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
\noindent 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
@ -1153,7 +1144,7 @@ definiert. \"uber die Definition/Benutzung von Funktionen wird folgendes erreich
\"ubersichtlicher werden.
\end{itemize}
Das Folgende Beispiel (Listing \ref{badsinewavelisting}) zeigt eine
\noindent Das Folgende Beispiel (Listing \ref{badsinewavelisting}) zeigt eine
Funktion, die eine Reihe von Sinusschwingungen unterschiedlicher
Frequenzen berechnet und graphisch darstellt.
@ -1170,13 +1161,13 @@ function meine_erste_funktion() % Funktionskopf
end
\end{lstlisting}
Dieses schlechte Beispiel ist ein Paradebeispiel f\"ur eine schlechte
\noindent Das obige 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 Die Funktion ist f\"ur genau einen Zweck geeignet.
\item Was sie tut, ist festgelegt und kann von au{\ss}en nicht
beeinflusst werden.
beeinflusst oder bestimmt 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
@ -1185,72 +1176,99 @@ Funktion. Sie hat folgende Probleme:
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:
\noindent Bevor wir anfangen die Funktion zu verbessern mu{\ss} definiert werden
was das zu l\"osende Problem ist:
\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 Definieren der Schnittstellen --- Was m\"ussen die beteiligten Funktionen
wissen? Was sollen sie zur\"uckliefern?
\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}
\noindent Das Beispielproblem aus Listing \ref{badsinewavelisting} kann in drei
Teilprobleme aufgetrennt werden. (i) Berechnen der \textbf{einzelnen}
Sinus. (ii) Plotten der jeweils berechneten Daten und (iii)
Koordination von Berechnung und Darstellung mit unterschiedlichen
Amplituden.
\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}
\paragraph{I. Berechnung eines einzelnen Sinus}
\textbf{2. Plotten einer einzelnen Schwingung:}
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.
\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}
\item \textbf{Name:} der Name sollte schon beschreiben, was die Funktion
tut. In diesem Fall berechnet sie einen Sinus. Ein geeigneter Name
w\"are also \textit{calculate\_sinwave}.
\item \textbf{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: \textit{amplitude,
frequency, t\_max, t\_step}.
\item \textbf{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: \textit{time, sine}
\end{enumerate}
\begin{lstlisting}
\noindent Mit dieser Information ist es nun gut m\"oglich die Funktion zu
implementieren (Listing \ref{sinefunctionlisting}).
\begin{lstlisting}[caption={Funktion, die einen Sinus berechnet.}, label=sinefunctionlisting]
function [time, sine] = calculate_sinewave(frequency, amplitude, t_max, t_step)
% The function calculates a sinewave with a given frequency and
% amplitude.
% Arguments: frequency, the frequency of the sine
% amplitude, the amplitude of the sine
% t_max, the duration of the sine in seconds
% t_step, the temporal resolution in seconds
% Returns: time, the time axis
% sine, the calculated sinewave
time = (0:t_step:t_max);
sine = sin(frequency .* time .* 2 * pi) .* amplitude;
\end{lstlisting}
\paragraph{II. Plotten einer einzelnen Schwingung}
Diese Aufage 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. \textit{plot\_sinewave}). 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, die die Daten plottet.}, label=sineplotfunctionlisting]
function plot_sinewave(x_data, y_data, name)
% Plots x-data against y-data and sets the display name.
% Arguments: x_data, the x-data
% y_data, the y-data
% name, the displayname
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}
\paragraph{III. Erstellen eines Skriptes zur Koordinierung}
Die letzt Aufgabe ist die Koordinierung der Berechung und des Plottens
f\"ur mehrere Amplituden. Das ist die klassische Aufgabe f\"ur ein
Skript. Auch hier gilt es einen ausdrucksvollen Name zu finden. Da es
keine Argumente und R\"uckgabewerte gibt bleibt und nur, die
ben\"otigten Information direkt in dem Skript zu defninieren. Dies
sind: 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 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, das die Berechnung und plotting koordiniert.}, label=sinesskriptlisting]
amplitudes = 0.25:0.25:1.25;
frequency = 2;
t_max = 10;
@ -1259,15 +1277,16 @@ t_step = 0.01;
figure()
hold on
for a = amplitudes
name = num2str(a);
[x_data, y_data] = calculate_sinewave(frequency, a, t_max, t_step);
plot_sinewave(x_data, y_data, name)
for i = 1:length(amplitudes)
[x_data, y_data] = calculate_sinewave(frequency, amplitudes(i), ...
t_max, t_step);
plot_sinewave(x_data, y_data, sprintf('freq: %5.2f, ampl: %5.2f',...
frequency, amplitudes(i)))
end
legend('show')
\end{lstlisting}
\begin{exercise}{}{}
\begin{exercise}{plotMultipleSinewaves.m}{}
Erweitert das Programm so, dass auch ein Satz von Frequenzen benutzt
wird.
\end{exercise}
@ -1283,14 +1302,19 @@ Funktionen sind kleine Code Fragmente, die
\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:
\noindent Die vorangegangene Aussagen klingen, als ob Skripte zu
verteufeln w\"aren und und vermieden werden sollten. Dem ist nicht
so. In Wahrheit sind sie daf\"ur gemacht, Hand in Hand mit den
Funktionen 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 (Abbildung
\ref{programlayoutfig}).
\begin{figure}
\includegraphics[width=0.5\columnwidth]{./images/simple_program.pdf}
\caption{\textbf{Ein typisches Programmlayout.} Das Kontrollskript
koordiniert den Aufruf der Funktionen, \"ubergibt Argumente und
nimmt R\"uckgabewerte entgegen.}\label{programlayoutfig}
\end{figure}