diff --git a/chapter.mk b/chapter.mk index 8a56ed1..8a0e56e 100644 --- a/chapter.mk +++ b/chapter.mk @@ -31,7 +31,7 @@ cleangnuplots : # script: chapter : $(BASENAME)-chapter.pdf -$(BASENAME)-chapter.pdf : $(BASENAME)-chapter.tex $(BASENAME).tex $(wildcard $(BASENAME).aux) $(PYPDFFILES) $(GPTTEXFILES) +$(BASENAME)-chapter.pdf : $(BASENAME)-chapter.tex $(BASENAME).tex $(wildcard $(BASENAME).aux) $(PYPDFFILES) $(GPTTEXFILES) ../../header.tex if test -f $(BASENAME).aux; then \ CHAPTER=$$(( $$(sed -n -e '/contentsline {chapter}/{s/.*numberline {\([0123456789]*\)}.*/\1/; p}' $(BASENAME).aux) - 1 )); \ PAGE=$$(sed -n -e '/contentsline {chapter}/{s/.*numberline {.*}.*}{\(.*\)}{chapter.*/\1/; p}' $(BASENAME).aux); \ diff --git a/header.tex b/header.tex index e13c850..fafdaa5 100644 --- a/header.tex +++ b/header.tex @@ -173,7 +173,7 @@ frame=single, caption={\protect\filename@parse{\lstname}\protect\filename@base}, captionpos=t, - xleftmargin=2.5em, + xleftmargin=21pt, xrightmargin=1mm, aboveskip=1ex, belowskip=2ex @@ -213,7 +213,7 @@ %%%%% code/matlab commands: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \usepackage{textcomp} -\newcommand{\varcode}[1]{\setlength{\fboxsep}{0.5ex}\colorbox{codeback}{\texttt{#1}}} +\newcommand{\varcode}[1]{\setlength{\fboxsep}{0.5ex}\colorbox{codeback}{\texttt{#1\protect\rule[-0.1ex]{0pt}{1.6ex}}}} \newcommand{\code}[2][]{\varcode{#2}\ifthenelse{\equal{#1}{}}{\protect\sindex[code]{#2}}{\protect\sindex[code]{#1}}} \newcommand{\matlab}{\texorpdfstring{MATLAB$^{\copyright}$}{MATLAB}} \newcommand{\matlabfun}[2][]{(\tr{\matlab-function}{\matlab-Funktion} \setlength{\fboxsep}{0.5ex}\colorbox{codeback}{\texttt{#2}})\ifthenelse{\equal{#1}{}}{\protect\sindex[code]{#2}}{\protect\sindex[code]{#1}}} @@ -290,11 +290,13 @@ \newenvironment{ibox}[2][tp] {\SetupFloatingEnvironment{iboxf}{placement=#1}% \begin{iboxf}% - \captionsetup{singlelinecheck=off,labelfont={large,sf,it,bf},font={large,sf,it,bf}} + \captionsetup{singlelinecheck=off,labelfont={large,sf,it,bf},font={large,sf,it,bf}}% \begin{mdframed}[linecolor=infoline,linewidth=1ex,% backgroundcolor=infoback,font={\sffamily},% frametitle={\caption{#2}},frametitleaboveskip=-1ex,% - frametitlebackgroundcolor=infoline]}% + frametitlebackgroundcolor=infoline]% + \setlength{\parindent}{0pt}\setlength{\parskip}{1ex}% + \captionsetup{singlelinecheck=off,labelfont={normalsize,sf,bf},font={normalsize,sf}}}% {\end{mdframed}% \end{iboxf}} @@ -319,11 +321,13 @@ {\captionsetup{singlelinecheck=off,hypcap=false,labelformat={empty},labelfont={large,sf,it,bf},font={large,sf,it,bf}} \ifthenelse{\equal{#1}{}}% {\begin{mdframed}[linecolor=importantline,linewidth=1ex,% - backgroundcolor=importantback,font={\sffamily}]}% + backgroundcolor=importantback,font={\sffamily}]% + \setlength{\parindent}{0pt}\setlength{\parskip}{1ex}}% {\begin{mdframed}[linecolor=importantline,linewidth=1ex,% backgroundcolor=importantback,font={\sffamily},% frametitle={\captionof{iboxf}{#1}},frametitleaboveskip=-1ex,% - frametitlebackgroundcolor=importantline]}% + frametitlebackgroundcolor=importantline]% + \setlength{\parindent}{0pt}\setlength{\parskip}{1ex}}% }% {\end{mdframed}} diff --git a/plotting/lecture/plotting-chapter.tex b/plotting/lecture/plotting-chapter.tex index 7498863..9383d63 100644 --- a/plotting/lecture/plotting-chapter.tex +++ b/plotting/lecture/plotting-chapter.tex @@ -16,5 +16,13 @@ \input{plotting} +\section{TODO} +\begin{itemize} +\item Beispiele schlechter plots sollten mehr Bezug zu den Typen von + plots haben, die wir machen! +\item subplot +\item Uebersicht zu wichtigen plot Befehlen (plot, scatter, bar, step, ...) +\end{itemize} + \end{document} diff --git a/pointprocesses/lecture/pointprocessscetch.gpt b/pointprocesses/lecture/pointprocessscetch.gpt index a758639..4579ff8 100644 --- a/pointprocesses/lecture/pointprocessscetch.gpt +++ b/pointprocesses/lecture/pointprocessscetch.gpt @@ -1,4 +1,4 @@ -set term epslatex size 11.4cm, 7cm +set term epslatex size 11.4cm, 6.5cm set out 'pointprocessscetch.tex' set border 0 diff --git a/programming/code/facultyWhileLoop.m b/programming/code/facultyWhileLoop.m index 8f718d1..f75ff8f 100644 --- a/programming/code/facultyWhileLoop.m +++ b/programming/code/facultyWhileLoop.m @@ -3,5 +3,6 @@ counter = 1; x = 1; while counter <= n x = x * counter; + counter = counter + 1 end -fprintf('Faculty of %i is: %i\n', n, x) \ No newline at end of file +fprintf('Faculty of %i is: %i\n', n, x) diff --git a/programming/code/ifelse.m b/programming/code/ifelse.m index 94de3d6..1d689f4 100644 --- a/programming/code/ifelse.m +++ b/programming/code/ifelse.m @@ -3,18 +3,16 @@ if x < 0.5 disp('x is less than 0.5'); end - if x < 0.5 disp('x is less than 0.5!'); else disp('x is greater than or equal to 0.5!') end - if x < 0.5 disp('x is less than 0.5!'); elseif x < 0.75 disp('x is greater than 0.5 but less than 0.75!'); else disp('x is greater than or equal to 0.75!') -end \ No newline at end of file +end diff --git a/programming/code/logicalIndexingTime.m b/programming/code/logicalIndexingTime.m index 5135f2d..7bde023 100644 --- a/programming/code/logicalIndexingTime.m +++ b/programming/code/logicalIndexingTime.m @@ -1,12 +1,12 @@ t = 0:0.001:10; x = randn(size(t)); -selection = x (t > 5 & t < 6); +selection = x(t > 5 & t < 6); figure() hold on plot(t, x, 'displayname', 'measurements') plot(t(t > 5 & t < 6), selection, 'displayname', 'selection') -xlabel('time [s]') -ylabel('intensity') +xlabel('Time [s]') +ylabel('Intensity') legend 'show' -box 'off' \ No newline at end of file +box 'off' diff --git a/programming/code/logicalVector.out b/programming/code/logicalVector.out index 950933a..14b5afb 100644 --- a/programming/code/logicalVector.out +++ b/programming/code/logicalVector.out @@ -1,12 +1,10 @@ >> logicalVector Logischer Vektor y: - y = 1 1 1 1 0 0 0 0 0 0 Datentyp von y: logical Alle Elemente aus x, die kleiner als 5 sind: - ans = 1 2 3 4 diff --git a/programming/code/vectorsize.m b/programming/code/vectorsize.m index 716a943..6a464f3 100644 --- a/programming/code/vectorsize.m +++ b/programming/code/vectorsize.m @@ -1,14 +1,3 @@ -a = (11:20); % a vector with 10 Elements -fprintf('length of a: %i\n', length(a)) -size_of_a = size(a); % get the size and store it in a new variable - -% size_of_a is a vector itself -fprintf('number of dimensions (rank) of size_of_a: %i\n', length(size_of_a)) - -% get the value of the second element of size_of_a -fprintf('number of entries in the 2nd dimesion of a: %i\n', size_of_a(2)) - -%% Uebersichtliche Alternative? -s = size(a); % Speicher den Rueckgabewert von size() in einer Variablen -s(2) % Inhalt der zweiten Zahl, d.h. Laenge der 2. Dimension -size(a,2) % Kurze Alternative +s = size(a) % Speicher den Rueckgabewert von size() in einer Variablen +s(2) % Inhalt der zweiten Zahl, d.h. Laenge der 2. Dimension +size(a,2) % Die kurze Alternative diff --git a/programming/code/vectorsize.out b/programming/code/vectorsize.out index c848de2..429d61e 100644 --- a/programming/code/vectorsize.out +++ b/programming/code/vectorsize.out @@ -1,4 +1,3 @@ ->> vectorsize -length of a: 10 -number of dimensions (rank) of size_of_a: 2 -number of entries in the 2nd dimesion of a: 10 \ No newline at end of file +s = 1 10 +ans = 10 +ans = 10 diff --git a/programming/lecture/programming-chapter.tex b/programming/lecture/programming-chapter.tex index 62fce49..4ace8b1 100644 --- a/programming/lecture/programming-chapter.tex +++ b/programming/lecture/programming-chapter.tex @@ -7,8 +7,8 @@ \typein[\pagenumber]{Number of first page} \typein[\chapternumber]{Chapter number} -\setcounter{page}{3} -\setcounter{chapter}{0} +\setcounter{page}{\pagenumber} +\setcounter{chapter}{\chapternumber} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -16,5 +16,21 @@ \input{programming} +\section{TODO} +\begin{itemize} +\item Ausgabeformat: \varcode{format} ? +\item Boolescher Ausdruck: ist doch eigentlich boolescher Ausdruck! +\item Expliziter die \varcode{(a:b:c)} Notation einf\"uhren! +\item Mathematische Funktionen sin(), cos(), exp() +\item Rundungsfunktionen round(), floor(), ceil() +\item Zeitvektoren, deltat, Umrechnung Zeit und Index. +\item Matrizen erstmal 2-D und nur kurz n-D +\item Zusammenfassung von Fehlermeldungen bezueglich Matrizen und Vektoren +\item Random-walk behutsam mit einer Schleife, dann zwei Schleifen. Plus Bildchen. +\item Doppelte for-Schleife +\item File output and input (load, save, fprintf, scanf) (extra chapter?) +\item help() und doc() +\end{itemize} + \end{document} diff --git a/programming/lecture/programming.tex b/programming/lecture/programming.tex index b94ab30..f4390fc 100644 --- a/programming/lecture/programming.tex +++ b/programming/lecture/programming.tex @@ -1,15 +1,16 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\chapter{\tr{Programming basics}{Programmierung in \matlab}} +\chapter{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 +Eine \determ{Variable} ist ein Zeiger auf eine Stelle im +Speicher. Dieser Zeiger hat einen Namen, den Variablennamen, und einen +\determ{Datentyp} (Abbildung \ref{variablefig}). Im Speicher wird der +Wert der Variablen bin\"ar als eine Folge von \determ[Bit]{Bits} (0 +oder 1) 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 @@ -39,37 +40,59 @@ befassen. \subsection{Erzeugen von Variablen} In \matlab{} kann eine Variable auf der Kommandozeile, in einem Skript oder einer Funktion an beliebiger Stelle erzeugt werden. Listing -\ref{varListing1} zeigt zwei M\"oglichkeiten dies zu tun: +\ref{varListing1} zeigt drei Beispiele: \begin{lstlisting}[label=varListing1, caption={Erzeugen von Variablen.}] - >> y = [] - y = - [] - >> - >> x = 38 - x = - 38 +>> x = 38 +x = + 38 + +>> y = [] +y = + [] + +>> z = 'A' +z = + A \end{lstlisting} Die Zeile 1 kann etwa so gelesen werden:''Erzeuge eine Variable mit -dem Namen y und weise ihr einen leeren Wert zu''. Das +dem Namen \varcode{x} und weise ihr den Wert 38 zu''. Das Gleichheitszeichen ist der sogenannte -\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. +\codeterm{Zuweisungsoperator}. Zeile 5 definiert eine Variable \varcode{y}, der +ein leerer Wert zugewiesen wird. Da \matlab{}, wenn nicht anders +angegeben, immer den \codeterm{double} Datentypen benutzt, haben beide +Variablen diesen Datentyp. In Zeile 9 wird der Variablen \varcode{z} der Buchstabe +``A'' zugewiesen. \varcode{z} nicht ein Flie{\ss}kommazahl von Typ \codeterm{double}, +sondern ein \codeterm{character} (Zeichen). + +Der Datentyp einer Variable kann mit \code{class()} abgefragt werden. +Eine Liste aller definierten Variablen gibt \code{who} +zur\"uck. Detailliertere Informationen \"uber Variablen zeigt +\code{whos} an. \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 +>>class(x) +ans = + double + +>> who +Your variables are: + +x y z + +>> whos + Name Size Bytes Class Attributes + + x 1x1 8 double + y 0x0 0 double + z 1x1 2 char \end{lstlisting} \begin{important}[Namen von Variablen] Bei der Namensgebung ist zu beachten, dass \matlab{} auf Gro{\ss}- - und Kleinschreibung achtet und ein Variablennane mit einem - alphabetischen Zeichen beginnen muss. Des Weiteren sind Umlaute, - Sonder- und Leerzeichen in Variablennamen nicht erlaubt. + und Kleinschreibung achtet und ein Variablenname mit einem + alphabetischen Zeichen beginnen muss. Umlaute, Sonder- und + Leerzeichen sind in Variablennamen nicht erlaubt. \end{important} \subsection{Arbeiten mit Variablen} @@ -84,40 +107,39 @@ werden. \matlab{} kennt alle normalen Dachsymbol \code[Operator!arithmetischer!5pow@\^{}]{\^{}} dargestellt. Listing \ref{varListing3} zeigt, wie sie benutzt werden. +\pagebreak[4] \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 +>> 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 % loesche die Variable z \end{lstlisting} -Beachtenswert ist z.B. in Zeilen 3 und 6, dass mit dem Inhalt einer +Beachtenswert ist in Zeilen 2 und 6, dass mit dem Inhalt einer Variablen gerechnet werden kann, ohne dass dadurch ihr Wert ver\"andert wird. Wenn der Wert einer Variablen ver\"andert werden -soll, dann muss der Variable der neue Wert explizit zugewiesen werden +soll, dann muss der neue Wert explizit einer Variablen zugewiesen werden (mit dem \code[Operator!Zuweisung!=]{=} Zuweisungsoperator, -z.B. Zeilen 16, 20). Zeile 25 zeigt wie eine einzelne Variable +z.B. Zeilen 14 und 18). Zeile 23 zeigt wie eine einzelne Variable gel\"oscht wird. @@ -126,30 +148,32 @@ gel\"oscht wird. Der Datentyp bestimmt, wie die im Speicher abgelegten Bitmuster interpretiert werden. Die wichtigsten Datentpyen sind: \begin{itemize} -\item \codeterm{integer} - Ganze Zahlen. Hier gibt es mehrere +\item \codeterm{integer}: Ganze Zahlen. Hier gibt es mehrere Unterarten, die wir in \matlab{} (meist) ignorieren k\"onnen. -\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 +\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 \codeterm{char} - ASCII Zeichen +\item \codeterm{char}: ASCII Zeichen \end{itemize} Unter den numerischen Datentypen gibt es verschiedene Arten mit -unterschiedlichem Speicherbedarf und Wertebreich. +unterschiedlichem Speicherbedarf und Wertebreich (siehe +Tabelle~\ref{dtypestab}). -\begin{table}[!h] +\begin{table}[t] \centering \titlecaption{Grundlegende numerische Datentypen und ihr Wertebereich.}{} \label{dtypestab} \begin{tabular}{llcl}\hline Datentyp & Speicherbedarf & Wertebereich & Beispiel \erh \\ \hline - double & 64 bit & $\approx -10^{308}$ bis $\approx 10^{308} $& Flie{\ss}kommazahlen.\erb\\ - int & 64 bit & $-2^{31}$ bis $2^{31}-1$ & Ganzzahlige Werte \\ - int16 & 16 bit & $-2^{15}$ bis $2^{15}-1$ & Digitalisierte Spannungen. \\ - uint8 & 8 bit & $0$ bis $255$ & Digitalisierte Imaging Daten. \\ \hline + \code{double} & 64 bit & $\approx -10^{308}$ bis $\approx 10^{308} $& Flie{\ss}kommazahlen.\erb\\ + \code{int} & 64 bit & $-2^{31}$ bis $2^{31}-1$ & Ganzzahlige Werte \\ + \code{int16} & 16 bit & $-2^{15}$ bis $2^{15}-1$ & Digitalisierte Spannungen. \\ + \code{uint8} & 8 bit & $0$ bis $255$ & Digitalisierte Imaging Daten. \\ \hline \end{tabular} \end{table} -\matlab{} arbeitet meist mit dem ``double'' Datentyp wenn numerische + +\matlab{} arbeitet meist mit dem \codeterm{double} Datentyp wenn numerische Daten gespeichert werden. Dennoch lohnt es sich, sich ein wenig mit den Datentypen auseinanderzusetzen (Box \ref{daqbox}). @@ -180,8 +204,8 @@ den Datentypen auseinanderzusetzen (Box \ref{daqbox}). \end{minipage}\vspace{0.25cm} Um Speicherplatz zu sparen ist es sinnvoll, die gemessenen Daten als - ``int16'' anstelle der ``double'' Werte im Rechner abzulegen. Die - Daten als ``echte'' Spannungen, also als Flie{\ss}kommawerte, + \code{int16} anstelle der \code{double} Werte im Rechner abzulegen. Die + Daten als Spannungswerte, also als Flie{\ss}kommawerte, abzulegen ben\"otigt den 4-fachen Speicherplatz (8 statt 2 Bytes) und bietet keine zus\"atzliche Information. \end{ibox} @@ -216,61 +240,69 @@ enth\"alt im Beispiel in Abbildung \ref{vectorfig} vier ganzzahlige Werte. (columnvector).}\label{vectorfig} \end{figure} -Das folgende Listing \ref{arrayListing1} zeigt, wie einfache Vektoren erstellt werden -k\"onnen. - -\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 +Das folgende Listing \ref{generatevectorslisting} zeigt, wie Vektoren erstellt +werden k\"onnen. + +\begin{lstlisting}[label=generatevectorslisting, 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} Die L\"ange eines Vektors, d.h. die Anzahl der Elemente des Vektors, -kann mithilfe der Funktionen \code{length()} und \code{numel()} bestimmt -werden. \"Ahnliche Information kann \"uber die Funktion \code{size()} -erhalten werden (Listing \ref{arrayListing2}). Im Falle des Vektors -\varcode{a} von oben erh\"alt man folgende Ausgabe: - -\begin{lstlisting}[label=arrayListing2, caption={Gr\"o{\ss}e von Vektoren.}] - >> length(a) - ans = - 10 - >> size(a) - ans = - 1 10 +kann mithilfe der Funktionen \code{length()} und \code{numel()} +bestimmt werden. \"Ahnliche Information kann \"uber die Funktion +\code{size()} erhalten werden (Listing \ref{vectorsizeslisting}). Der +Vektor \varcode{a} von oben hat folgende Gr\"o{\ss}en: + +\begin{lstlisting}[label=vectorsizeslisting, caption={Gr\"o{\ss}e von Vektoren.}] +>> length(a) +ans = + 10 + +>> size(a) +ans = + 1 10 \end{lstlisting} -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()]{length(a)} gibt die l\"angste Ausdehnung an. Der \code[Operator!Matrix!']{'}- -Operator transponiert den Spaltenvektor zu einem Zeilenvektor (Zeilen 14 ff.). - - -\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 +Die Ausgabe der \code{size()}-Funktion zeigt, dass Vektoren im Grunde +2-dimensional sind. Bei einem Zeilenvektor hat die erste Dimension die +Gr\"o{\ss}e 1. \code[length()]{length(a)} gibt die l\"angste +Ausdehnung an. Im folgenden Listing \ref{columnvectorlisting} transponiert der +\code[Operator!Matrix!']{'} - Operator einen Spaltenvektor +zu einem Zeilenvektor (Zeilen 14 ff.). + +\begin{lstlisting}[label=columnvectorlisting, 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 +b = + 1 2 3 4 5 6 7 8 9 10 + +>> size(b) +ans = + 1 10 \end{lstlisting} @@ -278,7 +310,8 @@ Operator transponiert den Spaltenvektor zu einem Zeilenvektor (Zeilen 14 ff.). \begin{figure} \includegraphics[width=0.4\columnwidth]{arrayIndexing} \titlecaption{Indices von Vektoren.}{Jedes Feld eines Vektors hat - einen Index mit dem auf den jeweiligen Inhalt zugegriffen werden + einen Index (kleine Zahl) mit dem auf den jeweiligen Inhalt + (gro{\ss}e Zahl) zugegriffen werden kann.}\label{vectorindexingfig} \end{figure} @@ -287,158 +320,242 @@ Der Zugriff auf die Inhalte eines Vektors erfolgt \"uber den Index 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. + \begin{important}[Indizieren] - Anders als viele andere Programmiersprachen beginnt \matlab{} mit - dem Index 1 an zu z\"ahlen. Der Zugriff auf Inhalte eines Vektors - mittels seines Indexes wird Indizieren genannnt. + Der Zugriff auf Inhalte eines Vektors mittels seines Indexes wird + Indizieren genannnt. + + Der Index des ersten Elements eines Vektors ist in \matlab{} die Eins. + + Der Index des letzten Elements entspricht der L\"ange des Vektors. \end{important} -Die Listings \ref{arrayListing4} und \ref{arrayListing5} zeigen wie + +Die Listings \ref{vectorelementslisting} und \ref{vectorrangelisting} zeigen wie mit Indexen auf die Inhalte eines Vektors zugegriffen werden kann. +Hierbei kann auf einzelne Werte zugegriffen werden oder, analog zur +Erzeugung von Vektoren, die \code[Operator!Matrix!:]{:} Notation +verwendet werden, um auf mehrere Element gleichzeitig zuzugreifen. -\begin{lstlisting}[label=arrayListing4, caption={Zugriff auf den Inhalt von Vektoren: einzelne Elemente}] - >> a = (11:20) - a = 11 12 13 14 15 16 17 18 19 20 - >> a(1) % das 1. Element - ans = 11 - >> a(5) % das 5. Element - ans = 15 - >> a(end) % das letzte Element - ans = 20 +\begin{lstlisting}[label=vectorelementslisting, caption={Zugriff auf den Inhalt von Vektoren: einzelne Elemente}] +>> a = (11:20) +a = + 11 12 13 14 15 16 17 18 19 20 + +>> a(1) % das 1. Element +ans = 11 + +>> a(5) % das 5. Element +ans = 15 + +>> a(end) % das letzte Element +ans = 20 \end{lstlisting} -Hierbei kann auf einzelne Werte zugegriffen werden oder, analog zur -Erzeugung von Vektoren, die \code[Operator!Matrix!:]{:} Notation verwendet werden, um auf mehrere -Element gleichzeitig zuzugreifen. - -\begin{lstlisting}[caption={Zugriff auf den Inhalt von Vektoren: Bereiche}, label=arrayListing5] - >> a([1 3 5]) % das 1., 3. und 5. Element - ans = - 11 13 15 - >> a(2:4) % alle Elemente von Index 2 bis einschliesslich 4 - ans = - 12 13 14 - >> a(1:2:end) % jedes zweite Element - ans = - 11 13 15 17 19 - >> a(:) % alle Elemente - ans = - 11 12 13 14 15 16 17 18 19 20 +\begin{lstlisting}[caption={Zugriff auf den Inhalt von Vektoren: Bereiche}, label=vectorrangelisting] +>> a([1 3 5]) % das 1., 3. und 5. Element +ans = + 11 13 15 + +>> a(2:4) % alle Elemente von Index 2 bis einschliesslich 4 +ans = + 12 13 14 + +>> a(1:2:end) % jedes zweite Element +ans = + 11 13 15 17 19 + +>> a(:) % alle Elemente als Zeilenvektor +ans = + 11 12 13 14 15 16 17 18 19 20 \end{lstlisting} \begin{exercise}{vectorsize.m}{vectorsize.out} Der R\"uckgabewert von \code[size()]{size(a)} ist wieder ein Vektor der - L\"ange 2. Wie k\"onnte man also die Gr\"o{\ss}e von \varcode{a} in der - zweiten Dimension herausfinden? + L\"ange 2. Wie k\"onnte also die Gr\"o{\ss}e von \varcode{a} in der + zweiten Dimension herausgefunden werden? \end{exercise} \subsubsection{Operationen auf Vektoren} Mit Vektoren kann sehr einfach gerechnet werden. Listing -\ref{arrayListing6} zeigt Rechnungen mit Vektoren. - -\begin{lstlisting}[caption={Rechnen mit Vektoren.},label=arrayListing6] - >> 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 % Multiplikation - 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. +\ref{vectorscalarlisting} zeigt die Verrechnung von Vektoren mit Skalaren +mit den Operatoren \code[Operator!arithmetischer!1add@+]{+}, +\code[Operator!arithmetischer!2sub@-]{-}, +\code[Operator!arithmetischer!3mul@*]{*}, +\code[Operator!arithmetischer!4div@/]{/} +\code[Operator!arithmetischer!5pow@.\^{}]{.\^}. + +\begin{lstlisting}[caption={Rechnen mit Vektoren und Skalaren.},label=vectorscalarlisting] +>> a = (0:2:8) +a = + 0 2 4 6 8 + +>> a + 5 % Addition von einem Skalar +ans = + 5 7 9 11 13 + +>> a - 5 % Subtraktion von einem Skalar +ans = + -5 -3 -1 1 3 + +>> a * 2 % Multiplikation mit einem Skalar +ans = + 0 4 8 12 16 + +>> a / 2 % Division mit einem Skalar +ans = + 0 1 2 3 4 + +>> a .^ 2 % Potenzierung mit einem Skalar +ans = + 0 4 16 36 64 \end{lstlisting} -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 mu{\ss} mit vorangestellem '.' -klar gemacht werden, dass es sich um eine \emph{elementweise} -Verarbeitung handeln soll. F\"ur diese elementweisen Operationen kennt -\matlab{} die Operatoren \code[Operator!arithmetischer!3mule@.*]{.*}, +Bei der elementweisen Verrechnung von zwei Vektoren muss +sichergestellt werden, dass sie die gleiche L\"ange und das gleiche +Layout (Spalten- oder Zeilenvektor) haben. Addition und Subtraktion +erfolgt immer elementweise (Listing~\ref{vectoradditionlisting}). + +\begin{lstlisting}[caption={Elementweise Addition und Subtraktion von + Vektoren.},label=vectoradditionlisting] +>> a = [4 9 12]; +>> b = [4 3 2]; +>> a + b % Addition von 2 Vektoren +ans = + 8 12 14 + +>> a - b % Subtraktion von 2 Vektoren +ans = + 0 6 10 + +>> c = [8 4]; +>> a + c % Beide Vektoren muessen gleich gross sein! +Error using + +Matrix dimensions must agree. +>> d = [8; 4; 2]; +>> a + d % Beide Vektoren muessen das gleiche Layout haben! +Error using + +Matrix dimensions must agree. +\end{lstlisting} + +Bei der Multiplikation, der Division und der Potenzierung mu{\ss} mit +vorangestellem '.' angezeigt werden, dass es sich um eine +\emph{elementweise} Verarbeitung handeln soll. F\"ur diese +elementweisen Operationen kennt \matlab{} die Operatoren +\code[Operator!arithmetischer!3mule@.*]{.*}, \code[Operator!arithmetischer!4dive@./]{./} und -\code[Operator!arithmetischer!5powe@.\^{}]{.\^{}}. Die einfachen Operatoren -\code[Operator!arithmetischer!3mul@*]{*}, -\code[Operator!arithmetischer!4div@/]{/} und -\code[Operator!arithmetischer!5pow@\^{}]{\^{}} sind mit den entsprechenden -Matrixoperationen aus der linearen Algebrar belegt (Box -\ref{matrixmultiplication}). +\code[Operator!arithmetischer!5powe@.\^{}]{.\^{}} +(Listing~\ref{vectorelemmultiplicationlisting}). -Zu Beachten ist des Weiteren noch die Fehlermeldung am Schluss von -Listing \ref{arrayListing6}. Wenn zwei Vektoren (elementweise) -miteinander verrechnet werden sollen, muss nicht nur die Anzahl der Elemente -\"ubereinstimmen, sondern es muss auch das Layout (Zeilen- oder -Spaltenvektoren) \"ubereinstimmen. +\begin{lstlisting}[caption={Elementweise Multiplikation, Division und + Potenzierung von Vektoren.},label=vectorelemmultiplicationlisting] +>> a .* b % Elementweise Multiplikation +ans = + 16 27 24 +>> a ./ b % Elementweise Division +ans = + 1 3 6 -Will man Elemente aus einem Vektor entfernen, dann weist man den -entsprechenden Zellen einen leeren Wert (\code[Operator!Matrix!{[]}]{[]}) zu. +>> a ./ b % Elementweise Potenzierung +ans = + 256 729 144 + +>> a .* c % Beide Vektoren muessen gleich gross sein! +Error using .* +Matrix dimensions must agree. +>> a .* d % Beide Vektoren muessen das gleiche Layout haben! +Error using .* +Matrix dimensions must agree. +\end{lstlisting} -\begin{lstlisting}[label=arrayListing7, caption={L\"oschen von Elementen aus einem Vektor.}] - >> a = (0:2:8); - >> length(a) - ans = - 5 +Die einfachen Operatoren \code[Operator!arithmetischer!3mul@*]{*}, +\code[Operator!arithmetischer!4div@/]{/} und +\code[Operator!arithmetischer!5pow@\^{}]{\^{}} sind mit den +entsprechenden Matrixoperationen aus der linearen Algebrar belegt (Box +\ref{matrixmultiplication}). Insbesondere ist die Multiplikation eines +Zeilenvektors $\vec a$ mit einem Spaltenvektor $\vec b$ das Skalarprodukt +$\sum_i = a_i b_i$. + +\begin{lstlisting}[caption={Multiplikation von Vektoren.},label=vectormultiplicationlisting] +>> a * b % Multiplikation zweier Zeilenvektoren +Error using * +Inner matrix dimensions must agree. +>> a' * b' % Multiplikation zweier Spaltenvektoren +Error using * +Inner matrix dimensions must agree. + +>> a * b' % Multiplikation Zeilenvektor mit Spaltenvektor +ans = + 67 - >> a(1) = [] % loesche das erste Element - a = 2 4 6 8 +>> a' * b % Multiplikation Spaltenvektor mit Zeilenvektor +ans = + 16 12 8 + 36 27 18 + 48 36 24 +\end{lstlisting} + +\pagebreak[4] +Zum Entfernen von Elementen aus einem Vektor, wird den +entsprechenden Zellen ein leeren Wert (\code[Operator!Matrix!{[]}]{[]}) zugewiesen: +\begin{lstlisting}[label=vectoreraselisting, caption={L\"oschen von Elementen aus einem Vektor.}] +>> a = (0:2:8); +>> length(a) +ans = 5 - >> a([1 3]) = [] - a = 4 8 +>> a(1) = [] % loesche das erste Element +a = 2 4 6 8 - >> length(a) - ans = - 2 +>> a([1 3]) = [] % loesche das erste und dritte Element +a = 4 8 + +>> length(a) +ans = 2 \end{lstlisting} Neben dem L\"oschen von Vektorinhalten k\"onnen Vektoren auch -erweitert oder zusammengesetzt werden. Auch hier muss das Layout der Vektoren -\"ubereinstimmen (Listing \ref{arrayListing8}, Zeile 12). Will man -einen Vektor erweitern, kann man \"uber das Ende hinaus -zuweisen. \matlab{} erweitert dann die Variable. Dieser Vorgang ist -``rechenintensiv'' und sollte, soweit m\"oglich, vermieden werden. - -\begin{lstlisting}[caption={Zusammenf\"ugen und Erweitern von Vektoren.}, label=arrayListing8] - >> 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]; - In an assignment A(:) = B, the number of elements in A and B must be the same. +erweitert oder zusammengesetzt werden. Auch hier muss das Layout der +Vektoren \"ubereinstimmen (Listing \ref{vectorinsertlisting}, Zeile +10). Zum Erweitern eines Vektors kann \"uber das Ende hinaus +zugewiesen werden (Zeile 20). \matlab{} erweitert dann die Variable +entsprechend. Dieser Vorgang ist rechenintensiv da der ganze Vektor +an eine neue Stelle im Arbeitsspeicher kopiert wird und sollte, soweit +m\"oglich, vermieden werden. + +\begin{lstlisting}[caption={Zusammenf\"ugen und Erweitern von Vektoren.}, label=vectorinsertlisting] +>> a = [4 3 2 1]; +>> b = [10 12 14 16]; +>> c = [a b] % erstelle einen Vektor aus einer Liste von Vektoren +c = + 4 3 2 1 10 12 14 16 +>> length(c) +ans = 8 +>> length(a) + length(b) +ans = 8 +>> c = [a b']; % Vektorlayout muss uebereinstimmen +Error using horzcat +Dimensions of matrices being concatenated are not consistent. + +>> a(1:3) = [5 6 7] % Weise den ersten drei Elementen neue Werte zu +a = + 5 6 7 1 +>> a(1:3) = [1 2 3 4]; % Laenge der Vektoren muss uebereinstimmen +In an assignment A(I) = B, the number of elements in B and I must be the same. + +>> a(3:6) = [1 2 3 4] % Zuweisung ueber die Laenge des Vektors hinweg +a = + 5 6 1 2 3 4 \end{lstlisting} \subsection{Matrizen} -Im Gegesatz zu den 1-dimensionalen Vektoren k\"onnen Martizen -n-dimensional sein, das hei{\ss}t, dass sie beliebig viele Dimensionen -haben k\"onnen. Von praktischer Bedeutung sind allerdings nur Matrizen -mit bis zu vier Dimensionen. Meist beschr\"ankt es sich jedoch auf 2- -bis 3-d Matrizen (Abbildung \ref{matrixfig} A,B). +Vektoren sind 1-dimensionale Spezialf\"alle von $n$-dimensionalen +Matrizen. Matrizen k\"onnen in \matlab{} beliebig viele Dimensionen +haben. Von praktischer Bedeutung sind allerdings nur Matrizen mit bis +zu vier Dimensionen. Meist beschr\"ankt es sich jedoch auf 2- bis 3-d +Matrizen (Abbildung \ref{matrixfig} A,B). \begin{figure} \includegraphics[width=0.5\columnwidth]{matrices} @@ -451,41 +568,37 @@ bis 3-d Matrizen (Abbildung \ref{matrixfig} A,B). Erzeugt werden Matrizen sehr \"ahnlich zu den Vektoren (Listing \ref{matrixListing}). Die Definition einer Matrize wird, wie beim Vektor, durch \code[Operator!Matrix!{[]}]{[]} eingeschlossen. Das -\code[Operator!Matrix!;]{;} trennt die einzelnen Zeilen der +Semikolon \code[Operator!Matrix!;]{;} trennt die einzelnen Zeilen der Matrize. \begin{lstlisting}[label=matrixListing, caption={Erzeugen von Matrizen.}] - >> a = [1 2 3; 4 5 6; 7 8 9] - >> a = - 1 2 3 - 4 5 6 - 7 8 9 - >> - >> b = ones(3,3,2); - >> b - - b(:,:,1) = - 1 1 1 - 1 1 1 - 1 1 1 - - b(:,:,2) = - 1 1 1 - 1 1 1 - 1 1 1 +>> a = [1 2 3; 4 5 6; 7 8 9] +>> a = +1 2 3 +4 5 6 +7 8 9 + +>> b = ones(3, 4, 2) +b(:,:,1) = + 1 1 1 1 + 1 1 1 1 + 1 1 1 1 +b(:,:,2) = + 1 1 1 1 + 1 1 1 1 + 1 1 1 1 \end{lstlisting} Zur Defintion von mehr-dimensionalen Matrizen ist die Notation in Zeile 1 nicht geeignet. Es gibt allerdings eine Reihe von -Helferfunktionen, die n-dimensionale Matrizen erstellen k\"onnen -(z.B. \code{ones()}, Zeile 7). Sollte sich die Notwendigkeit ergeben -mehrdimensionale Matrizen zusammenzuf\"ugen hilft die \code{cat()} -Funktion. +Helferfunktionen, die $n$-dimensionale Matrizen erstellen k\"onnen +(z.B. \code{ones()}, Zeile 7). Die \code{cat()}-Funktion kann +mehrdimensionale Matrizen zusammenzuf\"ugen. Um Informationen \"uber die Gr\"o{\ss}e einer Matrize zu bekommen ist die Funktion \code{length()} nicht geeignet. Wie oben erw\"ahnt gibt sie -die Gr\"o{\ss}e der l\"angsten Dimension aus. Wann immer es um -Matrizen geht, wird \code{size()} benutzt. +die Gr\"o{\ss}e der l\"angsten Dimension aus. Die \code{size()}-Funktion +gibt dagegen die L\"ange jeder Dimension als Vektor zur\"uck. \begin{figure} \includegraphics[width=0.9\columnwidth]{matrixIndexing} @@ -503,40 +616,46 @@ 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 -\codeterm{subscript indexing} genannt. +\codeterm{subscript indexing} genannt. Dabei bestimmt die errste Zahl +die Zeilennumer, die zweite die Splatennumer. \begin{lstlisting}[caption={Zugriff auf Inhalte von Matrizen, Indizierung.}, label=matrixIndexing] - >> x = randi(100, [3, 4, 5]); % 3-D Matrix mit Zufallszahlen - >> size(x) - ans = - 3 4 5 - >> x(1,1,1); % obere linke Ecke - ans(1,1,1) = - 14 - >> - >> x(1,1,:) % obere linke Ecke entlang der 3. Dimension - ans(1,1,:) = - 14 - ans(:,:,2) = - 58 - ans(:,:,3) = - 4 - ans(:,:,4) = - 93 - ans(:,:,5) = - 56 +>> x=rand(3,4) % 2-D Matrix mit Zufallszahlen mit 3 Zeilen und 4 Spalten +x = + 0.8147 0.9134 0.2785 0.9649 + 0.9058 0.6324 0.5469 0.1576 + 0.1270 0.0975 0.9575 0.9706 +>> size(x) +ans = + 3 4 + +>> x(1,1) % obere linke Ecke +ans = + 0.8147 +>> x(2,3) % Element der 2. Zeile, 3. Spalte +ans = + 0.5469 + +>> x(1,:) % erste Zeile +ans = + 0.8147 0.9134 0.2785 0.9649 +>> x(:,2) % zweite Spalte +ans = + 0.9134 + 0.6324 + 0.0975 \end{lstlisting} 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()]{numel(M)} -Elemente. Wobei dieser erst entlang der 1. Dimension, dann der 2., -3. etc. Dimension ansteigt. Listing \ref{matrixLinearIndexing} zeigt -ein Beispiel f\"ur den Einsatz des linearen Indizierens z.B. wenn man -den Minimalwert aller Elemente einer Matrize ermitteln m\"ochte. +so intuitiv verst\"andlich, kann aber sehr hilfreich sein. Der lineare +Index einer Zelle reicht von 1 bis \code{numel()} Elemente. Wobei +dieser erst entlang der 1. Dimension, dann der 2., 3. etc. Dimension +ansteigt. Listing \ref{matrixLinearIndexing} zeigt ein Beispiel f\"ur +den Einsatz des linearen Indizierens, z.B. zum Ermitteln des kleinsten +Wertes in einer Matrize. \begin{figure} \includegraphics[width=0.9\columnwidth]{matrixLinearIndexing} @@ -547,99 +666,99 @@ den Minimalwert aller Elemente einer Matrize ermitteln m\"ochte. \end{figure} \begin{lstlisting}[label=matrixLinearIndexing, caption={Lineares Indizieren in Matrizen.}] - >> x = randi(100, [3, 4, 5]); % 3-D Matrix mit Zufallszahlen - >> size(x) - ans = - 3 4 5 - >> numel(x) - ans = - 60 - >> min(min(min(x))) % Minumum uber die Zeilen, Spalten, Blaetter... - ans = - 4 - >> min(x(:)) % oder so - ans = - 4 +>> x = randi(100, [3, 4, 5]); % 3-D Matrix mit Zufallszahlen +>> size(x) +ans = +3 4 5 +>> numel(x) +ans = +60 +>> min(min(min(x))) % Minimum ueber die Zeilen, Spalten, Blaetter... +ans = +4 +>> min(x(:)) % oder so +ans = +4 \end{lstlisting} +\begin{ibox}[t]{\label{matrixmultiplication} Matrixmultiplikation.} + Die Matrixmuliplikation aus der linearen Algebra ist nicht eine + elementweise Multiplikation. Die Matrixmultiplikation ist nur dann + m\"oglich, wenn die Anzahl Spalten der ersten Matrize gleich der + Anzahl Zeilen in der zweiten Matrize ist. Formaler: zwei Matrizen + $\mathbf{A}$ und $\mathbf{B}$ k\"onnen mulipiziert $(\mathbf{A} + \cdot \mathbf{B})$ werden, wenn $\mathbf{A}$ die Gr\"o{\ss}e $(m \times n)$ und + $\mathbf{B}$ die Gr\"o{\ss}e $(n \times k)$ hat. Die Mulitplikation ist + m\"oglich wenn die \determ{inneren Dimensionen} $n$ gleich sind. + + Dann sind die Elemente $c_{i,j}$ des Matrixprodukts $\mathbf{C} = + \mathbf{A} \cdot \mathbf{B}$ gegeben durch das Skalarprodukt jeder + Zeile von $\mathbf{A}$ mit jeder Spalte aus $\mathbf{B}$: + \[ c_{i,j} = \sum_{k=1}^n a_{i,k} \; b_{k,j} \; . \] + + Die Matrixmultiplikation ist im Allgemeinen auch nicht kommutativ: + \[ \mathbf{A} \cdot \mathbf{B} \ne \mathbf{B} \cdot \mathbf{A} \; . \] + + Als Beispiel betrachten wir die beiden Matrizen + \[\mathbf{A}_{(3 \times 2)} = \begin{pmatrix} 1 & 2 \\ 5 & 4 \\ -2 & 3 \end{pmatrix} + \quad \text{und} \quad \mathbf{B}_{(2 \times 2)} = \begin{pmatrix} + -1 & 2 \\ -2 & 5 \end{pmatrix} \; . \] + F\"ur das Produkt $\mathbf{A} \cdot \mathbf{B}$ stimmen die inneren + Dimensionen der Matrizen \"uberein ($(3 \times 2) \cdot (2 + \times 2)$), die Matrixmultiplikation ist also m\"oglich. Nachdem + $\mathbf{A}$ drei Zeilen und $\mathbf{B}$ zwei Spalten hat, hat das + Ergebnis von $\mathbf{A} \cdot \mathbf{B}$ die Gr\"o{\ss}e $(3 + \times 2)$: + \[ \mathbf{A} \cdot \mathbf{B} = \begin{pmatrix} 1 \cdot -1 + 2 \cdot -2 & 1 \cdot 2 + 2\cdot 5 \\ + 5 \cdot -1 + 4 \cdot -2 & 5 \cdot 2 + 4 \cdot 5\\ + -2 \cdot -1 + 3 \cdot -2 & -2 \cdot 2 + 3 \cdot 5 \end{pmatrix} + = \begin{pmatrix} -5 & 12 \\ -13 & 30 \\ -4 & 11\end{pmatrix} \; . \] + + Das Produkt $\mathbf{B} \cdot \mathbf{A}$ ist dagegen nicht + definiert, da die inneren Dimensionen nicht \"ubereinstimmen + ($(2 \times 2) \cdot (3 \times 2)$). +\end{ibox} Beim Rechnen mit Matrizen gelten die gleichen Regeln wie bei Vektoren. Matrizen k\"onnen solange elementweise miteinander verrechnet werden, wie die Dimensionalit\"aten -\"ubereinstimmen. Besondere Vorsicht sollte man immer dann walten -lassen, wenn man Matrizen miteinander multiplizieren, dividieren oder -potenzieren will. Hier ist es wichtig sich klarzumachen was man will: -Eine elementweise Multiplikation +\"ubereinstimmen. Wichtig ist auch hier wieder die Unterscheidung +zwischen elementweiser Multiplikation (\code[Operator!arithmetischer!3mule@.*]{.*} Operator, Listing -\ref{matrixOperations} Zeile 18) oder ob eine Matrixmultiplikation +\ref{matrixOperations} Zeile 10) oder Matrixmultiplikation (\code[Operator!arithmetischer!3mul@*]{*} Operator, Listing -\ref{matrixOperations} Zeile 12, Box \ref{matrixmultiplication}) -durchgef\"uhrt werden soll. +\ref{matrixOperations} Zeile 14, 17 und 21, Box~\ref{matrixmultiplication}). +Bei der Matrixmultiplikation m\"ussen die inneren Dimensionen der Matrizen \"ubereinstimmen +(Box~\ref{matrixmultiplication}). +\pagebreak[4] \begin{lstlisting}[label=matrixOperations, caption={Zwei Arten der Multiplikation von Matrizen.}] - >> A = randi(10, [3, 3]) % 2-D Matrix - A = - 3 8 2 - 2 10 3 - 10 7 1 - >> B = randi(10, [3, 3]) % dto - B = - 2 1 7 - 1 5 9 - 5 10 5 - >> - >> A * B % Matrixmultiplikation - ans = - 24 63 103 - 29 82 119 - 32 55 138 - >> - >> A .* B % Elementweise Multiplikation - ans = - 6 8 14 - 2 50 27 - 50 70 5 -\end{lstlisting} - -\begin{ibox}[t]{\label{matrixmultiplication} Matrixmultiplikation.} - Die Matrixmuliplikation aus der linearen Algebra ist nicht eine - elementweise Multiplikation. Die Matrixmultiplikation ist nur - dann m\"oglich, wenn die Anzahl Spalten der ersten Matrize gleich - der Anzahl Zeilen in der zweiten Matrize ist. Formaler: zwei - Matrizen A, B k\"onnen mulipiziert $(A \cdot B)$ werden, wenn A die - Gr\"o{\ss}e $(m \times n)$ und B die Gr\"o{\ss}e $(n \times k)$ - hat. Die Mulitplikation ist m\"oglich wenn die ``inneren'' - Dimensionen $n$ gleich sind. Daraus - erkl\"art sich auch die folgende Fehlermeldung in \matlab{}: - \begin{lstlisting}[caption={Fehlermeldung bei Matrixmultiplikation}] ->> A = [1 2 3; 4 5 6]; ->> B = [2 4; 6 7]; ->> A * B +>> A = randi(5, [2, 3]) % 2-D Matrix +A = + 1 5 3 + 3 2 2 +>> B = randi(5, [2, 3]) % dito +B = + 4 3 5 + 2 4 5 + +>> A .* B % elementweise Multiplikation +ans = + 4 15 15 + 6 8 10 +>> A * B % Matrixmultiplikation Error using * -Inner matrix dimensions must agree. ->> size(A) +Inner matrix dimensions must agree. +>> A * B' % Matrixmultiplikation ans = - 2 3 ->> size(B) -ans = - 2 2 - \end{lstlisting} - - Als Beispiel betrachten wir die beiden Matrizen - \[A_{(3 \times 2)} = \begin{pmatrix} 1 & 2 \\ 5 & 4 \\ -2 & 3 \end{pmatrix} - \quad \text{und} \quad - B_{(2 \times 2)} = \begin{pmatrix} -1 & 2 \\ -2 & 5 \end{pmatrix} \; . \] - Die ``inneren'' Dimensionen der Matrizen stimmen \"uberein ($(3 - \times 2) \cdot (2 \times 2)$), die Matrixmultiplikation ist - also m\"oglich. Das Produkt wird aus dem Skalarprodukt - jeder Zeile von $A$ mit jeder Spalte aus $B$ berechnet. Nachdem - $A$ drei Zeilen und $B$ zwei Spalten hat, hat das Ergebnis von $A - \cdot B$ die Gr\"o{\ss}e $(3 \times 2)$: - \[A \cdot B = \begin{pmatrix} 1 \cdot -1 + 2 \cdot -2 & 1 \cdot 2 + 2\cdot 5 \\ - 5 \cdot -1 + 4 \cdot -2 & 5 \cdot 2 + 4 \cdot 5\\ - -2 \cdot -1 + 3 \cdot -2 & -2 \cdot 2 + 3 \cdot 5 \end{pmatrix} - = \begin{pmatrix} -5 & 12 \\ -13 & 30 \\ -4 & 11\end{pmatrix} \; . \] -\end{ibox} + 34 37 + 28 24 +>> A' * B % Matrixmultiplikation +ans = + 10 15 20 + 24 23 35 + 16 17 25 +\end{lstlisting} \section{Boolesche Operationen} @@ -654,99 +773,92 @@ Beziehung zwischen Entit\"aten zu testen. Hierzu werden die gleich und nicht) eingesetzt. Mehrere Ausdr\"ucke werden mittels der \codeterm[Operator!logischer]{logischen Operatoren} (\code[Operator!logischer!and1@\&]{\&}, \code[Operator!logischer!or1@{"|} {}]{|}, -UND, ODER ) verkn\"upft. Sie sind f\"ur uns nicht nur wichtig um +UND, ODER) verkn\"upft. Sie sind 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 Tabellen \ref{logicalandor} zeigen die -Wahrheitstabellen f\"ur das logische UND (Tabelle \ref{logicalandor}, -links) und das logische ODER (Tabelle \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 Tabellen \ref{logicalandor} zeigen die Wahrheitstabellen f\"ur das +logische UND, das logische ODER und das logische XOR +(entweder-oder). 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. Anders +ist das beim logischen ODER. Hier ist der gesamte Ausdruck wahr, wenn +sich der eine \emph{oder} der andere Ausdruck, oder beide Ausdr\"ucke +zu wahr auswerten lassen. Das auschlie{\ss}ende ODER (XOR) ist nur +wahr, wenn entweder der eine oder der andere Ausdruck wahr ist und ist +in \matlab{} als Funktion \code[xor()]{xor(A, B)} verf\"ugbar. \begin{table}[tp] - \titlecaption{Wahrheitstabellen logisches UND (links) und logisches ODER (rechts).}{}\label{logicalandor} + \titlecaption{Wahrheitstabellen logisches UND, ODER und XOR.}{}\label{logicalandor} \begin{tabular}{llll} \multicolumn{2}{l}{\multirow{2}{*}{}} & \multicolumn{2}{c}{\textbf{B}} \\ - \multicolumn{2}{l}{} & \multicolumn{1}{|c}{wahr} & falsch \\ \cline{2-4} + & \sffamily{\textbf{und}} & \multicolumn{1}{|c}{wahr} & falsch \\ \cline{2-4} \multirow{2}{*}{\textbf{A}} & \multicolumn{1}{l|}{wahr} & \multicolumn{1}{c}{\textcolor{mygreen}{wahr}} & \textcolor{red}{falsch} \erb \\ & \multicolumn{1}{l|}{falsch} & \multicolumn{1}{l}{\textcolor{red}{falsch}} & \textcolor{red}{falsch} \end{tabular} - \hspace{0.1\textwidth} + \hfill \begin{tabular}{llll} - \multicolumn{2}{l}{\multirow{2}{*}{}} & \multicolumn{2}{c}{\textbf{B}} \\ - \multicolumn{2}{l}{} & \multicolumn{1}{|c}{wahr} & falsch \\ \cline{2-4} + \multicolumn{2}{l}{\multirow{2}{*}{}} & \multicolumn{2}{c}{\textbf{B}} \\ + & \sffamily{\textbf{oder}} & \multicolumn{1}{|c}{wahr} & falsch \\ \cline{2-4} \multirow{2}{*}{\textbf{A}} & \multicolumn{1}{l|}{wahr} & \multicolumn{1}{c}{\textcolor{mygreen}{wahr}} & \textcolor{mygreen}{wahr} \erb \\ & \multicolumn{1}{l|}{falsch} & \multicolumn{1}{l}{\textcolor{mygreen}{wahr}} & \textcolor{red}{falsch} \end{tabular} + \hfill + \begin{tabular}{llll} + \multicolumn{2}{l}{\multirow{2}{*}{}} & \multicolumn{2}{c}{\textbf{B}} \\ + & \sffamily{\textbf{xor}} & \multicolumn{1}{|c}{wahr} & falsch \\ \cline{2-4} + \multirow{2}{*}{\textbf{A}} & \multicolumn{1}{l|}{wahr} & \multicolumn{1}{c}{\textcolor{red}{falsch}} & \textcolor{mygreen}{wahr} \erb \\ + & \multicolumn{1}{l|}{falsch} & \multicolumn{1}{l}{\textcolor{mygreen}{wahr}} & \textcolor{red}{falsch} + \end{tabular} \end{table} -Anders ist das beim logischen ODER. Hier ist der gesamte Ausdruck -wahr, wenn sich der eine \emph{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[Operator!logischer!and2@\&\&]{\&\&} und -\code[Operator!logischer!or2@{"|}{"|} {}]{||} 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 ausgewertet wird, muss -der zweite gar nicht mehr gepr\"uft werden. Die Verwendung der -\enterm{short-circuit} Versionen spart Rechenzeit. Das auschlie{\ss}ende -ODER (XOR) ist in \matlab{} nur als Funktion \code[xor()]{xor(A, B)} -verf\"ugbar. - -\begin{table}[th] - \titlecaption{\label{logicaloperators} - Logische Operatoren in \matlab.}{} - \begin{center} - \begin{tabular}{cc} - \hline - \textbf{Operator} & \textbf{Beschreibung} \erh \\ \hline - $\sim$ & logisches NICHT \erb \\ - $\&$ & logisches UND\\ - $|$ & logisches ODER\\ - $\&\&$ & short-circuit logisches UND\\ - $\|$ & short-circuit logisches ODER\\ - \hline - \end{tabular} - \end{center} +Tabelle \ref{logicalrelationaloperators} zeigt die logischen Operatoren, die in +\matlab{} definiert sind. Zu bemerken sind hier noch die +\code[Operator!logischer!and2@\&\&]{\&\&} und +\code[Operator!logischer!or2@{"|}{"|} {}]{||} 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 ausgewertet wird, +muss der zweite gar nicht mehr gepr\"uft werden. Die Verwendung der +\enterm{short-circuit} Versionen spart Rechenzeit, da die Ausdr\"ucke +nur sowei wie n\"otig ausgewertet werden. + +\begin{table}[t] + \titlecaption{\label{logicalrelationaloperators} + Logische (links) und relationale (rechts) Operatoren in \matlab.}{} + \begin{tabular}{cc} + \hline + \textbf{Operator} & \textbf{Beschreibung} \erh \\ \hline + \varcode{$\sim$} & logisches NICHT \erb \\ + \varcode{$\&$} & logisches UND\\ + \varcode{$|$} & logisches ODER\\ + \varcode{$\&\&$} & short-circuit logisches UND\\ + \varcode{$\|$} & short-circuit logisches ODER\\ + \hline + \end{tabular} + \hfill + \begin{tabular}{cc} + \hline + \textbf{Operator} & \textbf{Beschreibung} \erh \\ \hline + \varcode{$==$} & gleich \erb \\ + \varcode{$\sim=$} & ungleich\\ + \varcode{$>$} & gr\"o{\ss}er als \\ + \varcode{$<$} & kleiner als \\ + \varcode{$>=$} & gr\"o{\ss}er oder gleich \\ + \varcode{$<=$} & kleiner oder gleich \\ + \hline + \end{tabular} \end{table} Um Werte miteinander zu vergleichen gibt es die \codeterm[Operator!relationaler]{relationalen Operatoren} (Tabelle -\ref{relationaloperators}). Mit ihnen kann man auf Dinge wie +\ref{logicalrelationaloperators}). Mit ihnen kann man auf Dinge wie Gleichheit (\varcode{==}) gr\"o{\ss}er oder kleiner als (\varcode{>}, \varcode{<}) testen. -\begin{table}[th] - \titlecaption{\label{relationaloperators} - Relationale Operatoren in \matlab.}{} - \begin{center} - \begin{tabular}{cc} - \hline - \textbf{Operator} & \textbf{Beschreibung} \erh \\ \hline - $<$ & kleiner als \erb \\ - $>$ & gr\"o{\ss}er als \\ - $==$ & gleich \\ - $>=$ & gr\"o{\ss}er oder gleich \\ - $<=$ & kleiner oder gleich \\ - $\sim=$ & ungleich\\ - \hline - \end{tabular} - \end{center} -\end{table} - -Das Ergebnis eines Booleschen Ausdrucks ist immer vom Datentyp -\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 -\code{logical} Werte 1 und 0. - \begin{important}[Zuweisungs- und Gleichheitsoperator] Der Zuweisungsoperator \code[Operator!Zuweisung!=]{=} und der logische Operator \code[Operator!logischer!==]{==} sind zwei @@ -754,70 +866,76 @@ Beispiele. \matlab{} kennt die Schl\"usselworte \code{true} und k\"onnen sie leider leicht verwechselt werden. \end{important} +Das Ergebnis eines Booleschen Ausdrucks ist immer vom Datentyp +\codeterm{logical}. Jede beliebige Variable zu wahr oder falsch +ausgewertet werden indem diese in den Typ \code{logical} umgewandelt +wird. 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 Synonyme f\"ur die \code{logical} Werte 1 und +0. + \begin{lstlisting}[caption={Boolesche Ausdr\"ucke.}, label=booleanexpressions] - >> true - ans = - 1 - >> false - ans = - 0 - >> logical(1) - ans = - 1 - >> 1 == true - ans = - 1 - >> 1 == false - ans = - 0 - >> logical('test') - ans = - 1 1 1 1 - - >> 1 > 2 - ans = - 0 - >> 1 < 2 - ans = - 1 - >> x = [2 0 0 5 0] & [1 0 3 2 0] - x = - 1 0 0 1 0 - - >> ~([2 0 0 5 0] & [1 0 3 2 0]) - ans = - 0 1 1 0 1 - - >> [2 0 0 5 0] | [1 0 3 2 0] - ans = - 1 0 1 1 0 +>> true +ans = 1 +>> false +ans = 0 +>> logical(1) +ans = 1 +>> 1 == true +ans = 1 +>> 1 == false +ans = 0 +>> logical('test') +ans = 1 1 1 1 +>> 1 > 2 +ans = 0 +>> 1 < 2 +ans = 1 +>> x = [2 0 0 5 0] & [1 0 3 2 0] +x = 1 0 0 1 0 +>> ~([2 0 0 5 0] & [1 0 3 2 0]) +ans = 0 1 1 0 1 +>> [2 0 0 5 0] | [1 0 3 2 0] +ans = 1 0 1 1 0 \end{lstlisting} \section{Logisches Indizieren}\label{logicalindexingsec} Einer der wichtigsten Einsatzorte f\"ur Boolesche Ausdr\"ucke ist das -logische Indizieren. Das logische Indizieren ist eines der +logische Indizieren. Logisches Indizieren ist eines der Schl\"usselkonzepte in \matlab{}. Nur mit diesem k\"onnen 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 -benutzt um auf den urspr\"unglichen Vektor zuzugreifen. \matlab{} gibt -nur die Werte an den Stellen zur\"uck, an denen der logische Vektor -\codeterm{wahr} ist (Listing \ref{logicalindexing1}). - +Das Grundkonzept hinter der logischen Indizierung ist, dass durch die +Verwendung eines Booleschen Ausdrucks auf z.B. einen Vektor ein +logischer Vektor gleicher Gr\"o{\ss}e zur\"uckgegeben wird. Dieser +wird benutzt um die Elemente des urspr\"unglichen Vektors +auszuw\"ahlen, bei denen der logische Vektor \codeterm{wahr} ist +(Listing \ref{logicalindexing1}). Zeile 14 kann wie +folgt gelesen werden: Gib die Elemente von \varcode{x} an den +Stellen, an denen \varcode{x < 0} wahr ist, zur\"uck. \begin{lstlisting}[caption={Beispiel logisches Indizieren.}, label=logicalindexing1] - >> x = randn(10, 1); - >> % in zwei Schritten - >> x_smaller_zero = x < 0; % logischer vektor - >> elements_smaller_zero = x(x_smaller_zero); % benutzen, um zuzugreifen - >> % oder in einem Schritt - >> elements_smaller_zero = x(x < 0); +>> x = randn(1, 6) % Zeilenvektor mit 6 Zufallszahlen +x = + -1.4023 -1.4224 0.4882 -0.1774 -0.1961 1.4193 + +>> % logisches Indizieren in zwei Schritten: +>> x_smaller_zero = x < 0 % logischer Vektor +x_smaller_zero = + 1 1 0 1 1 0 +>> elements_smaller_zero = x(x_smaller_zero) % benutzen, um zuzugreifen +elements_smaller_zero = + -1.4023 -1.4224 -0.1774 -0.1961 + +>> % logisches Indizieren in einem Schritten: +>> elements_smaller_zero = x(x < 0) +elements_smaller_zero = + -1.4023 -1.4224 -0.1774 -0.1961 \end{lstlisting} \begin{exercise}{logicalVector.m}{logicalVector.out} @@ -828,20 +946,9 @@ nur die Werte an den Stellen zur\"uck, an denen der logische Vektor \item Was ist der Datentyp von \varcode{y}? \item Gibt alle Elemente aus \varcode{x} zur\"uck, die kleiner als 5 sind. \end{enumerate} - - Zeile 12 in der L\"osung kann wie folgt gelesen werden: Gib mir die Elemente - von (\varcode{x}) an den Stellen, an denen \varcode{x < 5} wahr ist. + \pagebreak[4] \end{exercise} -Logisches Indizieren wurde oben so benutzt, dass die Auswahl -auf dem Inhalt desselben Vektors beruhte. Ein sehr h\"aufiger Fall ist -jedoch, dass die Auswahl aus einem Vektor auf dem 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}[t] \includegraphics[width= 0.9\columnwidth]{logicalIndexingTime} \titlecaption{Beispiel f\"ur logisches Indizieren.} @@ -850,6 +957,13 @@ bestimmten Zeitraums ausw\"ahlen m\"ochte (Abbildung ausgew\"ahlt (\varcode{x(t > 5 \& t < 6)}).}\label{logicalindexingfig} \end{figure} +Logisches Indizieren wurde oben so benutzt, dass die Auswahl auf dem +Inhalt desselben Vektors beruhte. Ein weiterer sehr h\"aufiger Fall +ist jedoch, dass die Auswahl aus einem Vektor auf dem Inhalt eines +zweiten Vektors basiert. Ein Beispiel ist, dass \"uber einen +gewissen Zeitraum Daten aufgenommen werden und aus diesen die Daten eines +bestimmten Zeitraums ausgew\"ahlt werden sollen (\figref{logicalindexingfig}). + \begin{exercise}{logicalIndexingTime.m}{} Angenommen es werden \"uber einen bestimmten Zeitraum Messwerte genommen. Bei solchen Messungen erh\"alt man einen Vektor, der die @@ -857,12 +971,12 @@ bestimmten Zeitraums ausw\"ahlen m\"ochte (Abbildung jeweiligen Messwerten. \begin{itemize} - \item Erstelle einen Vektor \varcode{t = 0:0.001:10;}, der z.B. die Zeit + \item Erstelle einen Vektor \varcode{t = 0:0.001:10;}, der die Zeit repr\"asentiert. - \item Erstelle einen zweiten Vektor \varcode{x} mit Zufallszahlen der + \item Erstelle einen zweiten Vektor \varcode{x} mit Zufallszahlen, der die gleiche L\"ange hat wie \varcode{t}. Die Werte darin stellen Messungen zu den Zeitpunkten in \varcode{t} dar. - \item Benutze das logische Indizieren um die Messwerte + \item Benutze logische Indizieren um die Messwerte auszuw\"ahlen, die dem zeitlichen Abschnitt 5--6\,s entsprechen. \end{itemize} \end{exercise} @@ -902,28 +1016,29 @@ x = 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 -ganzer Abschnitte ist schlechter Prgrammierstil. Dabei geht es nicht nur um -einen \"asthetischen Aspekt sondern vielmehr darum, dass es schwerwiegende Nachteile gibt. +Verwendung von mehr oder weniger exakten Wiederholungen einzelner +Zeilen oder ganzer Abschnitte ist schlechter Prgrammierstil. Dabei +geht es nicht nur um einen \"asthetischen Aspekt sondern vielmehr +darum, dass es schwerwiegende Nachteile gibt: \begin{enumerate} \item Fehleranf\"alligkeit: Beim ``Copy-and-paste'' kann leicht - vergessen werden in einzelnen Klonen die entscheidende \"Anderung - auch wirklich vorzunehmen. + vergessen werden in einzelnen Wiederholungen die entscheidende + \"Anderung auch wirklich vorzunehmen. \item Flexibilit\"at: Das obige Programm ist f\"ur genau einen Zweck, Berechnung der Fakult\"at von f\"unf, gemacht und kann nichts anderes. -\item Wartung: Wenn ich einen Fehler gemacht habe, dann muss ich den - Fehler in allen Klonen korrigieren (sehr leicht wird dabei der ein oder - andere Klon \"ubersehen). -\item Verst\"andlichkeit: Solche Abschnitte sind schwerer zu lesen/zu - verstehen. Das liegt zum Teil daran, dass man dazu neigt \"uber sich - wiederholende Zeilen zu springen (ist ja eh das gleiche...) und dann - den entscheidenden Teil verpasst. Zum Anderen f\"uhrt - Codeduplication zu langen, un\"ubersichtlichen Programmen. +\item Wartung: Wenn ein Fehler gemacht wurde, dann muss der Fehler in + allen Wiederholungen korrigiert werden (sehr leicht wird dabei etwas + \"ubersehen). +\item Verst\"andlichkeit: Solche Abschnitte sind schwerer zu lesen und + schwer zu verstehen. Das liegt zum Teil daran, dass man dazu neigt + \"uber sich wiederholende Zeilen zu springen (ist ja eh das + gleiche...) und dann den entscheidenden Teil verpasst. Zum Anderen + f\"uhrt Codeduplication zu langen, un\"ubersichtlichen Programmen. \end{enumerate} Alle Programmiersprachen bieten zur L\"osung dieses Problems die -Schleifen. Eine Schleife wird immer dann eingesetzt, wenn man -Abschnitte wiederholt ausf\"uhren will. +Schleifen. Eine Schleife wird immer dann eingesetzt, wenn +Abschnitte wiederholt ausgef\"uhrt werden sollen. \subsubsection{Die \code{for} -- Schleife} @@ -943,7 +1058,7 @@ das Grundger\"ust einer for-Schleife. \begin{lstlisting}[caption={Beispiel einer \varcode{for}-Schleife.}, label=looplisting] >> for x = 1:5 - disp(x); + x end % die Laufvariable x nimmt mit jeder Iteration der Schleife % einen Wert des Vektors 1:5 an: @@ -977,11 +1092,10 @@ Schl\"usselwort \code{end} beendet. \begin{lstlisting}[caption={Grundstruktur einer \varcode{while} Schleife.}, label=whileloop] while x == true - % fuehre diesen sinnvollen code aus ... + % fuehre diesen sinnvollen Code aus ... end \end{lstlisting} - \begin{exercise}{facultyWhileLoop.m}{} Implementiere die Fakult\"at mit einer \code{while}-Schleife. \end{exercise} @@ -991,6 +1105,7 @@ end Implementiere eine \code{while}-Schleife, die unendlich l\"auft. Tipp: wenn der Boolesche Ausdruck hinter dem \code{while} zu wahr ausgewertet wird, wird die Schleife weiter ausgef\"uhrt. + Das Programm kann mit \keycode{Ctrl+C} abgebrochen werden. \end{exercise} @@ -1036,22 +1151,22 @@ beendet. Listing \ref{ifelselisting} zeigt den Aufbau einer \begin{lstlisting}[label=ifelselisting, caption={Grundger\"ust einer \varcode{if} Anweisung.}] - if x < y - % fuehre diesen code aus +if x < y + % fuehre diesen code aus wenn x < y elseif x > y - % etwas anderes soll getan werden + % etwas anderes soll getan werden fuer x > y else % wenn x == y, wieder etwas anderes end \end{lstlisting} \begin{exercise}{ifelse.m}{} - Ziehe eine Zufallszahl und \"uberpr\"ufe mit einer geeigneten \code{if} Anweisung, ob sie: + Ziehe eine Zufallszahl und \"uberpr\"ufe mit einer geeigneten \code{if} Anweisung, ob sie \begin{enumerate} - \item ... kleiner als 0.5 ist. - \item ... kleiner oder gr\"o{\ss}er-gleich 0.5 ist. - \item ... 1. kleiner als 0.5, 2. gr\"o{\ss}er oder gleich 0.5 aber kleiner - als 0.75 oder 3. gr\"o{\ss}er oder gleich 0.75 ist. + \item kleiner als 0.5 ist. + \item kleiner oder gr\"o{\ss}er-gleich 0.5 ist. + \item (i) kleiner als 0.5, (ii) gr\"o{\ss}er oder gleich 0.5 aber kleiner + als 0.75 oder (iii) gr\"o{\ss}er oder gleich 0.75 ist. \end{enumerate} \end{exercise} @@ -1081,7 +1196,7 @@ switch mynumber disp('positive one'); otherwise disp('something else'); - end +end \end{lstlisting} Wichtig ist hier, dass in jedem \code{case} auf Gleichheit der @@ -1160,7 +1275,7 @@ end \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. + $+1$ oder $-1$. \item Merke Dir alle Positionen. \item Plotte die Positionen als Funktion der Schrittnummer. \end{itemize} @@ -1201,15 +1316,15 @@ dieses Problem bieten die \codeterm[Funktion]{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 +Die Funktion hat einen Namen $f$, sie \"uber das Argument $x$ +einen Input und liefert ein Ergebnis in $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 +function [y] = functionName(arg_1, arg_2) +% ^ ^ ^ +% Rueckgabewert Argument_1, Argument_2 \end{lstlisting} Ein Funktion beginnt mit dem Schl\"usselwort \code{function} gefolgt @@ -1233,21 +1348,21 @@ definiert. \"Uber die Definition/Benutzung von Funktionen wird folgendes erreich \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={Ein schlechtes Beispiel einer Funktion, die eine Reihe Sinusse plottet.},label=badsinewavelisting] -function meine_erste_funktion() % Funktionskopf +function meineErsteFunktion() % 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 \end{lstlisting} Das obige Beispiel ist ein Paradebeispiel f\"ur eine schlechte Funktion. Sie hat folgende Probleme: @@ -1295,7 +1410,7 @@ welche Daten sie zur\"uckliefern soll. 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: \varcode{varamplitude}, \varcode{frequency}, + hei{\ss}en: \varcode{amplitude}, \varcode{frequency}, \varcode{t\_max}, \varcode{t\_step}. \item \codeterm[Funktion!R{\"u}ckgabewerte]{R\"uckgabewerte}: Um den Sinus korrekt darstellen zu k\"onnen brauchen wir die Zeitachse und @@ -1307,14 +1422,19 @@ implementieren (Listing \ref{sinefunctionlisting}). \begin{lstlisting}[caption={Funktion zur Berechnung eines Sinus.}, label=sinefunctionlisting] function [time, sine] = sinewave(frequency, amplitude, t_max, t_step) - % Calculate a sinewave of a given frequency, amplitude, duration and temporal resolution. - % [time, sine] = sinewave(frequency, amplitude, t_max, t_step) - % 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 +% Calculate a sinewave of a given frequency, amplitude, +% duration and temporal resolution. +% +% [time, sine] = sinewave(frequency, amplitude, t_max, t_step) +% +% 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: vector of the time axis +% sine: vector of the calculated sinewave time = (0:t_step:t_max); sine = sin(frequency .* time .* 2 * pi) .* amplitude; end @@ -1325,7 +1445,7 @@ end Das Plotten der berechneten Sinuschwingung 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. \code{plot\_function()}). Um einen einzelnen Sinus +orientieren (z.B. \code{plotFunction()}). 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 @@ -1333,12 +1453,15 @@ auch sinnvoll eine Zeichenkette f\"ur die Legende an die Funktion zu R\"uckgabewert ben\"otigt (Listing \ref{sineplotfunctionlisting}). \begin{lstlisting}[caption={Funktion zur graphischen Darstellung der Daten.}, label=sineplotfunctionlisting] -function plot_function(x_data, y_data, name) - % Plots x-data against y-data and sets the display name. - % plot_sinewave(x_data, y_data, name) - % Arguments: x_data, the x-data - % y_data, the y-data - % name, the displayname +function plotFunction(x_data, y_data, name) +% Plots x-data against y-data and sets the display name. +% +% plotFunction(x_data, y_data, name) +% +% Arguments: +% x_data: vector of the x-data +% y_data: vector of the y-data +% name : the displayname plot(x_data, y_data, 'displayname', name) end \end{lstlisting} @@ -1347,37 +1470,39 @@ end \paragraph{III. Erstellen eines Skriptes zur Koordinierung} Die letzte Aufgabe ist die Koordinierung der Berechung und des Plottens f\"ur mehrere Amplituden. Das ist die klassische Aufgabe -f\"ur ein \codeterm{Skript}. Auch hier gilt es einen ausdrucksvollen Name zu -finden. Da es keine Argumente und R\"uckgabewerte gibt, m\"ussen die -ben\"otigten Informationen direkt in dem Skript defniniert werden. Es -werden ben\"otigt: 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 +f\"ur ein \codeterm{Skript}. Auch hier gilt es einen ausdrucksvollen +Name zu finden. Da es keine Argumente und R\"uckgabewerte gibt, +m\"ussen die ben\"otigten Informationen direkt in dem Skript +defniniert werden. Es werden ben\"otigt: 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 mit +\code{figure()} 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 zur Koordination von Berechnung und graphischer Darstellung.}, label=sinesskriptlisting] +\begin{lstlisting}[caption={Kontrollskript zur Koordination von Berechnung und graphischer Darstellung.},label=sinesskriptlisting] amplitudes = 0.25:0.25:1.25; frequency = 2.0; t_max = 10.0; t_step = 0.01; - + figure() hold on - for i = 1:length(amplitudes) [x_data, y_data] = sinewave(frequency, amplitudes(i), ... t_max, t_step); - plot_function(x_data, y_data, sprintf('freq: %5.2f, ampl: %5.2f',... - frequency, amplitudes(i))) + plotFunction(x_data, y_data, sprintf('freq: %5.2f, ampl: %5.2f',... + frequency, amplitudes(i))) end +hold off legend('show') \end{lstlisting} \begin{exercise}{plotMultipleSinewaves.m}{} - Erweitert das Programm so, dass auch ein Satz von Frequenzen benutzt - wird. + Erweiter das Programm so, dass die Sinusse f\"ur einen Satz von + Frequenzen geplottet wird. + \pagebreak[4] \end{exercise} \subsection{Fazit} @@ -1394,7 +1519,7 @@ 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 Problem zu l\"osen. W\"ahrend die Funktionen relativ -kleine ``verdauliche'' Teilprobleme l\"osen. Sind die Skripte daf\"ur +kleine ``verdauliche'' Teilprobleme l\"osen, sind Skripte daf\"ur gemacht den Rahmen zu bilden und den Ablauf zu koordinieren (Abbildung \ref{programlayoutfig}). diff --git a/regression/code/errorGradient.m b/regression/code/errorGradient.m index ac484ec..a24367f 100644 --- a/regression/code/errorGradient.m +++ b/regression/code/errorGradient.m @@ -1,5 +1,4 @@ load('lin_regression.mat') - ms = -1:0.5:5; ns = -10:1:10; @@ -27,4 +26,4 @@ ylabel('Intercept b') zlabel('Mean squared error') set(gcf, 'paperunits', 'centimeters', 'papersize', [15, 10.5], ... 'paperposition', [0., 0., 15, 10.5]) -saveas(gcf, 'error_gradient', 'pdf') \ No newline at end of file +saveas(gcf, 'error_gradient', 'pdf') diff --git a/regression/code/lsqGradient.m b/regression/code/lsqGradient.m index 4041d9e..39bfbbb 100644 --- a/regression/code/lsqGradient.m +++ b/regression/code/lsqGradient.m @@ -7,11 +7,8 @@ function gradient = lsqGradient(parameter, x, y) % y, vector of the corresponding measured output values % % Returns: the gradient as a vector with two elements - h = 1e-6; % stepsize for derivatives - partial_m = (lsqError([parameter(1)+h, parameter(2)], x, y) - lsqError(parameter, x, y))/ h; partial_n = (lsqError([parameter(1), parameter(2)+h], x, y) - lsqError(parameter, x, y))/ h; - gradient = [partial_m, partial_n]; end diff --git a/regression/lecture/regression.tex b/regression/lecture/regression.tex index ffa32c2..cdfeb8c 100644 --- a/regression/lecture/regression.tex +++ b/regression/lecture/regression.tex @@ -316,7 +316,6 @@ partielle Ableitung nach $m$ durch Parametersatz $(m, b)$ der Geradengleichung als 2-elementigen Vektor sowie die $x$- und $y$-Werte der Messdaten als Argumente entgegennimmt und den Gradienten an dieser Stelle zur\"uckgibt. - \pagebreak[4] \end{exercise} \begin{exercise}{errorGradient.m}{} @@ -378,7 +377,6 @@ Punkte in Abbildung \ref{gradientdescentfig} gro{\ss}. Funktion der Optimierungsschritte zeigt. \item Erstelle einen Plot, der den besten Fit in die Daten plottet. \end{enumerate} - \pagebreak \end{exercise}