From cc1ce11fe9e5008001d96a7ab83287a893ea3cae Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Fri, 6 Nov 2015 22:20:06 +0100 Subject: [PATCH] programming part done --- programming/code/plotMultipleSinewaves.m | 17 ++ programming/lectures/programming.tex | 250 +++++++++++++---------- 2 files changed, 154 insertions(+), 113 deletions(-) create mode 100644 programming/code/plotMultipleSinewaves.m diff --git a/programming/code/plotMultipleSinewaves.m b/programming/code/plotMultipleSinewaves.m new file mode 100644 index 0000000..b0063f0 --- /dev/null +++ b/programming/code/plotMultipleSinewaves.m @@ -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') diff --git a/programming/lectures/programming.tex b/programming/lectures/programming.tex index 6498e71..35ed4c1 100644 --- a/programming/lectures/programming.tex +++ b/programming/lectures/programming.tex @@ -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}