diff --git a/header.tex b/header.tex index fe89c66..b014897 100644 --- a/header.tex +++ b/header.tex @@ -167,8 +167,11 @@ \newcommand{\reZpN}{\mathds{R^+_0}} \newcommand{\koZ}{\mathds{C}} -%%%%% english terms: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%% english, german and code terms: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\enterm}[1]{``#1''} +\newcommand{\determ}[1]{\textit{#1}} +\newcommand{\codeterm}[1]{\textit{#1}} +\newcommand{\filename}[1]{\texttt{#1}} %%%%% code/matlab commands: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \usepackage{textcomp} diff --git a/programming/lecture/programming.tex b/programming/lecture/programming.tex index b618fa7..975ebeb 100644 --- a/programming/lecture/programming.tex +++ b/programming/lecture/programming.tex @@ -53,7 +53,7 @@ Listing zeigt zwei M\"oglichkeiten: Die Zeile 1 kann etwa so gelesen werden:''Erzeuge eine Variable mit dem Namen y und weise ihr einen leeren Wert zu.'' Das Gleichheitszeichen ist der sogenannte -\emph{Zuweisungsoperator}. Zeile 5 definiert eine Variable x, der +\codeterm{Zuweisungsoperator}. Zeile 5 definiert eine Variable x, der nun der Zahlenwert 38 zugewiesen wird. Da \matlab{}, wenn nicht anders angegeben immer den ``double'' Datentypen benutzt, haben beide Variablen diesen Datentyp. @@ -73,10 +73,11 @@ Leerzeichen in Variablennamen nicht erlaubt. \subsection{Arbeiten mit Variablen} -Nat\"urlich kann mit den Variablen auch gearbeitet, bzw -gerechnet werden. \matlab{} kennt alle normalen arithmetischen Operatoren wie -\code{+, -, *. /}. Die Potenz wird \"uber das Dach Symbol \code{\^} -dargestellt. Das folgende Listing zeigt, wie sie benutzt werden. +Nat\"urlich kann mit den Variablen auch gearbeitet, bzw gerechnet +werden. \matlab{} kennt alle normalen arithmetischen Operatoren wie +\code{+}, \code{-}, \code{*} und \code{/}. Die Potenz wird \"uber das +Dachsymbol \code{\^} dargestellt. Das folgende Listing zeigt, wie sie +benutzt werden. \begin{lstlisting}[label=varListing3, caption={Rechnen mit Variablen.}] >> x = 1; @@ -120,13 +121,13 @@ Der Datentyp bestimmt, wie die im Speicher abgelegten Bitmuster interpretiert werden. Die wichtigsten Datentpyen sind folgende: \begin{itemize} -\item \textit{integer} - Ganze Zahlen. Hier gibt es mehrere +\item \codetterm{integer} - Ganze Zahlen. Hier gibt es mehrere Unterarten, die wir in \matlab{} (meist) ignorieren k\"onnen. -\item \textit{double} - Flie{\ss}kommazahlen. Im Gegensatz zu den reelen Zahlen, die durch diesen Datentyp dargestellt werden, sind sie abz\"ahlbar. -\item \textit{complex} - Komplexe Zahlen. -\item \textit{logical} - Boolesche Werte, die als wahr +\item \codeterm{double} - Flie{\ss}kommazahlen. Im Gegensatz zu den reelen Zahlen, die durch diesen Datentyp dargestellt werden, sind sie abz\"ahlbar. +\item \codeterm{complex} - Komplexe Zahlen. +\item \codeterm{logical} - Boolesche Werte, die als wahr (\code{true}) oder falsch (\code{false}) interpretiert werden. -\item \textit{char} - ASCII Zeichen +\item \codeterm{char} - ASCII Zeichen \end{itemize} Unter den numerischen Datentypen gibt es verschiedene Arten mit unterschiedlichem Speicherbedarf und Wertebreich. @@ -278,11 +279,14 @@ Zeilenvektor. Der Zugriff auf die Inhalte eines Vektors erfolgt \"uber den Index (Abbildung \ref{vectorindexingfig}). Jedes Feld in einem Vektor hat -einen fortlaufenden \textit{Index}, \"uber den auf die Werte des +einen fortlaufenden \codeterm{Index}, \"uber den auf die Werte des Vektors zugegriffen werden kann. Dabei spielt es keine Rolle, ob es -sich um einen Zeilen- oder Spaltenvektor handelt. \textbf{Achtung!} +sich um einen Zeilen- oder Spaltenvektor handelt. +\begin{important} Anders als viele andere Sprachen beginnt \matlab{} mit dem Index -1. Die Listings \ref{arrayListing4} und \ref{arrayListing5} zeigen wie +1. +\end{important} +Die Listings \ref{arrayListing4} und \ref{arrayListing5} zeigen wie mit Indexen auf die Inhalte eines Vektors zugegriffen werden kann. \begin{lstlisting}[label=arrayListing4, caption={Zugriff auf den Inhalt von Vektoren I}] @@ -487,7 +491,7 @@ Der Zugriff auf Inhalte von Matrizen erfolgt \"uber den Index Koordinatensystem wird jede Zelle einer Matrize mit einem Index angesprochen, der aus $n$ Zahlen besteht wobei $n$ die Dimensionalit\"at der Matrize ist. Diese Art des Zugriffs wird -\textit{subsript indexing} genannt. +\codeterm{subsript indexing} genannt. \begin{lstlisting}[caption={Zugriff auf Inhalte von Matrizen, Indexierung.}, label=matrixIndexing] @@ -512,8 +516,8 @@ Dimensionalit\"at der Matrize ist. Diese Art des Zugriffs wird 56 \end{lstlisting} -Alternativ zum \textit{subscript indexing} k\"onnen die Zellen einer -Matrize auch \textit{linear} angesprochen werden (Abbildung +Alternativ zum \codeterm{subscript indexing} k\"onnen die Zellen einer +Matrize auch \emph{linear} angesprochen werden (Abbildung \ref{matrixlinearindexingfig}). Diese Art der Adressierung ist nicht so intuitiv verst\"andlich, kann aber sehr hilfreich sein. Der ``linare'' Index einer Zelle reicht von 1 bis \code{numel(M)} @@ -586,13 +590,13 @@ durchgef\"uhrt werden soll. \section{Boolesche Operationen} -Boolesche Ausdr\"ucke sind Anweisungen, die zu \emph{wahr} oder -\emph{falsch} ausgewertet werden. Man kennt sie z.B. aus der +Boolesche Ausdr\"ucke sind Anweisungen, die zu \codeterm{wahr} oder +\codeterm{falsch} ausgewertet werden. Man kennt sie z.B. aus der Mengenlehre. In der Programmierung werdens sie eingesetzt, um z.B. die Beziehung zwischen Entit\"aten zu testen. Hierzu werden die -\emph{relationalen Operatoren} (\code{>}, \code{<}, \code{==}, +\codeterm{relationalen Operatoren} (\code{>}, \code{<}, \code{==}, \code{!}, gr\"o{\ss}er als, kleiner als, gleich und nicht) -eingesetzt. Mehrere Ausdr\"ucke werden mittels der \textit{logischen +eingesetzt. Mehrere Ausdr\"ucke werden mittels der \codeterm{logischen Operatoren} (\code{\&}, \code{|}, UND, ODER ) verkn\"upft. Sie sind f\"ur uns nicht nur wichtig um Codeabschnitte bedingt auszuf\"uhren (Verzweigungen, \ref{controlstructsec}) sondern auch um aus Vektoren @@ -655,7 +659,7 @@ verf\"ugbar. \end{center} \end{table} -Um Werte miteinander zu vergleichen gibt es die \textit{relationalen +Um Werte miteinander zu vergleichen gibt es die \codeterm{relationalen Operatoren} (Tabelle \ref{relationaloperators}). Mit ihnen kann man auf Dinge wie Gleicheit (\code{==}) gr\"o{\ss}er oder kleiner als (\code{>}, \code{<}) testen. @@ -679,13 +683,13 @@ auf Dinge wie Gleicheit (\code{==}) gr\"o{\ss}er oder kleiner als \end{table} 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 +\codeterm{logical}. Man kann jede beliebige Variable zu wahr oder falsch +auswerten indem man in den Typ \code{logical} umwandelt. Dabei werden von \matlab{} alle Werte, die nicht 0 sind als wahr eingesch\"atzt. Listing \ref{booleanexpressions} zeigt einige Beispiele. \matlab{} kennt die Schl\"usselworte \code{true} und \code{false}. Diese sind jedoch nur Synonyme f\"ur die -\textit{logical} Werte 1 und 0. Man beachte, dass der +\code{logical} Werte 1 und 0. Man beachte, dass der Zuweisungsoperator \code{=} und der logische Operator \code{==} zwei grundverschiedene Dinge sind. Da sie umgangsprachlich gleich sind kann man sie leider leicht verwechseln. @@ -744,7 +748,7 @@ die Verwendung eines Booleschen Ausdrucks auf z.B. einen Vektor einen logischen Vektor gleicher Gr\"o{\ss}e erh\"alt. Dieser wird nun benutzt um auf den urspr\"unglichen Vektor zuzugreifen. \matlab{} gibt nun die Werte an den Stellen zur\"uck, an denen der logische Vektor -\textit{wahr} ist (Listing \ref{logicalindexing1}). +\codeterm{wahr} ist (Listing \ref{logicalindexing1}). \begin{lstlisting}[caption={Beispiel logisches Indizieren.}, label=logicalindexing1] @@ -863,13 +867,13 @@ Abschnitte wiederholt ausf\"uhren will. \subsubsection{Die \code{for} -- Schleife} 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 +\codeterm{for-Schleife}. Sie besteht aus dem \codeterm{Schleifenkopf} und +dem \codeterm{Schleifenk\"orper}. Der Kopf regelt, wie h\"aufig der Code im K\"orper ausgef\"uhrt wird. Der Schleifenkopf beginnt mit dem Schl\"usselwort \code{for} auf welches folgend die -\textit{Laufvariable} definiert wird. In \matlab ``l\"auft''/iteriert +\codeterm{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 +\codeterm{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 \code{end} beendet. Listing \ref{looplisting} zeigt das @@ -988,9 +992,9 @@ Die \code{switch} Verzweigung Wird eingesetzt wenn mehrere F\"alle auftreten k\"onnen, die einer unterschiedlichen Behandlung bed\"urfen. Wird mit dem Schl\"usselwort \code{switch} begonnen, gefolgt von der -\textit{switch Anweisung} (Zahl oder String). Jeder Fall auf den die +\codeterm{switch Anweisung} (Zahl oder String). Jeder Fall auf den die Anweisung \"uberpr\"ft werden soll wird mit dem Schl\"usselwort -\code{case} eingeleitet. Diese wird gefolgt von der \textit{case +\code{case} eingeleitet. Diese wird gefolgt von der \codeterm{case Anweisung} welche definiert gegen welchen Fall auf \underline{Gleichheit} getestet wird. F\"ur jeden Fall wird der Programmcode angegeben, der ausgef\"uhrt werden soll Optional k\"onnen @@ -1097,13 +1101,13 @@ wird, dann wird es Zeile f\"Ur Zeile von oben nach unten ausgef\"uhrt. \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 +Alle Programme werden in den sogenannten \codeterm{m-files} gespeichert +(z.B. \filename{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 +\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 @@ -1111,7 +1115,7 @@ 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 \emph{Funktionen}. +dieses Problem bieten die \codeterm{Funktionen}. \subsection{Funktionen} @@ -1193,7 +1197,7 @@ was das zu l\"osende Problem ist: \end{enumerate} Das Beispielproblem aus Listing \ref{badsinewavelisting} kann in drei Teilprobleme aufgetrennt werden. (i) Berechnen der \emph{einzelnen} -Sinus. (ii) Plotten der jeweils berechneten Daten und (iii) +Sinusse. (ii) Plotten der jeweils berechneten Daten und (iii) Koordination von Berechnung und Darstellung mit unterschiedlichen Amplituden. @@ -1205,16 +1209,16 @@ hei{\ss}en soll, (ii) welche Information sie ben\"otigt und (iii) welche Daten sie zur\"uckliefern soll. \begin{enumerate} -\item \textbf{Name:} der Name sollte schon beschreiben, was die Funktion +\item \codeterm{Name:} der Name sollte schon beschreiben, was die Funktion tut. In diesem Fall berechnet sie einen Sinus. Ein geeigneter Name w\"are also \code{calculate\_sinwave}. -\item \textbf{Argumente:} die zu brechnende Sinusschwingung sei durch +\item \codeterm{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: \code{amplitude}, \code{frequency}, \code{t\_max}, \code{t\_step}. -\item \textbf{R\"uckgabewerte:} Um den Sinus korrekt darstellen zu k\"onnen brauchen wir die +\item \codeterm{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: \code{time, sine} \end{enumerate} @@ -1317,13 +1321,3 @@ gemacht den Rahmen zu bilden und den Ablauf zu koordinieren (Abbildung koordiniert den Aufruf der Funktionen, \"ubergibt Argumente und nimmt R\"uckgabewerte entgegen.}\label{programlayoutfig} \end{figure} - - -\begin{ibox}[tp]{Python} - The cooler programming language. -\end{ibox} - - -\begin{important} - Something you should really remember. -\end{important} diff --git a/regression/lecture/lin_regress.py b/regression/lecture/lin_regress.py index 44898c1..7a1adc1 100644 --- a/regression/lecture/lin_regress.py +++ b/regression/lecture/lin_regress.py @@ -5,16 +5,16 @@ from matplotlib.transforms import Bbox def create_data(): m = 0.75 n= -40 - x = np.arange(5.,115., 2.5) + x = np.arange(10.,110., 2.5) y = m * x + n; - noise = np.random.randn(len(x))*15 + rng = np.random.RandomState(37281) + noise = rng.randn(len(x))*15 y += noise return x, y, m, n -def plot_data(x, y): - plt.scatter(x, y, marker='o', color='dodgerblue', s=40) - ax = plt.gca() +def plot_data(ax, x, y): + ax.scatter(x, y, marker='o', color='b', s=40) ax.spines["right"].set_visible(False) ax.spines["top"].set_visible(False) ax.yaxis.set_ticks_position('left') @@ -27,21 +27,13 @@ def plot_data(x, y): ax.set_ylim(-80, 80) ax.set_xticks(np.arange(0,121, 40)) ax.set_yticks(np.arange(-80,81, 40)) - fig = plt.gcf() - fig.set_facecolor("white") - fig.set_size_inches(3., 3.) - plt.tight_layout() - fig.savefig("lin_regress.pdf") - plt.close() -def plot_data_slopes(x, y, m, n): - plt.scatter(x, y, marker='o', color='dodgerblue', s=40) - for i in np.linspace(m/4, m*1.5, 5): - plt.plot(x, i*x+n, color="r", lw=2) - - plt.xlim([-2.5, 102.5]) - ax = plt.gca() +def plot_data_slopes(ax, x, y, m, n): + ax.scatter(x, y, marker='o', color='b', s=40) + xx = np.asarray([2, 118]) + for i in np.linspace(0.3*m, 2.0*m, 5): + ax.plot(xx, i*xx+n, color="r", lw=2) ax.spines["right"].set_visible(False) ax.spines["top"].set_visible(False) ax.yaxis.set_ticks_position('left') @@ -49,26 +41,18 @@ def plot_data_slopes(x, y, m, n): ax.tick_params(direction="out", width=1.25) ax.tick_params(direction="out", width=1.25) ax.set_xlabel('Input x') - ax.set_ylabel('Output y') + #ax.set_ylabel('Output y') ax.set_xlim(0, 120) ax.set_ylim(-80, 80) ax.set_xticks(np.arange(0,121, 40)) ax.set_yticks(np.arange(-80,81, 40)) - fig = plt.gcf() - fig.set_facecolor("white") - fig.set_size_inches(3., 3.) - plt.tight_layout() - fig.savefig("lin_regress_slope.pdf") - plt.close() -def plot_data_intercepts(x, y, m, n): - plt.scatter(x, y, marker='o', color='dodgerblue', s=40) - for i in np.linspace(n-n/2, n+n/2, 5): - plt.plot(x, m * x + i, color="r", lw=2) - - plt.xlim([-2.5, 102.5]) - ax = plt.gca() +def plot_data_intercepts(ax, x, y, m, n): + ax.scatter(x, y, marker='o', color='b', s=40) + xx = np.asarray([2, 118]) + for i in np.linspace(n-1*n, n+1*n, 5): + ax.plot(xx, m*xx + i, color="r", lw=2) ax.spines["right"].set_visible(False) ax.spines["top"].set_visible(False) ax.yaxis.set_ticks_position('left') @@ -76,22 +60,25 @@ def plot_data_intercepts(x, y, m, n): ax.tick_params(direction="out", width=1.25) ax.tick_params(direction="out", width=1.25) ax.set_xlabel('Input x') - ax.set_ylabel('Output y') + #ax.set_ylabel('Output y') ax.set_xlim(0, 120) ax.set_ylim(-80, 80) ax.set_xticks(np.arange(0,121, 40)) ax.set_yticks(np.arange(-80,81, 40)) - fig = plt.gcf() - fig.set_facecolor("white") - fig.set_size_inches(3., 3.) - plt.tight_layout() - fig.savefig("lin_regress_intercept.pdf") - plt.close() if __name__ == "__main__": x, y, m, n = create_data() plt.xkcd() - plot_data(x,y) - plot_data_slopes(x,y,m,n) - plot_data_intercepts(x,y,m,n) + fig = plt.figure() + ax = fig.add_subplot(1, 3, 1) + plot_data(ax, x, y) + ax = fig.add_subplot(1, 3, 2) + plot_data_slopes(ax, x, y, m, n) + ax = fig.add_subplot(1, 3, 3) + plot_data_intercepts(ax, x, y, m, n) + fig.set_facecolor("white") + fig.set_size_inches(7., 2.6) + fig.tight_layout() + fig.savefig("lin_regress.pdf") + plt.close() diff --git a/regression/lecture/regression.tex b/regression/lecture/regression.tex index d856639..de73701 100644 --- a/regression/lecture/regression.tex +++ b/regression/lecture/regression.tex @@ -10,9 +10,7 @@ ein Optimierungsproblem, der besser als Kurvenfit bekannt ist (\enterm{curve fitting}). \begin{figure}[tp] - \includegraphics[width=0.33\columnwidth]{lin_regress}\hfill - \includegraphics[width=0.33\columnwidth]{lin_regress_slope}\hfill - \includegraphics[width=0.33\columnwidth]{lin_regress_intercept} + \includegraphics[width=1\textwidth]{lin_regress}\hfill \titlecaption{.}{F\"ur eine Reihe von Eingangswerten $x$, z.B. Stimulusintensit\"aten, wurden die Antworten $y$ eines Systems gemessen (links). Der postulierte lineare Zusammenhang hat @@ -32,14 +30,15 @@ beiden Parameter Steigung $m$ und $y$-Achsenabschnitt $n$ und es wird die Kombination von $m$ und $n$ gesucht, die die Systemantwort am besten vorhersagt. -In folgenden Kapitel werden wir anhand dieses Beispiels zeigen, -welchen Methoden hinter einem Kurvenfit stecken, wie also die optimale -Kombination aus Steigung und $y$-Achsenabschnitt gefunden werden kann. +In folgenden Kapitel werden wir anhand dieses Beispiels zeigen, welche +Methoden hinter einem Kurvenfit stecken, wie also numerisch die +optimale Kombination aus Steigung und $y$-Achsenabschnitt gefunden +werden kann. \section{Methode der kleinsten quadratischen Abweichung} -Um die optimale Parameterkombination zu finden muss zun\"achst ein +Um die optimale Parameterkombination zu finden, muss zun\"achst ein Ma{\ss} f\"ur den Unterschied zwischen den tats\"achlich gemessenen und den unter Verwendung eines Parametersatzes vorhergesagten Werten definiert werden. Eine der am h\"aufigsten verwendeten