%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{\tr{Programming basics}{Grundlagen der Programmierung in Matlab}} \section{Variablen und Datentypen} \subsection{Variablen} Eine Variable ist ein Zeiger auf eine Stelle im Speicher. Dieser Zeiger hat einen Namen, den Variablennamen, und einen Datentyp (Abbildung \ref{variablefig}).Im Speicher wird der Wert der Variablen bin\"ar gespeichert. Wird auf den Wert der Variable zugegriffen, wird dieses Bitmuster je nach Datentyp interpretiert. Das Beispiel in Abbildung \ref{variablefig} zeigt, dass das gleiche Bitmuster im einen Fall als 8-Bit Integer Datentyp zur Zahl 38 interpretiert wird und im anderen Fall als Character zum kaufm\"annischen ``und'' ausgewertet wird. In Matlab sind Datentypen nicht von sehr zentraler Bedeutung. Wir werden uns dennoch sp\"ater etwas genauer mit ihnen befassen. \begin{figure} \centering \begin{subfigure}{.5\textwidth} \includegraphics[width=0.8\textwidth]{variable} \label{variable:a} \end{subfigure}% \begin{subfigure}{.5\textwidth} \includegraphics[width=.8\textwidth]{variableB} \label{variable:b} \end{subfigure} \caption{\textbf{Variablen.} Variablen sind Zeiger auf eine Adresse im Speicher, die einen Namen und einen Datentypen beinhalten. Im Speicher ist der Wert der Variable bin\"ar gespeichert. Abh\"angig vom Datentyp wird dieses Bitmuster unterschiedlich interpretiert.}\label{variablefig} \end{figure} \subsection{Erzeugen von Variablen} In Matlab kann eine Variable auf der Kommandozeile, in einem Skript oder einer Funktion an beliebiger Stelle erzeugen. Das folgende Listing zeigt zwei M\"oglichkeiten: \footnotesize \begin{lstlisting}[label=varListing1, caption=Erzeugen von Variablen] >> y = [] y = [] >> >> x = 38 x = 38 \end{lstlisting} \normalsize 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 \textit{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. \footnotesize \begin{lstlisting}[label=varListing2, caption={Erfragen des Datentyps einer Variable, Listen aller definierten Variablen.}] >>disp(class(x)) double >> >> who % oder whos um mehr Information zu bekommen \end{lstlisting} \normalsize Bei der Namensgebung ist zu beachten, dass Matlab auf Gro{\ss}- und Kleinschreibung achtet und ein Variablennane mit einem alphabethischen Zeichen beginnen muss. Des Weiteren sind Umlaute, Sonder- und Leerzeichen in Variablennamen nicht erlaubt. \subsection{Arbeiten mit Variablen} Nat\"urlich kann man mit den Variablen auch arbeiten, bzw rechnen. 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. \footnotesize \begin{lstlisting}[label=varListing3, caption={Rechnen mit Variablen.}] >> x = 1; >> x + 10 ans = 11 >> >> x % x wurde nicht veraendert ans = 1 >> >> y = 2; >> >> x + y ans = 3 >> >> z = x + y z = 3 >> >> z = z * 5; >> z z = 15 >> >> clear z \end{lstlisting} \normalsize Beachtenswert ist z.B. in Zeilen 3 und 6, dass wir mit dem Inhalt einer Variablen rechnen k\"onnen, ohne dass dadurch ihr Wert ver\"andert w\"urde. Wenn der Wert einer Variablen ver\"andert werden soll, dann muss dieser der Variable expliyit zugewiesen werden (mit dem \code{=} Zuweisungsoperator, z.B. Zeilen 16, 20). Zeile 25 zeigt wie eine einzelne Variable gel\"oscht wird. \subsection{Datentypen} 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 Unterarten, die wir in Matlab (meist) ignorieren k\"onnen. \item \textit{double} - Flie{\ss}kommazahlen. \item \textit{complex} - Komplexe Zahlen. \item \textit{logical} - Boolesche Werte, die als wahr (\textit{true}) oder falsch (\textit{false}) interpretiert werden. \item \textit{char} - ASCII Zeichen \end{itemize} Unter den numerischen Datentypen gibt es verschiedene Arten mit unterschiedlichem Speicherbedarf und Wertebreich. \begin{table}[] \centering \caption{Gel\"aufige Datentypen und ihr Wertebereich.} \label{dtypestab} \begin{tabular}{l|l|c|cl} Datentyp & Speicherbedarf & Wertebereich & Beispiel \\ \cline{1-4} double & 64 bit & & Flie{\ss}kommazahlen.\\ \cline{1-4} int & 64 bit & $-2^{31} bis 2^{31}-1$ & Ganzzahlige Werte \\ \cline{1-4} int16 & 64 bit & $-2^{15} bis 2^{15}-1$ & Digitalisierte Spannungen. \\ \cline{1-4} uint8 & 64 bit & 0 bis 255 & Digitalisierte Imaging Daten. \\ \cline{1-4} & & & \end{tabular} \end{table} Matlab arbeitet meist mit dem ``double'' Datentyp wenn numerische Daten gespeichert werden. Dennoch lohnt es sich, sich ein wenig mit den Datentypen auseinanderzusetzen. Ein Szenario, dass in der Neurobiologie nicht selten ist, ist, dass wir die elektrische Aktivit\"at einer Nervenzelle messen. Die gemessenen Spannungen werden mittels Messkarte digitalisiert und auf dem Rechner gespeichert. Typischerweise k\"onnen mit solchen Messkarten Spannungen im Bereich $\pm 10$\,V gemessen werden. Die Aufl\"osung der Wandler betr\"agt typischerweise 16 bit. Das heisst, dass der gesamte Spannungsbereich in $2^{16}$ Schritte aufgeteilt ist. Um Speicherplatz zu sparen ist es sinnvoll, die gemessenen Daten als ``int16'' Werte im Rechner abzulegen. Die Daten als ``echte'' Spannungen, also als Flie{\ss}kommawerte, abzulegen w\"urde den 4-fachen Speicherplatz ben\"otigen. \section{Vektoren und Matrizen} \begin{definition}[Vektoren und Matrizen] Vektoren und Matrizen sind die wichtigsten Datenstrukturen in Matlab. In andern Programmiersprachen spricht man von ein- bzw. mehrdimensionalen Feldern. Felder sind Datenstrukturen, die mehrere Werte des geleichen Datentyps in einer Variablen vereinen. Da Matalb seinen Ursprung in der Verarbeitung von mathematischen Vektoren und Matrizen hat werden sie hier auch so genannt.\\ In Wahrheit existiert auch in Matlab kein Unterschied zwischen beiden Datenstrukturen. Im Hintergrund sind auch Vektoren 2-diemsensionale Matrizen bei denen eine Dimension die Gr\"o{\ss}e 1 hat. \end{definition} \subsection{Vektoren} Im Gegensatz zu den Variablen, die einzelene Werte beinhalten, Skalare, kann ein Vektor mehrere Werte des gleichen Datentyps beinhalten (Abbildung \ref{vectorfig} B). Die Variable ``test'' enth\"alt in diesem Beispiel vier ganzzahlige Werte. \begin{figure} \includegraphics[width=0.8\columnwidth]{scalarArray} \caption{\textbf{Skalare und Vektoren. A)} Eine skalare Variable kann genau einen Wert tragen. \textbf{B)} Ein Vektor kann mehrer Werte des gleichen Datentyps (z.B. ganzzahlige Integer Werte) beinhalten. Matlab kennt den Zeilen- (row-) und Spaltenvektor (columnvector).}\label{vectorfig} \end{figure} Das folgende Listing zeigt, wie einfache Vektoren erstellt werden k\"onnen. \footnotesize \begin{lstlisting}[label=arrayListing1, caption={Erstellen einfacher Zeilenvektoren.}] >> a = [0 1 2 3 4 5 6 7 8 9] % Erstellen eines Zeilenvektors a = 0 1 2 3 4 5 6 7 8 9 >> >> b = (0:9) % etwas bequemer b = 0 1 2 3 4 5 6 7 8 9 >> >> c = (0:2:10) c = 0 2 4 6 8 10 \end{lstlisting} \normalsize Die L\"ange eines Vektors kann mithilfe der Funktion \code{length()} bestimmt werden. \"Ahnliche Information kann man \"uber die Funktion \code{size()} erhalten. Im Falle des Vektors \code{a} von oben erh\"alt man folgende Ausgabe: \footnotesize \begin{lstlisting}[label=arrayListing2, caption={Gr\"o{\ss}e von Vektoren.}] >> length(a) ans = 10 >> size(a) ans = 1 10 \end{lstlisting} \normalsize Diese Ausgabe zeigt, dass Vektoren im Grunde 2-dimensional sind. Bei einem Zeilenvektor hat die erste Dimension die Gr\"o{\ss}e 1. \code{length(a)} gibt die l\"angste Ausdehnung an. \footnotesize \begin{lstlisting}[label=arrayListing3, caption={Spaltenvektoren.}] >> b = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] % Erstellen eines Spaltenvektors b = 1 2 .... 9 10 >> length(b) ans = 10 >> size(b) ans = 10 1 >> b = b'; % Transponieren >> size(b) ans = 1 10 \end{lstlisting} Der \code{'}- Operator transponiert den Spaltenvektor zu einem Zeilenvektor. \subsubsection{Zugriff auf Inhalte von Vektoren} \begin{figure} \includegraphics[width=0.4\columnwidth]{arrayIndexing} \caption{\textbf{Indices von Vektoren.} Jedes Feld eines Vektors hat einen Index mit dem auf den jeweiligen Inhalt zugegriffen werden kann.}\label{vectorindexingfig} \end{figure} Der Zugriff auf die Inhalte eines Vektors erfolgt \"uber den Index (Abbildung \ref{vectorindexingfig}). Jedes Feld in einem Vektor hat einen \textit{Index} \"uber den auf die Werte des Vektors zugegriffen werden kann. Dabei spielt es keine Rolle, ob es sich um einen Zeilen- oder Spaltenvektor handlet. \textbf{Achtung!} Anders als viele andere Sprachen beginnt Matlab mit dem Index 1. Die Listings \ref{arrayListing4} und \ref{arrayListing5} zeigen wie man mit dem Index auf die Inhalte zugreifen kann. \footnotesize \begin{lstlisting}[label=arrayListing4, caption={Zugriff auf den Inhalt von Vektoren I}] >> a = (11:20); >> a(1) % das 1. Element ans = 11 >> a(5) % das 5. Element ans = 15 >> a(end) % das letzte Element ans = 20 \end{lstlisting} \normalsize Hierbei kann man auf einzelne Werte zugreifen oder, analog zur Erzeugung von Vektoren, die \code{:} Notation verwenden um auf mehrere Element gleichzeitig zuzugreifen. \footnotesize \begin{lstlisting}[caption={Zugriff auf den Inhalt von Vektoren I}, label=arrayListing5] >> a([1 3 5]) % das 1., 3. und 5. Element ans = 11 13 15 >> a(2:4) % alle element von Index 2 bis 4 ans = 12 13 14 >> a(1:2:end) %jedes zweite Element ans = 11 13 15 17 19 \end{lstlisting} \normalsize \paragraph{Frage:} Der R\"uckgabewert von \code{size(a)} ist wieder ein Vektor der L\"ange 2. Wie k\"onnte man also die Gr\"o{\ss}e von \code{a} in der zweiten Dimension herausfinden? \paragraph{Antwort:} Man speichert den R\"uckgabewert in einer Variable (\code{s = size(a);}) und gibt den Inhalt an der Stelle 2 aus (\code{disp(s(2))}). \subsubsection{Operationen auf Vektoren} Nat\"urlich kann man mit Vektoren auch rechnen. Listing \ref{arrayListing5} zeigt Rechnungen mit Vektoren. \footnotesize \begin{lstlisting}[caption={Rechnen mit Vektoren.},label=arrayListing5] >> a = (0:2:8); >> a + 5 % addiere einen Skalar ans = 5 7 9 11 13 >> a - 5 % subtrahiere einen Skalar ans = -5 -3 -1 1 3 >> a .* 2 % Multiplication ans = 0 4 8 12 16 >> a ./ 2 % Division ans = 0 1 2 3 4 >> a(1:3) + a(2:4) % Addieren von 2 Vektoren ans = 2 6 10 >> >> a(1:2) + a(2:4) % Vektoren muessen gleich gross sein! ??? Error using ==> plus Matrix dimensions must agree. \end{lstlisting} \normalsize Wird ein Vektor mit einem skalaren Wert verrechnet, dann ist das Problemlos m\"oglich. Bei der Multiplikation (Zeile 10), der Division (Zeile 14) und auch der Potenzierung sollte man mit vorangestellem '.' klar machen, dass es sich um einen \textit{elementweise} Verarbeitung handelt. F\"ur diese elementweisen Operationen kennt Matlab die Operatoren \code{.*, ./} und \code{.\^}. Die einfachen Operatoren sind im Kontext von Vektoren und Matrizen anders belegt, als man es vielleicht erwarten w\"urde. Es sind dann die entsprechenden Matrixoperationen, die man aus der linearen Algebrar kennt (s.u.). Zu Beachten ist des Weiteren noch die Fehlermeldung am SChluss von Listing \ref{arrayListing5}. Wenn zwei Vektoren (elementweise) miteinander verrechnet werden sollen muss nicht nur die Anzahl Element übereinstimmen sondern es muss auch das Layout (Zeilen- oder Spaltenvektoren) \"ubereinstimmen. Will man Elemente aus einem Vektor entfernen, dann weist man den entsprechenden Zellen einen leeren Wert (\code{[]}) zu. \footnotesize \begin{lstlisting}[label=arrayListing6, caption={L\"oschen von Elementen aus einem Vektor.}] >> a = (0:2:8); >> length(a) ans = 5 >> a(1) = [] % loesche das erste Element a = 2 4 6 8 >> a([1 3]) = [] a = 4 8 >> length(a) ans = 2 \end{lstlisting} Neben dem L\"oschen von Vektorinhalten kann man Vektoren auch erweitern oder zusammensetzen. Auch hier muss das Layout der Vektoren \"ubereinstimmen (Listing \ref{arrayListing7}, Zeile 12). Will man einen Vektor erweitern, kann man \"uber das Ende hinaus zuweisen. Matlab erweitert dann die Variable. Auch hierbei muss auf das Layout geachtet werden. Zudem ist dieser Vorgang ``rechenintensiv'' und man sollte, soweit m\"oglich, vermeiden Vektoren bei Bedarf einfach zu erweitern. \footnotesize \begin{lstlisting}[caption={Zusammenf\"ugen und erweitern von Vektoren.}, label=arrayListing7] >> a = (0:2:8); >> b = (10:2:19); >> c = [a b] % erstelle einen Vektor aus einer Liste von Vektoren c = 0 2 4 6 8 10 12 14 16 18 >> length(c) ans = 10 >> length(a) + length(b) ans = 10 >> c = [a b']; Error using horzcat Dimensions of matrices being concatenated are not consistent. >> b(6:8) = [1 2 3 4]; \end{lstlisting} \subsection{Matrizen} \begin{figure} \includegraphics[width=0.5\columnwidth]{matrices} \caption{\textbf{Indices von Vektoren.} Jedes Feld eines Vektors hat einen Index mit dem auf den jeweiligen Inhalt zugegriffen werden kann.}\label{vectorindexingfig} \end{figure} \begin{figure} \includegraphics[width=0.9\columnwidth]{matrixIndexing} \caption{\textbf{Indices von Vektoren.} Jedes Feld eines Vektors hat einen Index mit dem auf den jeweiligen Inhalt zugegriffen werden kann.}\label{vectorindexingfig} \end{figure} \begin{figure} \includegraphics[width=0.9\columnwidth]{matrixLinearIndexing} \caption{\textbf{Indices von Vektoren.} Jedes Feld eines Vektors hat einen Index mit dem auf den jeweiligen Inhalt zugegriffen werden kann.}\label{vectorindexingfig} \end{figure} \section{Boolesche Operationen} \section{Logisches Indizieren} \section{Kontrollstrukturen} \begin{definition}[Kontrollstrukturen] In der Regel wird ein Programm Zeile f\"ur Zeile von oben nach unten ausgef\"uhrt. Manchmal muss der Kontrollfluss aber so gesteuert werden, dass bestimmte Teile des Programmcodes wiederholt oder nur unter bestimmten Bedingungen ausgef\"uhrt werden. Von grosser Bedeutung sind hier zwei Strukturen: \begin{enumerate} \item Schleifen. \item Bedingte Anweisungen und Verzweigungen. \end{enumerate} \end{definition} \section{Skripte und Funktionen} \section{Graphische Darstellung von Daten} \begin{figure} \includegraphics[width=0.9\columnwidth]{./images/convincing} \caption{Die Folgen schlecht annotierter Plots. \url{www.xkcd.com}} \label{xkcdplotting} \end{figure}