24.04.2013 Aufrufe

MATLAB - Eine Einführung - TUM

MATLAB - Eine Einführung - TUM

MATLAB - Eine Einführung - TUM

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

<strong>MATLAB</strong> - <strong>Eine</strong> <strong>Einführung</strong><br />

Christian Kufner Harald Schmid Konstantin Schorp Bettina Tögel<br />

Matthias Vestner Konstantin Pieper Lorenz Pfeifroth Stefan Jerg<br />

Boris von Loesch<br />

16. April 2009


Vorwort<br />

Das vorliegende Skript gibt dem Leser eine <strong>Einführung</strong> in den Umgang mit <strong>MATLAB</strong>. Die Bedienung<br />

von <strong>MATLAB</strong> und die Themen Visualisierung und lineare Algebra mit <strong>MATLAB</strong> werden erklärt. Auf<br />

weiterführende Funktionen <strong>MATLAB</strong> wie Toolboxen und das Einbinden von Java- und C-Programmen<br />

wird eingegangen.<br />

Dieses Handbuch ist besonders für Studenten der Mathematik geeignet, die im Studium <strong>MATLAB</strong><br />

benötigen. Grundkenntnisse der linearen Algebra werden vorausgesetzt, jedoch sind keine Programmierkenntnisse<br />

notwendig. Dieses Skript ist im Internet unter<br />

http://www.fs.tum.de/fsmpi/kurse/matlab/matlabeinfuehrung.pdf<br />

verfügbar. Sie erreichen den verantwortlichen Mitarbeiter der TU München unter der Email-Adresse<br />

brandenb@ma.tum.de.<br />

Zweite Auflage Dieses Skript wurde für den Ferienkurs „<strong>MATLAB</strong> Grundlagen“ im Wintersemester<br />

07/08 überarbeitet und um die Abschnitte „Eigenwerte“ 5.5, „Ein- und Ausgabe“ 7 und „Troubleshooting“<br />

erweitert. Die Webadresse des Kurses ist<br />

http://ferienkurse.ma.tum.de/twiki/bin/view/Allgemein/WS0708/Matlab.<br />

Dritte Auflage Dieses Skript wurde für den Ferienkurs „<strong>MATLAB</strong> Grundlagen“ im Sommersemester<br />

08 überarbeitet. Die Webadresses des Kurses ist<br />

http://ferienkurse.ma.tum.de/twiki/bin/view/Ferienkurse/SS08/MatLabG<br />

Vierte Auflage Für die vierte Auflage wurden weite Teile des Skriptes stark verändert. Ein Einstiegsbeispiel<br />

(Kapitel 1) soll den Leser mit den besonderen Fähigkeiten von <strong>MATLAB</strong> vertraut machen.<br />

Kapitel 2 ist komplett umgearbeitet worden, zusätzlich wurde das Skript um einen Index ergänzt. Diese<br />

<strong>Einführung</strong> wurde für die Ferienkurse <strong>MATLAB</strong> im SS09 verwendet.<br />

http://www.ma.tum.de/Ferienkurse/WiSe0809/MatLabC<br />

1


Inhaltsverzeichnis<br />

0.1 Bezug von <strong>MATLAB</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4<br />

0.2 Alternativen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4<br />

0.3 Hinweise zur Eingabe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5<br />

0.3.1 Komplexe Zahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5<br />

1 Motivation 7<br />

1.1 Interpolation durch kubischen Splines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7<br />

1.2 Implementierung in <strong>MATLAB</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />

1.3 Visualisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />

1.4 Erweiterung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10<br />

1.5 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10<br />

2 Vektoren und Matrizen 11<br />

2.1 Matrizen erzeugen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11<br />

2.1.1 Spezielle Matrizen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />

2.1.2 Doppelpunkt Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

2.2 Indizierung und Doppelpunktnotation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

2.3 Operatoren und Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16<br />

2.3.1 Rechenoperatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17<br />

2.3.2 Basisfunktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18<br />

2.3.3 Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19<br />

2.4 Matrizen manipulieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21<br />

3 Operatoren und Flusskontrolle 23<br />

3.1 Relationale Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

3.2 Logische Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

3.2.1 Indizierung mit logischen Feldern . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />

3.3 Flusskontrolle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26<br />

4 M-Dateien 30<br />

4.1 Skriptdateien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30<br />

4.2 Funktionsdateien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31<br />

4.3 M-Dateien bearbeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31<br />

4.4 Mit M-Dateien und der Pfadvariable von <strong>MATLAB</strong> arbeiten . . . . . . . . . . . . . . . . 32<br />

4.5 Dualität von Befehl und Funktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32<br />

5 Lineare Algebra mit <strong>MATLAB</strong> 34<br />

5.1 Norm und Kondition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34<br />

5.2 Lineare Gleichungssysteme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35<br />

5.2.1 A n × n Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35<br />

5.2.2 A m × n Matrix mit m > n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35<br />

5.2.3 A m × n Matrix mit m < n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35<br />

5.3 Inverse, Pseudoinverse und Determinante . . . . . . . . . . . . . . . . . . . . . . . . . . . 35<br />

5.4 Zerlegungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />

5.4.1 LR-Zerlegung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />

5.4.2 Cholesky-Zerlegung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />

5.4.3 QR-Zerlegung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />

5.4.4 Singulärwertzerlegung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />

2


5.5 Eigenwertpropleme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />

5.5.1 Eigenwerte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />

5.6 Matrixfunktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38<br />

6 Eigene Funktionen 39<br />

6.1 Referenzen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39<br />

6.2 Subfunktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />

6.3 Globale Variablen und Rekursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />

7 Ein- und Ausgabe 42<br />

7.1 Direkte Eingabe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42<br />

7.2 Bildschirmausgabe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />

7.3 Speichern und Laden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />

7.4 Indirekte Eingabe und Ausgabe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44<br />

8 Optimierung von M-Files 46<br />

8.1 Vektorisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />

8.2 Preallokierung von Speicher . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />

9 Tipps und Tricks 48<br />

9.1 Leere Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48<br />

9.2 ∞ und −∞ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48<br />

10 Grafiken mit <strong>MATLAB</strong> erstellen 50<br />

10.1 Grafiken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50<br />

10.2 2-dimensionale Plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50<br />

10.3 Mehrere Plots in einem Fenster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55<br />

10.4 3-dimensionale Plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56<br />

10.4.1 Animationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58<br />

10.5 Diagramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />

10.5.1 Balkendiagramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />

10.5.2 Tortendiagramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60<br />

11 Troubleshooting 61<br />

11.1 Errors und Warnings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61<br />

11.2 Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61<br />

12 Weiterführende <strong>MATLAB</strong>-Funktionen 62<br />

12.1 Toolkits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62<br />

12.1.1 Symbolic Math Toolbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62<br />

12.1.2 Image Processing Toolbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />

12.2 Der <strong>MATLAB</strong> C-Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />

12.3 Andere Programmiersprachen mit <strong>MATLAB</strong> verwenden . . . . . . . . . . . . . . . . . . . 64<br />

12.3.1 Fortran und C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64<br />

12.3.2 Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />

12.4 GUIs programmieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />

12.4.1 GUI Kommandos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />

12.4.2 GUIDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66<br />

3


Einleitung<br />

<strong>MATLAB</strong> ist eine mächtige Anwendung für Mathematiker und Ingenieure, die von der Firma The Mathworks<br />

entwickelt und vertrieben wird. Vielfältigste Funktionen zur Lösung numerischer Probleme, der<br />

Visualisierung von Daten und die Erweiterbarkeit des Basispakets über Toolboxen machen <strong>MATLAB</strong> zu<br />

einem guten Werkzeug für Studenten der Mathematik, die sich im Rahmen ihres Studiums auch mit dem<br />

Lösen numerischer Probleme beschäftigen.<br />

<strong>MATLAB</strong> enthält eine komfortable IDE (integrated development environment) die den Programmierer<br />

bei seiner Arbeit unterstützt. In ihr sind sind unter anderem enthalten<br />

• eine interaktive Codeeingabe,<br />

• eine ausführliche Hilfe,<br />

• ein Quellcode Editor mit Syntax Highlighting,<br />

• ein Debugger um Programme schrittweise durchlaufen zu lassen,<br />

• ein Profiler zum Erkennen von Geschwindigkeitsengpässsen.<br />

Im Gegensatz zu anderen Programmiersprachen wie C, Fortran oder Java muss <strong>MATLAB</strong> Code vor der<br />

Ausführung nicht kompiliert werden, sondern wird direkt interpretiert 1 . Auch müssen Variablen vor ihrer<br />

ersten Verwendung nicht deklariert werden. Deshalb ist <strong>MATLAB</strong> in die Kategorie der Skriptsprachen,<br />

wie z.B. Python, Tcl oder Perl, einzuordnen.<br />

Das Besondere an <strong>MATLAB</strong> ist die Verwendung von mehrdimensionalen Feldern (auch mit komplexen<br />

Zahlen) wie Vektoren und Matrizen als Standardtypen und eine umfangreiche mathematische Bibliothek.<br />

Damit ist es möglich, Algorithmen in einer mathematischen Syntax unter Verwendung von Standardkomponenten<br />

wie z.B. einer LR-Zerlegung schnell zu implementieren (Prototyping). Der Vorwurf, dass<br />

Programme in <strong>MATLAB</strong> im Vergleich zu Fortran oder C viel langsamer sind, ist im Allgemeinen nicht<br />

berechtigt, wenn man bei der Programmierung gewisse Prinzipien befolgt. Dies liegt daran, dass MAT-<br />

LAB intern sehr schnelle Routinen z.B. für das Matrix-Vektor-Produkt oder die Fouriertransformation<br />

verwendet; wie andere Numerikpakete verwendet <strong>MATLAB</strong> für die Lineare Algebra die BLAS und LA-<br />

PACK Bibliotheken.<br />

Diese <strong>Einführung</strong> soll einen Einblick in den Aufbau und die grundlegenden Funktionen von <strong>MATLAB</strong><br />

geben. Weiterführende Informationen findet man in der umfangreichen eingebauten Hilfe, in den vielen<br />

<strong>MATLAB</strong> Bücher und natürlich auch im Internet.<br />

0.1 Bezug von <strong>MATLAB</strong><br />

Als Student gibt es die Möglichkeit kostengünstig eine Studentenversion zu erwerben, die allerdings nur<br />

während und für das Studium verwendet werden darf. Weiterhin ist auf allen Computer der Rechnerhalle<br />

<strong>MATLAB</strong> verfügbar.<br />

0.2 Alternativen<br />

Neben <strong>MATLAB</strong> gibt es eine Reihe Programmpakete, die -zumindest was die grundlegenden Funktionen<br />

angeht- sehr ähnlich sind. <strong>Eine</strong> nicht repräsentative Liste frei verfügbarer Pakete:<br />

1 Seit <strong>MATLAB</strong> R6.5 wird der Code während der Ausführung durch einen Just-In-Time Kompilierer übersetzt um eine<br />

höhere Performance im Vergleich zur direkten Ausführung zu erhalten<br />

4


Octave ist ein Open-Source Clone von <strong>MATLAB</strong> der für viele Betriebssysteme verfügbar ist. Alle Beispiele<br />

aus diesem Skript (bis auf das Kapitel Grafik) sollten ohne Änderung auch in Octave funktionieren.<br />

http://www.gnu.org/software/octave/<br />

SciLab <strong>Eine</strong> freie <strong>MATLAB</strong> Alternative die am INRIA 2 entwickelt wurde. Der Syntax ist nicht kompatibel<br />

zu <strong>MATLAB</strong>, allerdings recht ähnlich; im Paket enthalten ist ein <strong>MATLAB</strong> zu SciLab<br />

Konverter.<br />

http://www.scilab.org/<br />

Python+NumPy+SciPy NumPy und SciPy erweitern die Skriptsprache Python um einen flexiblen<br />

Array-Typ und eine umfangreiche mathematische Bibliothek. Die Syntax ist verschieden zu MAT-<br />

LAB. Diese Kombination erfreut sich in letzter Zeit größerer Beliebtheit. Ein besonderer Vorteil<br />

dieses Paketes ist die Möglichkeit, sehr einfach andere Numerikcodes wie z.B. PETSc oder Trilinos<br />

direkt in Python zu verwenden.<br />

http://www.scipy.org<br />

0.3 Hinweise zur Eingabe<br />

Wie C oder Java unterscheidet <strong>MATLAB</strong> zwischen Groß- und Kleinschreibung. So kann der Befehl<br />

sin(pi/2) richtig interpretiert werden, die Eingabe von Sin(pi/2) gibt jedoch eine Fehlermeldung zurück:<br />

??? Undefined function or method ’Sin’ for input arguments of type ’double’.<br />

Methodennamen werden in <strong>MATLAB</strong> grundsätzlich klein geschrieben und als Programmierer sollte<br />

man sich an diese Konvention halten.<br />

In den ersten Kapiteln werden wir die Beispiele direkt in die interaktive Codeeingabe eintippen.<br />

Das Ergebnis eines Befehls wird standardmäßig direkt ausgegeben. Dies kann unterdrückt werden durch<br />

Abschließen des Befehls mit einem Semikolon. Wird das Ergebnis eines Befehls nicht in einer Variable<br />

gespeichert, wird es automatisch in die Variable ans geschrieben.<br />

>> sin(pi/2)<br />

ans =<br />

1<br />

>> sin(pi/4);<br />

>> ans<br />

ans =<br />

0.7071<br />

Mehrere Befehle können durch Komma (mit Ausgabe des Ergebnisses) oder Semikolon (ohne Ausgabe<br />

des Ergebnisses) getrennt in eine Zeile geschrieben werden. Hierbei wird nur das letzte Resultat in ans<br />

gespeichert.<br />

>> cos(0); cos(pi/4), cos(pi/2)<br />

ans =<br />

0.7071<br />

ans =<br />

6.1232e-17<br />

0.3.1 Komplexe Zahlen<br />

<strong>MATLAB</strong> interpretiert eine Zahl standardmäßig als Gleitpunktzahl mit doppelter Genauigkeit 3 . Komplexe<br />

Zahlen werden durch<br />

2 Institut national de recherche en informatique et en automatique<br />

3 Im Gegensatz zu vielen anderen Programmiersprachen ist 1/2 also wirklich 0.5.<br />

5


+i<br />

eingegeben, z.B. 2+0.5i. Aus diesem Grund sollte die imaginäre Einheit i nicht durch eine Variable<br />

überschrieben werden, da es sonst Probleme mit komplexen Zahlen geben kann.<br />

<strong>MATLAB</strong> verwendet automatisch komplexe Zahlen wenn dies nötig ist. So wird z.B. √ −1 richtig als<br />

komplexe Zahl interpretiert. In vielen anderen Programmiersprachen würde dieser Aufruf eine Fehlermeldung<br />

erzeugen.<br />

6


Kapitel 1<br />

Motivation<br />

Bevor wir uns die Funktionen von <strong>MATLAB</strong> im Detail anschauen, wollen wir an einem kurzen Beispiel<br />

die schnelle und effiziente Umsetzung eines Algorithmus in <strong>MATLAB</strong> demonstrieren. Wie werden hier<br />

die Vorzüge gegenüber klassischen Programmiersprachen feststellen.<br />

1.1 Interpolation durch kubischen Splines<br />

Bei der Interpolation ist eine stetige Funktion S : R → R gesucht, die eine gegebene Menge von Knotenpunkten<br />

(xi, yi) ∈ R×R, i = 0, . . . , n mit xi < xj, i < j interpoliert, d.h. S(xi) = yi für i = 0, . . . , n. Häufig<br />

benötigt man, dass die Funktion S mindestens zweimal stetig differenzierbar ist, dann bieten sich kubische<br />

Splines zur Interpolation an. Ein kubischer Spline ist eine C 2 ([x0, xn]) Funktion, die eingeschränkt<br />

auf ein Intervall [xi, xi+1], i = 0, . . . , n − 1 ein Polynom 3. Grades ist. Diese Aufgabe ist nur dann eindeutig<br />

lösbar, wenn man noch zusätzliche Informationen am Rand vorgibt. Dafür gibt es mehrere Varianten,<br />

eine davon ist, dass die zweiten Ableitungen in den Randpunkten verschwinden (S ′′ (x0) = 0 = S ′′ (xn)).<br />

In diesem Fall nennt man den Spline natürlichen Spline.<br />

<strong>Eine</strong> Möglichkeit einen natürlichen Spline zu berechnen, ist die Momentenmethode. Wir wollen in diesem<br />

Rahmen nicht auf deren Herleitung eingehen sondern verweisen auf [1]. Als Momente Mi bezeichnet<br />

man die zweiten Ableitungen an den Stützstellen xi, also Mi = S ′′ (xi). Hat man sie berechnet, kann man<br />

die Koeffizienten des Polynoms<br />

Pi(x) = αi + βi(x − xi) + γi(x − xi) 2 + δi(x − xi) 3<br />

auf dem Intervall [xi, xi+1] direkt angeben (hi+1 = xi+1 − xi):<br />

αi = yi<br />

βi = yi+1 − yi<br />

hi+1<br />

γi = Mi<br />

2<br />

δi = Mi+1 − Mi<br />

6hi+1<br />

− 2Mi + Mi+1<br />

hi+1<br />

6<br />

Die Momente sind Lösung des linearen Gleichungssystems<br />

⎛<br />

2<br />

⎜µ1<br />

⎜<br />

⎝<br />

λ0<br />

2<br />

µ2<br />

λ1<br />

2<br />

. ..<br />

λ2<br />

. ..<br />

µn−1<br />

. ..<br />

2<br />

⎞<br />

⎛<br />

⎟ ⎜<br />

⎟ ⎜<br />

⎟ ⎜<br />

⎟ ⎜<br />

⎟ ⎜<br />

⎟ ⎝<br />

λn−1⎠<br />

2<br />

µn<br />

7<br />

M0<br />

M1<br />

.<br />

Mn−1<br />

Mn<br />

⎞<br />

⎛<br />

⎟ ⎜<br />

⎟ ⎜<br />

⎟ ⎜<br />

⎟ = ⎜<br />

⎟ ⎜<br />

⎠ ⎝<br />

d0<br />

d1<br />

.<br />

dn−1<br />

dn<br />

⎞<br />

⎟<br />

⎠<br />

(1.1)


mit (j = 1, . . . , n − 1)<br />

hj<br />

λj =<br />

hj + hj−1<br />

µj = 1 − λj<br />

6<br />

dj =<br />

hj + hj−1<br />

Für den natürlichen Spline setzt man noch<br />

yj+1 − yj<br />

hj<br />

λ0 = d0 = dn = µn = 0. 1<br />

1.2 Implementierung in <strong>MATLAB</strong><br />

− yj<br />

<br />

− yj−1<br />

.<br />

hj−1<br />

In diesem Abschnitt werden uns ein kurzes <strong>MATLAB</strong> Skript ansehen, welches die Koeffizienten der<br />

Polynome die den kubischen Spline beschreiben ausrechnet. Da dies nur eine kurze Motivation für die<br />

Verwendung von <strong>MATLAB</strong> sein soll, werden wir die Implementierung nicht in voller Ausführlichkeit<br />

besprechen. Die genaue Funktionsweise sollte mit Hilfe der späteren Ausführungen verständlich werden.<br />

Die Funktion kspline bekommt als Eingabeparameter ein Vektor x mit den Stützstellen und ein<br />

Vektor y mit den zu interpolierenden Werten. Zurückgegeben wird eine (n − 1) × 4-Matrix, in deren i-ter<br />

Zeile die Koeffizienten des kubischen Polynoms des Intervalls [xi, xi+1] stehen.<br />

1 function [ P ] = k s p l i n e ( x , y )<br />

2 n = length ( x ) ;<br />

3 j j = 1 : n−1; j = 2 : n−1;<br />

4 h = [ x ( j j +1)−x ( j j ) ] ;<br />

5 lambda = [ 0 , h ( j +1)./( h ( j )+h ( j + 1 ) ) ] ;<br />

6 mu = [1−lambda ( j ) , 0 ] ;<br />

7 d = [ 0 , ( 6 . / ( h ( j )+h ( j + 1 ) ) ) . ∗ ( ( y ( j +1)−y ( j ) ) . / h ( j +1) . . .<br />

8 − ( y ( j )−y ( j −1))./ h ( j ) ) , 0 ] ;<br />

9 A = 2∗eye ( n ) + diag ( lambda , 1) + diag (mu, −1);<br />

10 M = (A \ d ’ ) ’ ;<br />

11 alpha = y ( j j ) ; gamma = M( j j ) / 2 ;<br />

12 beta = ( y ( j j +1)−y ( j j ) ) . / h ( j j +1) − h ( j j +1).∗(2∗M( j j )+M( j j +1))/6;<br />

13 d e l t a = (M( j j +1)−M( j j ) ) . / ( 6 ∗ h ( j j +1));<br />

14 P = [ alpha ’ , beta ’ , gamma’ , delta ’ ] ;<br />

15 end<br />

In der ersten Zeile des Skripts speichern wir die Anzahl der Punkte in der Variable n und erzeugen<br />

Vektoren jj und j in dem die Zahlen von 1 bzw. 2 bis n − 1 stehen. Dann berechnen wir die Länge<br />

der Intervalle [xi, xi+1] und speichern diese in h. Auf dieselbe Weise berechnen wir die λi, µi und di. Die<br />

Einträge λ0, µn, d0 und dn werden hierbei explizit auf Null gesetzt. Man sieht, wie sich die Formeln aus<br />

dem vorherigen Abschnitt nahezu eins zu eins im <strong>MATLAB</strong> Code wiederfinden.<br />

In Zeile 9 erzeugen wir die Matrix aus (1.1) indem wir auf eine mit zwei multiplizierte Einheitsmatrix<br />

die Vektoren lambda und mu auf die Nebendiagonalen addieren.<br />

Der Aufruf M = (A \ d’)’; löst nun das Gleichungssystem (1.1). Der hierbei verwendete Backslash-<br />

Operator wählt automatisch das Verfahren welches das Gleichungssystem möglichst effizient löst, z.B.<br />

eine Cholesky-Zerlegung bei einer symmetrisch positiv definiten Matrix. Da Vektoren in <strong>MATLAB</strong> standardmäßig<br />

Zeilenvektoren sind, müssen wir die rechte Seite d mit ’ transponieren und die Lösung auf die<br />

selbe Weise zurück in einen Zeilenvektor transformieren. Alternativ hätten wir auch den Slash-Operator<br />

verwenden können, um das zweimalige Transponieren zu vermeiden: M = d / A;.<br />

Nachdem die Momente bestimmt sind, berechnen die letzten Zeilen der Funktion die Koeffizienten<br />

des Polynoms und schreiben sie in die (n − 1) × 4-Matrix P. Damit ist alles berechnet.<br />

An diesem Beispiel kann man gut erkennen, wie effektiv der gegebene Algorithmus implementiert<br />

wurde. Wir sind komplett ohne Kontrollstrukturen wie z.B. Schleifen ausgekommen. Zusätzlich lässt sich<br />

der Programmcode sehr gut lesen und ist gut verständlich.<br />

1 Mit dieser Wahl folgt sofort M0 = S ′′ (x0) = Mn = S ′′ (xn) = 0<br />

8


Das folgende Beispiel demonstriert die Verwendung der Methode um einen kubischen Spline zu berechnen,<br />

der die Wurzelfunktion im Intervall [0, 1] interpoliert:<br />

>> x=0:0.1:1;<br />

>> y=sqrt(x);<br />

>> P=kspline(x,y)<br />

P =<br />

0 3.4008 3.5780 -59.6338<br />

0.3162 2.2081 -14.3121 53.2933<br />

0.4472 0.9445 1.6759 -10.7011<br />

0.5477 0.9587 -1.5345 4.2121<br />

0.6325 0.7781 -0.2708 -0.4530<br />

0.7071 0.7104 -0.4067 0.5202<br />

0.7746 0.6446 -0.2507 0.1069<br />

0.8367 0.5977 -0.2186 0.1827<br />

0.8944 0.5595 -0.1638 -0.0523<br />

0.9487 0.5236 -0.1795 0.7479<br />

Das Intervall wird in äquidistante Stücke der Länge 0.1 unterteilt und dann die Werte der Wurzelfunktion<br />

an den Intervallgrenzen in y gespeichert. Mit diesen Informationen füttern wir unsere Routine kspline,<br />

die uns das gewünschte Ergebnis zurückliefert.<br />

1.3 Visualisierung<br />

Im letzten Abschnitt haben wir die Koeffizienten der Polynome des kubischen Splines berechnet. <strong>Eine</strong><br />

weitere Stärke von <strong>MATLAB</strong> ist die Visualisierung. Deshalb wollen wir uns im folgenden noch eine weitere<br />

Funktion ansehen, die den Spline auf den Bildschirm plottet.<br />

1 function p l o t S p l i n e ( x , P )<br />

2 hold on ;<br />

3 g = 1 0 ;<br />

4 for i =1: length ( x)−1<br />

5 X = ( x ( i ) : ( x ( i +1)−x ( i ) ) / g : x ( i +1))−x ( i ) ;<br />

6 Y = P( i , : ) ∗ [ ones ( 1 , length (X) ) ; X; X. ^ 2 ; X. ^ 3 ] ;<br />

7 plot (X+x ( i ) ,Y) ;<br />

8 end<br />

9 hold o f f ;<br />

10 end<br />

Die Routine zeichnet die Funktion intervallweise, dazu verwenden wir eine for Schleife. Jedes Intervall<br />

verschieben wir in den Ursprung und unterteilen es in g=10 Teile auf denen wir das Polynom auswerten<br />

wollen. Die Koordinaten der Punkte speichern wir in X. Mit dem Befehl<br />

Y= P(i,:)*[ones(1,length(X)); X; X.^2; X.^3];<br />

berechnen wir das Skalarprodukt der i-ten Zeile der Matrix P mit dem Vektor der aus den Faktoren<br />

(x − xi) k , k = 0, . . . , 3 besteht für jede Stelle x aus X.<br />

Das eigentliche Plotten übernimmt der plot Befehl welcher in seiner einfachsten Version Vektoren mit<br />

x− und y−Koordinaten der Punkte erwartet. Diese werden automatische mit Geradenstücken verbunden.<br />

Normalerweise überschreibt <strong>MATLAB</strong> mit jedem plot Befehl die alte Graphik. Dies kann unterbunden<br />

werden durch die Angabe von hold on;.<br />

Der folgende Aufruf plottet den kubischen Spline und die Funktion sqrt(x) im Intervall [0, 1]:<br />

>> x=0:0.1:1;<br />

>> y=sqrt(x);<br />

>> xx=0:0.01:1;<br />

>> plotSpline(x, kspline(x,y)); hold on; plot(xx, sqrt(xx), ’r’);<br />

Abbildung 1.3 zeigt das Ergebniss.<br />

9


1.4 Erweiterung<br />

Abbildung 1.1: Kubischer Spline der Wurzelfunktion<br />

<strong>Eine</strong> weitere Qualität von <strong>MATLAB</strong> ist die einfache Möglichkeit vorhandene Algorithmen zu ersetzen.<br />

Wir wollen dies an der Funktion kspline vorführen.<br />

Bei Beispielen mit wenig Knotenpunkten arbeitet kspline recht schnell, wird die Zahl der Knotenpunkte<br />

jedoch groß, wird die Funktion überproportional langsamer, auch der Speicherbedarf steigt stark<br />

an. Die Erklärung hierfür ist, dass die Zeit für das Lösen des größer werdenden Gleichungssystems (1.1)<br />

n Zeit (1000 Ausführungen) Speicher Zeit (A dünn) Speicher (A dünn)<br />

100 0.79sec 93kB 0.87sec 17kB<br />

200 2.57sec 342kB 1.33sec 34kB<br />

400 32.00sec 1309kB 2.44sec 68kB<br />

800 138.00sec 5118kB 4.85sec 137kB<br />

1600 570.00sec 20237kB 9.64sec 275kB<br />

Tabelle 1.1: Laufzeiten von kspline<br />

nicht proportional mit der Anzahl der Unbekannten wächst. Die Matrix ist jedoch nur dünn besetzt (fast<br />

alle Einträge sind Null) und hat eine sehr einfache Struktur (Tridiagonal). Diese Tatsache wollen wir im<br />

Folgenden ausnutzen.<br />

<strong>MATLAB</strong> unterstützt dünnbesetzte Matrizen, hierbei werden im wesentlichen nur die Einträge gespeichert,<br />

die von Null verschieden sind. Zusätzlich erkennt der Gleichungssystemlöser die Bandstruktur der<br />

Matrix und verwendet effiziente Algorithmen um das System zu lösen. Das einzige was wir machen müssen<br />

um diese Funktionen zu verwenden ist die Matrix A dünn besetzt zu erzeugen, alles andere übernimmt<br />

<strong>MATLAB</strong> für uns. Dies können wir machen, in dem wir z.B. die Zeile 9 durch die folgende ersetzen:<br />

A = 2*speye(n) + spdiags([[lambda, 0]’, [mu, 0]’], [1, -1], n, n);<br />

Die neue Version berechnet die Lösung der Interpolationsaufgabe in optimaler Komplexität: Bei Verdoppelung<br />

der Punkte verdoppelt sich auch die Zeit (und Speicherbedarf) zum Berechnen des Splines (s.<br />

Tabelle 1.1).<br />

1.5 Zusammenfassung<br />

Wir haben in diesem Kapitel gesehen wie man einen Algorithmus mit wenigen Zeilen (25) in <strong>MATLAB</strong><br />

implementiert und sich das Ergebnis grafisch darstellen lassen kann.<br />

Zusätzlich konnten wir durch Ändern nur einer Zeile einen nicht optimale Methode in eine mit linearer<br />

Laufzeit umwandeln. <strong>MATLAB</strong> übernimmt die komplette Arbeit und verwendet automatischen einen<br />

optimalen Algorithmus um das Gleichungssystem zu lösen.<br />

10


Kapitel 2<br />

Vektoren und Matrizen<br />

Wie schon in der Einleitung erwähnt, ist der Umgang mit Feldern eine Besonderheit von <strong>MATLAB</strong>.<br />

Ein Verständnis dieser ist essentiell für die effektive Verwendung von <strong>MATLAB</strong>. Da aus mathematischer<br />

Sicht insbesondere Vektoren und Matrizen interessant sind, werden wir uns in dieser <strong>Einführung</strong> auf diese<br />

beschränken. Die Behandlung höherdimensionaler Felder erfolgt in vielen Fällen analog.<br />

2.1 Matrizen erzeugen<br />

Matrizen können auf mehrere Arten erzeugt werden. Viele Typen von Matrizen können direkt über eine<br />

<strong>MATLAB</strong> Funktion generiert werden. Die Nullmatrix, die Einheitsmatrix und Einsmatrizen können über<br />

die Funktionen zeros, eye und ones erzeugt werden. Alle haben die gleiche Syntax. Zum Beispiel erzeugt<br />

zeros(m,n) oder zeros([m,n]) eine m×n Nullmatrix, während zeros(n) eine n×n Nullmatrix erzeugt.<br />

>> zeros(2)<br />

ans =<br />

0 0<br />

0 0<br />

>> ones(2,3)<br />

ans =<br />

1 1 1<br />

1 1 1<br />

>> eye(3,2)<br />

ans =<br />

1 0<br />

0 1<br />

0 0<br />

Zwei andere Matrizen erzeugende Funktionen sind rand und randn, die Matrizen mit Pseudozufallszahlen<br />

als Einträgen generieren. Die Syntax ist die gleiche wie bei eye. Die Funktion rand erzeugt eine<br />

Matrix mit Zahlen aus der Gleichverteilung über dem Einheitsintervall [0, 1]. 1 randn erzeugt eine Matrix<br />

deren Einträge standardnormalverteilt sind. Ohne Argumente geben beide Funktionen eine einzelne<br />

Zufallszahl zurück.<br />

>> rand<br />

ans =<br />

0.9501<br />

1 Für diese Verteilung ist der Anteil der Zahlen aus einem Intervall [a, b] mit 0 < a < b < 1 stets b − a.<br />

11


and(3)<br />

ans =<br />

0.2311 0.8913 0.0185<br />

0.6068 0.7621 0.8214<br />

0.4860 0.4565 0.2835<br />

Bei Experimenten mit Zufallszahlen ist es oft wichtig, die gleichen Zufallszahlen erneut zu erzeugen.<br />

Die Zahlen, die von rand (bzw. randn) erzeugt werden hängen vom Zählerstand des Generators ab.<br />

Dieser Zähler kann über den Befehl rand(’state’,j) (bzw. randn(’state’,j)) gesetzt werden, mit<br />

einer nicht-negativen ganzen Zahl j. j=0 ist der Anfangszustand des Generators (diesen Zustand hat<br />

der Generator, wenn <strong>MATLAB</strong> startet). Möchte man nicht bei jedem Start von <strong>MATLAB</strong> dieselben<br />

Zufallszahlen zu bekommen, sollte der Generator durch den Befehl rand(’state’,sum(100*clock)) auf<br />

einen von der Zeit abhängigen Zustand gesetzt werden. Die Periode von rand und randn, also die Anzahl<br />

Terme die erzeugt werden, bevor sich Teilfolgen wiederholen, übersteigt 2 1492 ≈ 10 449 .<br />

Mit der Funktion diag können Diagonalmatrizen angelegt werden. Für einen Vektor x erzeugt diag(x)<br />

eine Diagonalmatrix mit der Diagonale x.<br />

>> diag([1 2 3])<br />

ans =<br />

1 0 0<br />

0 2 0<br />

0 0 3<br />

Allgemeiner legt diag(x,k) x auf die k-te Diagonale, wobei k > 0 Diagonalen über der Hauptdiagonalen<br />

beschreibt, und k < 0 die darunter (k = 0 bezeichnet die Hauptdiagonale).<br />

>> diag([1 2],1)<br />

ans =<br />

0 1 0<br />

0 0 2<br />

0 0 0<br />

>> diag([3 4],-2)<br />

ans =<br />

0 0 0 0<br />

0 0 0 0<br />

3 0 0 0<br />

0 4 0 0<br />

Matrizen können explizit über die Klammernotation (square bracket notation) erzeugt werden. Zum<br />

Beispiel kann eine 3x3-Matrix mit den ersten neun Primzahlen mit folgendem Befehl erzeugt werden:<br />

>> A = [2 3 5<br />

7 11 13<br />

17 19 23]<br />

A =<br />

2 3 5<br />

7 11 13<br />

17 19 23<br />

Das Ende einer Zeile kann über ein Semikolon anstatt eines Zeilenumbruchs angegeben werden. Ein<br />

kürzere Variante des letzten Beispiels ist also:<br />

>> A = [2 3 5; 7 11 13; 17 19 23]<br />

12


Innerhalb einer Zeile können einzelne Elemente über ein Leerzeichen oder Komma getrennt werden.<br />

In ersterem Fall sollte beachtet werden, dass bei Angabe von Vorzeichen für die einzelnen Einträge<br />

kein Leerzeichen zwischen Vorzeichen und Element gelassen werden darf. <strong>MATLAB</strong> interpretiert das<br />

Vorzeichen sonst als Plus oder Minus Operator.<br />

>> v = [-1 2 -3 4]<br />

v =<br />

-1 2 -3 4<br />

>> w = [-1,2,-3,4]<br />

w =<br />

-1 2 -3 4<br />

>> x = [-1 2 - 3 4]<br />

x =<br />

-1 -1 4<br />

Häufig sehr praktisch ist das Erzeugen von Matrizen durch Angabe von Blöcken, anstatt der einzelnen<br />

Elemente. Sei z.B. B=[1 2; 3 4]:<br />

>> C = [B zeros(2); ones(2) eye(2)]<br />

C =<br />

1 2 0 0<br />

3 4 0 0<br />

1 1 1 0<br />

1 1 0 1<br />

Blockdiagonalmatrizen können noch einfacher direkt über die Funktion blkdiag erzeugt werden.<br />

>> A = blkdiag(B,ones(2))<br />

A =<br />

1 2 0 0<br />

3 4 0 0<br />

0 0 1 1<br />

0 0 1 1<br />

Für ”getäfelte” Blockmatrizen eignet sich repmat: repmat(A,m,n) erzeugt eine Block-m × n-Matrix, in<br />

der jeder Block eine Kopie von A ist. Wird n weggelassen, wird der Wert standardmäßig auf m gesetzt.<br />

>> B=[1,2;3,4];<br />

>> A = repmat(B,2)<br />

A =<br />

1 2 1 2<br />

3 4 3 4<br />

1 2 1 2<br />

3 4 3 4<br />

2.1.1 Spezielle Matrizen<br />

<strong>MATLAB</strong> verfügt über Funktionen um ganz spezielle Matrizen zu erzeugen. Ein Beispiel hierfür sind die<br />

Hilbertmatrizen, deren Elemente aij den Wert 1/(i + j − 1) haben. Die Matrix wird durch den Befehl<br />

hilb erzeugt, und ihre Inverse (die nur ganzzahlige Komponenten hat!) über invhilb.<br />

Quadratische n × n Matrizen die nur aus den Zahlen 1, . . . , n 2 bestehen, deren Zeilen- und Spaltensummen<br />

und Summe der Einträge der Diagonalen gleich ist nennt man magische Quadrate. Diese können<br />

mit <strong>MATLAB</strong> durch die Funktion magic erzeugt werden.<br />

13


magic(3)<br />

ans =<br />

8 1 6<br />

3 5 7<br />

4 9 2<br />

Über fünfzig weitere spezielle und berühmte Matrizen können mit dem Befehl gallery erzeugt werden,<br />

diese sind teilweise dünn besetzt. Mehr über diese speziellen Matrizen erfährt man in der Hilfe.<br />

2.1.2 Doppelpunkt Operator<br />

Der Doppelpunkt Operator ist einer der wichtigsten Operatoren in <strong>MATLAB</strong> und findet in vielen Fällen<br />

Verwendung. Mit seiner Hilfe können spezielle Zeilenvektoren erzeugt werden, die z.B. bei der Indizierung<br />

in for Schleifen oder beim Plotten verwendet werden. Dabei wird ausgehend von einer Zahl solange eine<br />

Einheit addiert und in dem Vektor gespeichert, bis ein vorgegebenes Ende erreicht oder überschritten<br />

wurde. Die allgemeine Syntax ist<br />

: oder ::.<br />

Ein paar Beispiele sollte die Verwendung deutlich machen:<br />

>> j=1:5<br />

j =<br />

1 2 3 4 5<br />

>> X=1.2:0.2:2<br />

X =<br />

1.2000 1.4000 1.6000 1.8000 2.0000<br />

>> X=1:-0.3:0<br />

X =<br />

1.0000 0.7000 0.4000 0.1000<br />

Dem Doppelpunkt Operator verwandt ist die Funktion linspace, die als Eingabe neben Start und<br />

Ende die Anzahl der zu erzeugenden Punkte verlangt anstatt des Abstandes. linspace(a,b,n) erzeugt<br />

n Punkte gleichen Abstands zwischen a und b. Der Standardwert für n ist 100.<br />

>> linspace(-1,1,9)<br />

ans =<br />

Columns 1 through 6<br />

-1.0000 -0.7500 -0.5000 -0.2500 0 0.2500<br />

Columns 7 through 9<br />

0.5000 0.7500 1.0000<br />

2.2 Indizierung und Doppelpunktnotation<br />

Die Indizierung von Feldern erfolgt in <strong>MATLAB</strong> durch runde Klammern und startet wie bei Fortran<br />

beim Index 1. Bei Matrizen steht der erste Index für die Zeilen-, der zweite für die Spaltennummer des<br />

Elements.<br />

>> A=rand(2,2)<br />

14


A =<br />

0.6557 0.8491<br />

0.0357 0.9340<br />

>> A(1,1)<br />

ans =<br />

0.6557<br />

>> A(2,1)<br />

ans =<br />

0.0357<br />

Es gibt bei <strong>MATLAB</strong> keine nicht positiven Indices, der Versuch wird durch eine Fehlermeldung bestraft:<br />

>> A(0,0)<br />

??? Attempted to access A(0,0); index must be a positive integer or logical.<br />

Ein Vorteil von <strong>MATLAB</strong> gegenüber anderen Programmiersprachen ist, dass nicht nur auf die einzelnen<br />

Elemente eines Feldes zugegriffen werden kann, sondern auf beliebige Teilblöcke. Dafür ersetzt<br />

man einfach beim Indizieren die Zahlen durch Vektoren. Sei A eine n × m-Matrix und r und c Vektoren<br />

mit positiven ganzzahligen Elementen kleiner gleich n (bzw. m). Dann ist B=A(r,c) eine Matrix mit<br />

Einträgen bij =A(r(i),c(j)).<br />

>> A=[1,2,3;4,5,6;7,8,9]<br />

A =<br />

1 2 3<br />

4 5 6<br />

7 8 9<br />

>> A([1,2],3)<br />

ans =<br />

3<br />

6<br />

>> A([2,3],[2,3])<br />

ans =<br />

5 6<br />

8 9<br />

Besonders häufig wird in diesen Fällen der Doppelpunktoperator verwendet. Die Teilmatrix bestehend<br />

aus der Schnittmenge der Zeilen p bis q und den Spalten r bis s wird mit A(p:q,r:s) zurückgegeben. Ein<br />

Sonderfall ist ein einzelner Doppelpunkt, dieser wählt sämtliche Zeilen oder Spalten; A(:,j) bezeichnet<br />

also die j-te Spalte, und A(i,:) die i-te Zeile von A. Das Schlüsselwort end steht für den letzten Index in<br />

der angegebenen Dimension; A(end,:) bezeichnet also die letzte Zeile von A.<br />

>> A(1:3,2:end)<br />

ans =<br />

2 3<br />

5 6<br />

8 9<br />

>> A(1,:)<br />

ans =<br />

15


1 2 3<br />

>> A(:,end)<br />

ans =<br />

3<br />

6<br />

9<br />

<strong>MATLAB</strong> speichert alle Felder intern als Spaltenvektor, Matrizen spaltenweise von der ersten zur<br />

letzten Spalte. Auf diese Repräsentation kann durch Angabe nur eines Indizes zugegriffen werden, dies<br />

wird häufig lineares Indizieren genannt.<br />

>> A(:)<br />

ans =<br />

1<br />

4<br />

7<br />

2<br />

5<br />

8<br />

3<br />

6<br />

9<br />

>> A(4)<br />

ans =<br />

2<br />

Wird A(:) auf der linken Seite einer Zuweisung benutzt, so wird damit A gefüllt, unter Beibehaltung<br />

der Struktur von A. Mit dieser Notation ergibt sich eine Möglichkeit auf folgende Weise eine 3×3 - Matrix<br />

der ersten 9 Primzahlen zu erzeugen:<br />

>> A = zeros(3); A(:) = primes(23); A = A’<br />

A =<br />

2 3 5<br />

7 11 13<br />

17 19 23<br />

Die Funktion primes erzeugt einen Vektor von Primzahlen, die kleiner oder gleich dem Eingabeargument<br />

sind. Die Transposition A = A’ ist nötig um die Primzahlen entlang der Zeilen anstatt entlang der<br />

Spalten anzuordnen.<br />

<strong>Eine</strong> weitere Funktion die beim Indizieren hilfreich ist, ist sub2ind. Diese berechnet aus Matrixindizes<br />

lineare Indizes. Hiermit können wir z.B. die Diagonale der obigen Matrix A mit 1 überschreiben.<br />

>> A(sub2ind(size(A), 1:3, 1:3))=1<br />

A =<br />

1 3 5<br />

7 1 13<br />

17 19 1<br />

2.3 Operatoren und Funktionen<br />

Um ein Feld zu transponieren stellt <strong>MATLAB</strong> die Operatoren ’ und .’ zur Verfügung. Die Operatoren<br />

unterscheiden sich, wenn die Einträge des Feldes komplex sind, ’ erzeugt die adjungierte Matrix A ∗ , .’<br />

die Transponierte A T .<br />

16


A=[1+i , 2-i; 1 , 2]<br />

A =<br />

1.0000 + 1.0000i 2.0000 - 1.0000i<br />

1.0000 2.0000<br />

>> A’<br />

ans =<br />

1.0000 - 1.0000i 1.0000<br />

2.0000 + 1.0000i 2.0000<br />

>> A.’<br />

ans =<br />

1.0000 + 1.0000i 1.0000<br />

2.0000 - 1.0000i 2.0000<br />

2.3.1 Rechenoperatoren<br />

<strong>MATLAB</strong> unterstützt das Rechnen mit Vektoren und Matrizen. So können zwei Felder gleicher Dimensionen<br />

einfach durch + addiert und mit - subtrahiert werden:<br />

>> x=1:3;<br />

>> y=2:4;<br />

>> x+y<br />

ans =<br />

3 5 7<br />

>> eye(2)-ones(2)<br />

ans =<br />

0 -1<br />

-1 0<br />

<strong>MATLAB</strong> interpretiert den Multiplikationsoperator * als Matrixprodukt oder als Multiplikation mit<br />

einem Skalar. Bei ersterem muss die Anzahl der Spalten des ersten Arguments gleich der Anzahl der<br />

Zeilen des zweiten Argumentes sein. Daneben gibt es noch den elementweisen Multiplikationsoperator<br />

.*.<br />

>> x=1:3;<br />

>> y=2:4;<br />

>> x*y<br />

??? Error using ==> mtimes<br />

Inner matrix dimensions must agree.<br />

>> x*y’<br />

ans =<br />

20<br />

>> x.*y<br />

ans =<br />

2 6 12<br />

>> A=[1,2,3;4,5,6;7,8,9];<br />

>> A*y<br />

17


ans =<br />

20<br />

47<br />

74<br />

>> 2*A<br />

ans =<br />

2 4 6<br />

8 10 12<br />

14 16 18<br />

Auch das Potenzieren ^ wird im Matrixprodukt Sinn interpretiert, analog zur Multiplikation gibt es auch<br />

die „gepunktete“ Version .^.<br />

Die Division gibt es in zwei Ausführungen: den Slash / und den Backslash \. Beide entsprechem dem<br />

(ggf. approximativen) Lösen eines linearen Gleichungssystems. B/A steht ungefähr für BA −1 , A\B für<br />

A −1 B). Mit diesen Operatoren befassen wir uns ausführlich in Abschnitt 5.2.<br />

>> A=hilb(2);<br />

>> b=[1;2]<br />

b =<br />

1<br />

2<br />

>> A\b<br />

ans =<br />

-8<br />

18<br />

>> invhilb(2)*b<br />

ans =<br />

-8<br />

18<br />

Natürlich gibt es auch wieder das elementweise dividieren ./, dieses muss auch eingesetzt werden, wenn<br />

ein Skalar durch einen Vektor geteilt wird.<br />

>> x=1:3<br />

>> 3/x<br />

??? Error using ==> mrdivide<br />

Matrix dimensions must agree.<br />

>> 3./x<br />

ans =<br />

3.0000 1.5000 1.0000<br />

>> x./x<br />

ans =<br />

1 1 1<br />

2.3.2 Basisfunktionen<br />

Um Eigenschaften wie die Länge oder Dimensionen von Feldern abzufragen gibt es in <strong>MATLAB</strong> eine<br />

Hand voll Funktionen:<br />

18


length Gibt die Länge eines Vektors zurück, bei einer Matrix wird die größere der beiden Dimensionen<br />

zurückgegeben.<br />

size Gibt die Dimensionen einer Matrix zurück.<br />

numel Gibt die Anzahl der Elemente einer Matrix zurück, numel(A)==prod(size(A))==length(A(:))<br />

>> B=[1,2;2,3;4,5]<br />

B =<br />

1 2<br />

2 3<br />

4 5<br />

>> length(B)<br />

ans =<br />

3<br />

>> size(B)<br />

ans =<br />

3 2<br />

>> numel(B)<br />

ans =<br />

6<br />

2.3.3 Funktionen<br />

<strong>MATLAB</strong> verfügt über unzählige Funktionen die Vektoren und Matrizen als Eingabe erwarten. Grundsätzlich<br />

verändert eine Funktion in <strong>MATLAB</strong> kein Eingabeargument. 2 Viele dieser Methoden kann man<br />

einer von drei Gruppen zuordnen:<br />

• Skalare Funktionen<br />

• Vektorfunktionen<br />

• Matrixfunktionen<br />

Skalare Funktionen sind solche, die komponentenweise wirken. Beispiele sind sin, cos, exp und<br />

factorial (Fakultät). Übergibt man diesen Funktionen ein mehrdimensionales Feld, hat die Rückgabe<br />

die gleiche Dimensionen wie das Eingabeargument und die Funktion wurde auf jeden Eintrag des<br />

Feldes angewendet.<br />

>> x=linspace(-pi/2,pi/2,5)<br />

x =<br />

-1.5708 -0.7854 0 0.7854 1.5708<br />

>> sin(x)<br />

ans =<br />

-1.0000 -0.7071 0 0.7071 1.0000<br />

>> A=magic(3);<br />

>> factorial(A)<br />

ans =<br />

2 Eingabeargumente werden als Wert und nicht als Referenz übergeben.<br />

19


40320 1 720<br />

6 120 5040<br />

24 362880 2<br />

Vektorwertige Funktionen operieren auf Vektoren und geben ein Skalar oder einen Vektor zurück.<br />

Beispiele sind max, sum, prod mit skalarem Rückgabewert, diff (Differenz jeweils aufeinander folgender<br />

Elemente), cumsum oder sort geben einen Vektor zurück. Übergibt man diesem Typ von Funktion eine<br />

Matrix, wird die Funktion auf jede Spalte angewendet und die Rückgabe wieder in eine Spalte geschrieben.<br />

>> x=1:4;<br />

>> sum(x)<br />

ans =<br />

10<br />

>> max(x)<br />

ans =<br />

4<br />

>> diff(x)<br />

ans =<br />

1 1 1<br />

>> A=magic(3);<br />

>> sum(A)<br />

ans =<br />

15 15 15<br />

>> cumsum(A)<br />

ans =<br />

8 1 6<br />

11 6 13<br />

15 15 15<br />

Viele vektorwertige Funktionen unterstützen die Übergabe eines zweiten Parameters dim, der die Dimension<br />

(1=Spalten, 2=Zeilen) angibt, über welche die Funktion ausgeführt werden soll. Damit ist es also<br />

z.B. auch einfach möglich die Summe der Zeilen von A zu berechnen:<br />

>> sum(A,2)<br />

ans =<br />

15<br />

15<br />

15<br />

Möchte man diese Funktion nicht auf die Spalten einer Matrix A sondern auf die ganze Matrix -als<br />

Vektor aufgefasst- anwenden, übergibt man A(:) als Eingabeargument (vgl. 2.2).<br />

>> sum(A(:))<br />

ans =<br />

45<br />

Matrixfunktionen erwarten als Eingabe eine Matrix. Beispiele sind norm, chol, triu und tril. Die<br />

letzten beiden Funktionen extrahieren aus einer gegebenen Matrix eine obere, bzw. untere Dreiecksmatritzen.<br />

Allgemein gibt tril(A,k) (bzw. triu(A,k)) die Elemente auf und unter (bzw. ober) der k-ten<br />

Diagonale zurück.<br />

20


A = [2 3 5; 7 11 13; 17 19 23]<br />

A =<br />

2 3 5<br />

7 11 13<br />

17 19 23<br />

>> tril(A)<br />

ans =<br />

2 0 0<br />

7 11 0<br />

17 19 23<br />

>> triu(A,1)<br />

ans =<br />

0 3 5<br />

0 0 13<br />

0 0 0<br />

2.4 Matrizen manipulieren<br />

Es gibt mehrere Befehle für die Manipulation von Matrizen. Die Funktion reshape ändert die Dimensionen<br />

einer Matrix: reshape(A,m,n) erzeugt eine m × n Matrix, deren Elemente spaltenweise aus A<br />

entnommen werden.<br />

>> A = [1 4 9; 16 25 36], B = reshape(A,3,2)<br />

A =<br />

B =<br />

1 4 9<br />

16 25 36<br />

1 25<br />

16 9<br />

4 36<br />

Die Notation [] steht für eine leere 0 × 0-Matrix. Weist man einer Zeile oder Spalte einer Matrix den<br />

Wert [] zu, so wird sie aus der Matrix gelöscht.<br />

>> A=magic(3)<br />

A =<br />

8 1 6<br />

3 5 7<br />

4 9 2<br />

>> A(2,:)=[]<br />

A =<br />

8 1 6<br />

4 9 2<br />

In diesem Beispiel würde der gleiche Effekt durch A = A([1 3],:) erzielt werden. Die leere Matrix<br />

ist auch als Platzhalter in Argumentlisten nützlich.<br />

An einen vorhandenen Vektor können einfach weitere Elemente angehängt werden, indem man einem<br />

Index der größer als die Länge des Vektors ist, einen Wert zuweist. Der Vektor wird daraufhin automatisch<br />

bis zu dem entsprechenden Index verlängert und mit Nullen gefüllt.<br />

21


x=1:3;<br />

>> x(6)=9<br />

x =<br />

1 2 3 0 0 9<br />

Auf dieselbe Weise können neue Zeilen und Spalten an eine Matrix angehängt werden:<br />

>> A=eye(2)<br />

A =<br />

1 0<br />

0 1<br />

>> A(3,:)=[1,1]<br />

A =<br />

1 0<br />

0 1<br />

1 1<br />

>> A(:,3)=2<br />

A =<br />

1 0 2<br />

0 1 2<br />

1 1 2<br />

>> A=eye(2)<br />

A =<br />

1 0<br />

0 1<br />

>> A(3,3)=2<br />

A =<br />

1 0 0<br />

0 1 0<br />

0 0 2<br />

22


Kapitel 3<br />

Operatoren und Flusskontrolle<br />

3.1 Relationale Operatoren<br />

Die relationalen Operatoren von <strong>MATLAB</strong> sind<br />

== gleich<br />

~= ungleich<br />

< weniger als<br />

> größer als<br />

= größer oder gleich<br />

Tabelle 3.1: Die relationalen Operatoren in <strong>MATLAB</strong><br />

Beachten Sie, dass in <strong>MATLAB</strong> ein einzelnes Gleichheitszeichen = eine Zuweisung angibt und nie auf<br />

Gleichheit testet. Vergleiche zwischen Skalaren erzeugen logisch 1 wenn die Relation wahr und logisch<br />

0 wenn sie falsch ist. <strong>MATLAB</strong> verwenden hier intern keine doubles sondern einen anderen Datentyp<br />

(logical), dies sollte aber in den wenigsten Fällen zu Problemen führen.<br />

Vergleiche sind auch zwischen Matrizen gleicher Dimension definiert und zwischen Matrizen und Skalaren,<br />

deren Ergebnis in beiden Fällen eine Matrix mit Nullen und Einsen ist. Für Matrix-Matrix Vergleiche<br />

werden die entsprechenden Paare von Elementen verglichen, während für Matrix-Skalar Vergleiche der<br />

Skalar mit jedem Matrixelement verglichen wird.<br />

>> A = [1 2; 3 4]; B = 2*ones(2);<br />

>> A==B<br />

ans =<br />

0 1<br />

0 0<br />

>> A>2<br />

ans =<br />

0 0<br />

1 1<br />

Um zu testen ob zwei Matrizen A und B gleich sind, kann der Ausdruck isequal(A,B) verwendet<br />

werden. Die Funktion isequal is eine der vielen nützlichen logischen Funktionen, deren Namen mit is<br />

beginnt. Für eine Liste aller dieser Funktionen rufen sie in <strong>MATLAB</strong> doc is auf. Die Funktion isnan<br />

ist besonders wichtig, da der Test x == NaN immer das Ergebnis 0 (falsch) liefert, selbst wenn x = NaN!<br />

(Ein NaN ist gerade so definiert, dass er zu allem ungleich und ungeordnet ist).<br />

3.2 Logische Operatoren<br />

Die logischen Operatoren von <strong>MATLAB</strong> sind<br />

23


& logisches und<br />

| logisches oder<br />

∼ logisches nicht<br />

xor logisches exklusives oder<br />

all wahr wenn alle Elemente eines Vektors von<br />

Null verschieden sind<br />

any wahr wenn wenigstens ein Element eines Vektors<br />

von Null verschieden ist<br />

Tabelle 3.2: Die logischen Operatoren in <strong>MATLAB</strong><br />

Wie die relationalen Operatoren produzieren &,| und ∼ Matrizen von Nullen und Einsen, falls eines<br />

der Argumente eine Matrix ist. Die Funktion all gibt, wenn sie auf einen Vektor angewendet wird, 1<br />

zurück wenn alle Elemente des Vektors verschieden von 0 sind, und 0 sonst. Die any Funktion ist ebenfalls<br />

so definiert, wobei ’irgendeiner’ hier ’alle’ ersetzt. Beispiele:<br />

>> x = [-1 1 1]; y = [1 2 -3];<br />

>> x>0 & y>0<br />

ans =<br />

0 1 0<br />

>> x>0 | y>0<br />

ans =<br />

1 1 1<br />

>> xor(x>0,y>0)<br />

ans =<br />

1 0 1<br />

>> any(x>0)<br />

ans =<br />

1<br />

>> all(x>0)<br />

ans =<br />

0<br />

Beachte, dass xor als Funktion xor(a,b) aufgerufen werden muss. Die Operatoren and, or, not und<br />

die relationalen Operatoren können ebenfalls in funktionaler Form aufgerufen werden, and(a,b) ...(mehr<br />

dazu unter help ops).<br />

Die Funktionen all und any sind Vektorfunktionen (vgl. Abschnitt 2.3.3), deshalb gibt all auf Matrizen<br />

angewandt einen Zeilenvektor zurück der die Ergebnisse von all angewendet auf die Spaltenvektoren<br />

enthält. Mit all(A(:)==B(:)) können die beiden Matrizen A und B auf Gleichheit getestet werden.<br />

3.2.1 Indizierung mit logischen Feldern<br />

Die Rückgabewerte von <strong>MATLAB</strong>s relationalen und logischen Operatoren sind Felder bestehend aus<br />

Nullen und Einsen. Diese sind Beispiele für logische Felder. Sie können auch per Hand erzeugt werden,<br />

indem man den Befehl logical auf ein reelles Feld anwendet. Hierbei werden alle Einträge ungleich 0 zu<br />

logisch 1, alle Einträge gleich 0 zu logisch 0 konvertiert.<br />

>> y=[1 0.2 0 -3 0]<br />

y =<br />

24


1.0000 0.2000 0 -3.0000 0<br />

>> i1 = logical(y)<br />

i1 =<br />

1 1 0 1 0<br />

>> i2 = (y~=0)<br />

i2 =<br />

1 1 0 1 0<br />

Logische Felder können zur Indizierung verwendet werden, hierbei muss das zu indizierende Feld die<br />

gleichen Dimensionen wie das logische Feld haben. Das Ergebnis sind alle Einträge bei denen logisch 1<br />

steht als Spaltenvektor.<br />

>> i3 = [1 1 0 1 0]<br />

i3 =<br />

1 1 0 1 0<br />

>> whos<br />

Name Size Bytes Class<br />

i1 1x5 40 double array (logical)<br />

i2 1x5 40 double array (logical)<br />

i3 1x5 40 double array<br />

y 1x5 40 double array<br />

Grand total is 20 elements using 160 bytes<br />

>> y(i1)<br />

ans =<br />

1.0000 0.2000 -3.0000<br />

>> y(i2)<br />

ans =<br />

1.0000 0.2000 -3.0000<br />

>> isequal(i2,i3)<br />

ans =<br />

1<br />

>> y(i3) ??? Index into matrix is negative or zero. See release<br />

notes on changes to logical indices.<br />

Merke, dass obwohl i2 die gleichen Elemente wie i3 hat (und in <strong>MATLAB</strong> auch als identisch angesehen<br />

wird), nur i2 zur Indizierung verwendet werden kann.<br />

Logische Indizierung wird meistens in Verbindung mit relationalen Operatoren angewandt, z.B. um<br />

die negativen Einträge einer Matrix auf Null zu setzen:<br />

>> A=rand(3)-0.5*ones(3)<br />

A =<br />

0.4649 0.4572 -0.3581<br />

-0.3424 -0.0146 -0.0782<br />

0.4706 0.3003 0.4157<br />

25


A(A> x = [-3 1 0 -inf 0];<br />

>> f=find(x)<br />

f =<br />

1 2 4<br />

Wenn find auf eine Matrix angewendet wird, bezieht sich der Indexvektor auf A als Vektor seiner<br />

Spaltenvektoren (also A(:)), und dieser Vektor kann wiederum verwendet werden, um Elemente in A<br />

anzusprechen. Im folgenden Beispiel benutzen wir find um alle Elemente von A auf 0 zu setzen, die<br />

kleiner sind als die entsprechenden Elemente von B:<br />

>> A=[4 2 16; 12 4 3], B = [12 3 1; 10 -1 7]<br />

A =<br />

B =<br />

4 2 16<br />

12 4 3<br />

12 3 1<br />

10 -1 7<br />

>> f = find(A> A(f) = 0<br />

A =<br />

0 0 16<br />

12 4 0<br />

>> A=[4 2 16; 12 4 3];<br />

>> A(A


if expression<br />

statements<br />

end<br />

statements werden ausgeführt, wenn die Realteile der Elemente von expression alle verschieden von 0<br />

sind. Der folgende Code ersetzt zum Beispiel x und y wenn x größer ist als y:<br />

if x > y<br />

temp = y;<br />

y = x;<br />

x = temp;<br />

end<br />

Folgen auf einen if-Befehl auf der gleichen Zeile weitere Befehle, so müssen diese durch ein Komma<br />

getrennt werden, um das if-Kommando vom nächsten Befehl zu trennen.<br />

>> if x > 0, sqrt(x);end<br />

Befehle die nur ausgeführt werden sollen, wenn expression falsch ist, können nach else eingefügt<br />

werden.<br />

>> e = exp(1);<br />

>> if 2^e > e^2<br />

disp(’2^e is bigger’)<br />

else<br />

disp(’e^2 is bigger’)<br />

end<br />

Schließlich kann mit elseif ein weiterer Test hinzugefügt werden mit (beachte, dass zwischen else<br />

und if kein Leerzeichen stehen darf):<br />

if isnan(x)<br />

disp(’Not a Number’)<br />

elseif isinf(x)<br />

disp(’Plus or minus infinity’)<br />

else<br />

disp(’A ’’regular’’ floating point number’)<br />

end<br />

Bei einer if-Abfrage der Form if Bedingung 1 & Bedingung 2 wird Bedingung 2 nicht ausgewertet,<br />

wenn Bedingung 1 falsch ist (dies wird ”early return” if Auswertung genannt). Dies ist nützlich, wenn<br />

die Auswertung von Bedingung 2 ansonsten einen Fehler produzieren könnte, zum Beispiel durch einen<br />

Index außerhalb des zulässigen Bereichs oder eine nicht definierte Variable.<br />

Die for-Schleife ist einerseits eine der wichtigsten Strukturen in <strong>MATLAB</strong>, andererseits vermeiden<br />

viele Programmierer, die kurzen und schnellen Code produzieren wollen, dessen Verwendung. Die Syntax<br />

lautet:<br />

for variable = ausdruck<br />

statements<br />

end<br />

Normalerweise ist ausdruck ein Vektor der Form i:s:j. Die Befehle werden für jedes Element von<br />

ausdruck ausgeführt, wobei variable dem entsprechenden Element von ausdruck zugeordnet ist. Zum<br />

Beispiel wird die Summe der ersten 25 Elemente der harmonischen Folge 1/i erzeugt durch:<br />

>> s = 0;<br />

>> for i=1:25, s=s+1/i;end,s<br />

s =<br />

3.8160<br />

<strong>Eine</strong> weitere Möglichkeit um ausdruck zu definieren ist, die Klammernotation zu verwenden.<br />

27


for x = [pi/6 pi/4 pi/3], disp([x,sin(x)]), end<br />

0.5236 0.5000<br />

0.7854 0.7071<br />

1.0472 0.8660<br />

Mehrere for-Schleifen können verschachtelt werden. In diesem Fall hilft einrücken, um die Lesbarkeit<br />

des Codes zu erhöhen. Der folgende Code bildet die symmetrische 5x5-Matrix A = (aij) mit aij = i/j<br />

für j >= i:<br />

>> n = 5; A = eye(n);<br />

>> for j=2:n<br />

for i = 1:j-1<br />

A(i,j) = i/j;<br />

A(j,i) = i/j;<br />

end<br />

end<br />

Der ausdruck in der for-Schleife kann eine Matrix sein, in diesem Fall wird variable der Spaltenvektor<br />

zugewiesen, vom Ersten zum Letzten. Zum Beispiel, um x in der Reihenfolge auf jeden Einheitsvektor<br />

zu setzen, kann man for x = eye(n),...,end schreiben.<br />

Die while-Schleife hat die Form<br />

while ausdruck<br />

statements<br />

end<br />

Die Befehle werden ausgeführt, so lange ausdruck wahr ist. Das folgende Beispiel nähert die kleinste<br />

von Null verschiedene Gleitkommazahl an:<br />

>> x=1; while x>0, xmin = x; x = x/2; end, xmin<br />

xmin =<br />

4.9407e-324<br />

<strong>Eine</strong> while-Schleife kann mit dem Befehl break beendet werden, der die Kontrolle an den ersten Befehl<br />

nach dem entsprechenden end zurückgibt. <strong>Eine</strong> unendliche Schleife kann mit while 1, ..., end erzeugt<br />

werden. Dies kann nützlich sein, wenn es ungünstig ist, den Abbruchtest an den Anfang der Schleife zu<br />

setzen. (Merke, dass <strong>MATLAB</strong> im Gegensatz zu manch anderen Sprachen keine ”repeat-until” Schleife<br />

hat.)<br />

Das vorige Beispiel lässt sich damit auch folgendermaßen notieren:<br />

x = 1;<br />

while 1<br />

xmin = x;<br />

x = x/2;<br />

if x == 0, break, end<br />

end<br />

xmin<br />

Der Befehl break kann auch verwendet werden, um eine for-Schleife zu verlassen. In einer verschachtelten<br />

Schleife führt ein break zum Verlassen der Schleife auf der nächsthöheren Ebene. Der Befehl<br />

continue setzt die Ausführung sofort in der nächsten Iteration der for- oder while-Schleife fort, ohne<br />

die verbleibenden Befehle in der Schleife auszuführen.<br />

for i=1:10<br />

if i < 5, continue, end<br />

disp(i)<br />

end<br />

28


In komplexeren Schleifen kann continue verwendet werden um umfangreiche if-Abfragen zu vermeiden.<br />

Zuletzt bleibt noch der Kontrollbefehl switch. Er besteht aus ”switch Ausdruck”, gefolgt von einer<br />

Liste von<br />

”case Ausdruck Befehl”, die optional mit<br />

”otherwise Ausdruck” enden und mit einem end beendet werden. Der Ausdruck bei switch wird<br />

ausgewertet und die Befehle nach dem ersten passenden case Ausdruck werden ausgeführt. Falls keiner<br />

der Fälle passt, werden die Befehle nach otherwise ausgeführt. Das folgende Beispiel wertet die p-Norm<br />

eines Vektors x aus (also norm(x,p)):<br />

switch p<br />

case 1<br />

y = sum(abs(x));<br />

case 2<br />

y = sqrt(x’*x);<br />

case inf<br />

y = max(abs(x));<br />

otherwise<br />

error(’p must be 1, 2 or inf.’)<br />

end<br />

Der Ausdruck nach case kann eine Liste von Werten sein, die in geschweiften Klammern eingeschlossen<br />

ist (ein Cell-Array). In diesem Fall kann der switch-Ausdruck zu jedem Element der Liste passen.<br />

x = input(’Enter a real number: ’); switch x<br />

case {inf,-inf}<br />

disp(’Plus or minus infinity’)<br />

case 0<br />

disp(’Zero’)<br />

otherwise<br />

disp(’Nonzero and finite’)<br />

end<br />

C Programmierer seien darauf hingewiesen, dass das switch-Konstrukt von <strong>MATLAB</strong> sich anders<br />

verhält als das von C: Sobald ein <strong>MATLAB</strong> case Ausdruck zur Variable passt und die Befehle ausgeführt<br />

wurden, wird die Kontrolle an den ersten Befehl nach dem switch-Block übergeben, ohne dass weitere<br />

break Befehle nötig sind.<br />

29


Kapitel 4<br />

M-Dateien<br />

Viele nützliche Berechnungen lassen sich über die Kommandozeile von <strong>MATLAB</strong> durchführen. Nichtsdestotrotz<br />

wird man früher oder später M-Dateien schreiben müssen. Diese sind das Pendant zu Programmen,<br />

Funktionen, Subroutinen und Prozeduren in anderen Programmiersprachen. Fügt man eine Folge<br />

von Befehlen zu einer M-Datei zusammen, ergeben sich vielfältige Möglichkeiten, wie etwa<br />

• an einem Algorithmus herumzuexperimentieren indem man eine Datei bearbeitet, anstatt eine lange<br />

Liste von Befehlen wieder und wieder zu tippen<br />

• einen dauerhaften Beleg für ein numerisches Experiment schaffen<br />

• nützliche Funktionen aufzubauen die zu einem späteren Zeitpunkt erneut verwendet werden können<br />

• M-Dateien mit anderen Kollegen austauschen<br />

Im Internet findet man eine Vielzahl nützlicher M-Dateien, die von Benutzern geschrieben wurden.<br />

<strong>Eine</strong> M-Datei ist eine Textdatei mit der Dateiendung .m, die <strong>MATLAB</strong> Befehle enthält. Es gibt zwei<br />

Arten:<br />

• Skriptdateien (oder Kommandodateien) haben keine Ein- oder Ausgabeargumente und operieren<br />

auf Variablen im Workspace.<br />

• Funktionsdateien enthalten eine function Definitionszeile und akzeptieren Eingabeargumente<br />

und geben Ausgabeargumente zurück, und ihre internen Variable sind lokal auf die Funktion beschränkt<br />

(sofern sie nicht als global deklariert wurden).<br />

4.1 Skriptdateien<br />

Ein Skript erlaubt es, eine Folge von Befehlen die wiederholt verwendet werden sollen oder in Zukunft<br />

noch gebraucht werden. Ein Beispiel für ein Skript ist folgender „Sinus random plotter“:<br />

%randSin<br />

%Plottet die Sinusfunktion nur ausgewertet an n+2 zufälligen Stellen<br />

n=10;<br />

x=sort([0,rand(1,n)*2*pi,2*pi]);<br />

y=sin(x);<br />

plot(x,y);<br />

Die ersten beiden Zeilen des Skripts beginnen mit dem % Symbol und sind daher Kommentare.<br />

Sobald <strong>MATLAB</strong> auf ein % trifft ignoriert es den Rest der Zeile. Dies erlaubt das Einfügen von Text,<br />

der das Skript für Menschen leichter verständlich macht. Angenommen dieses Skript wurde unter dem<br />

Namen randSin.m gespeichert, dann ist die Eingabe von randSin an der Kommandozeile gleichwertig<br />

zur Eingabe der einzelnen Zeilen des Skripts.<br />

30


4.2 Funktionsdateien<br />

Selbst geschriebene Funktionsdateien erweitern den Umfang von <strong>MATLAB</strong>. Sie werden auf die gleiche<br />

Weise verwendet wie die bereits existierenden <strong>MATLAB</strong> Funktionen wie sin, eye, size usw.<br />

Hier ist ein Beispiel für eine Funktionsdatei:<br />

function y = maxentry(A)<br />

%MAXENTRY Largest absolute value of matrix entries.<br />

% MAXENTRY(A) is the maximum of the absolute values<br />

% of the entries of A.<br />

y = max(abs(A(:)));<br />

Dieses Beispiel präsentiert mehrere Features. Die erste Zeile fängt mit dem Schlüsselwort function an,<br />

gefolgt vom Ausgabeargument y, und dem Gleichheitszeichen. Rechts von = kommt der Funktionsname<br />

maxentry, gefolgt vom Eingabeargument A in Klammern. (Im Allgemeinen kann es beliebig viele Einund<br />

Ausgabeargumente geben.) Der Funktionsname muss der gleiche sein wie der Name der M-Datei, die<br />

die Funktion enthält - in diesem Fall muss die Datei maxentry heißen.<br />

Die zweite Zeile der Funktionsdatei heißt H1-Zeile (help 1). Sie sollte eine Kommentarzeile sein: <strong>Eine</strong><br />

Zeile die mit einem %-Zeichen beginnt und danach ohne Leerzeichen dem Funktionsname in Großbuchstaben<br />

– gefolgt von einem oder mehr Leerzeichen und dann einer kurzen Beschreibung. Die Beschreibung<br />

sollte mit einem Großbuchstaben anfangen und mit einem Punkt enden und dabei auf die Worte „der“,<br />

„die“, „das“ und „ein“, „eine“ verzichten. Alle Kommandozeilen – beginnend mit der ersten bis zur ersten<br />

Nichtkommentarzeile (in der Regel eine Leerzeile, um die Lesbarkeit des Codes zu erhöhen) – werden<br />

beim Aufruf von help function_name angezeigt. Darum sollten diese Zeilen die Funktion und ihre Argumente<br />

beschreiben. Funktionenname und -argumente groß zu schreiben ist eine allgemein akzeptierte<br />

Konvention. Im Falle von maxentry sieht die Ausgabe folgendermaßen aus<br />

>> help maxentry<br />

MAXENTRY Largest absolute value of matrix entries.<br />

MAXENTRY(A) is the maximum of the absolute values<br />

of the entries of A.<br />

An dieser Stelle sei noch einmal mit Nachdruck darauf hingewiesen, dass es sich lohnt, alle Funktionsdateien<br />

auf diese Art und Weise zu dokumentieren. Oft ist es nützlich, in Kommentaren anzugeben,<br />

wann die Funktion zuerst geschrieben wurde, und ob Veränderungen hinzugefügt wurden.<br />

Der Befehl help funktioniert auf ähnliche Art und Weise mit Skriptdateien, er zeigt die Anfangsfolge<br />

an Kommentaren an.<br />

Die Funktion maxentry wird wie jede andere <strong>MATLAB</strong> Funktion aufgerufen:<br />

>> maxentry(1:10)<br />

ans =<br />

10<br />

>> maxentry(magic(4))<br />

ans =<br />

16<br />

4.3 M-Dateien bearbeiten<br />

Es gibt zwei Möglichkeiten, M-Dateien zu bearbeiten. Jeder beliebige ASCII-Editor kann verwendet<br />

werden (benutzt man ein Textverarbeitungsprogramm, so ist sicherzustellen, dass das Programm die<br />

Datei auch wieder im ASCII-Format speichert). Oder man benutzt den internen Editor/Debugger von<br />

<strong>MATLAB</strong>. Dieser Editor verfügt über Funktionen, die das Bearbeiten von M-Dateien unterstützen. Zum<br />

Beispiel werden Schleifen und if-Abfragen automatisch eingerückt, es gibt mehrfarbiges Syntax Highlighting,<br />

und einen automatischen Vergleich von Klammern und Doppelpunkten. Diese und andere Features<br />

können im Menü Tools-Optionen deaktiviert oder modifiziert werden.<br />

31


4.4 Mit M-Dateien und der Pfadvariable von <strong>MATLAB</strong> arbeiten<br />

Viele <strong>MATLAB</strong>-Funktionen sind M-Dateien die auf der Festplatte gespeichert werden, während andere in<br />

den <strong>MATLAB</strong>-Interpreter integriert sind. Der <strong>MATLAB</strong> Suchpfad ist eine Liste von Ordnern, die angibt,<br />

wo <strong>MATLAB</strong> nach M-Dateien sucht. <strong>Eine</strong> M-Datei ist nur dann verfügbar, wenn sie sich im Suchpfad<br />

befindet. Geben Sie path ein, um den aktuellen Suchpfad angezeigt zu bekommen. Die Pfadvariable kann<br />

über path gesetzt werden, und über addpath können Befehle hinzugefügt werden. <strong>Eine</strong> weitere Möglichkeit<br />

zur Bearbeitung des Suchpfads ist der Pfad-Browser, der über Datei-Pfad Einstellen oder die Eingabe<br />

von pathtool aufgerufen wird.<br />

Der Suchpfad kann mit mehreren Befehlen durchsucht werden. Der Befehl what listet alle <strong>MATLAB</strong><br />

Dateien im aktuellen Verzeichnis auf;<br />

what verzeichnisname listet alle <strong>MATLAB</strong>-Dateien im Ordner<br />

verzeichnisname im Pfad. Der Befehl lookfor keyword durchsucht den Pfad nach M-Dateien, die<br />

keyword in ihrer H1 Zeile enthalten (die erste Zeile des Hilfetextes). Um alle Kommentarzeilen, die bei<br />

Eingabe von help angezeigt werden, zu durchsuchen, kann man lookfor mit dem Parameter -all aufrufen:<br />

lookfor keyword -all<br />

Manche <strong>MATLAB</strong>-Funktionen benutzen Kommentarzeilen nach dem ersten Block von Kommentaren,<br />

um weitere Informationen zu liefern, wie etwa bibliographische Angaben (zum Beispiel fminsearch).<br />

Auf diese Information kann über type zugegriffen werden. Sie wird beim Aufruf von help nicht angezeigt.<br />

Die Eingabe von which foo zeigt den Pfad der Funktion foo an, oder gibt an, dass die Funktion builtin<br />

ist, oder nicht vorhanden. Diese Funktion ist nützlich falls man wissen möchte, in welchem Ordner<br />

sich eine bestimmte Funktion befindet. Falls mehr als eine Funktion mit dem Namen foo im Suchpfad<br />

existiert, zeigt which foo -all alle Funktionen an.<br />

Ein Skript, welches sich nicht auf dem Suchpfad befindet kann über den Befehl run gefolgt vom<br />

vollständigen Pfad des Skriptes aufgerufen werden. <strong>Eine</strong> M-Datei foo.m kann über type foo oder type<br />

foo.m am Bildschirm ausgegeben werden. (Falls es eine ASCII-Datei mit dem Namen foo gibt, so würde<br />

der erste Befehl foo ausgeben anstatt foo.m) Folgt type auf den Befehl more on, so wird die Datei<br />

seitenweise angezeigt (more off schaltet die seitenweise Darstellung wieder aus).<br />

Erstellt man eine neue M-Datei, sollte man vermeiden, einen Namen zu wählen, der im Suchpfad<br />

bereits vorhanden ist. Dies kann man mit Hilfe der Befehle which, type, help oder exist überprüfen.<br />

Der Befehl exist(’name’) überprüft, ob name eine Variable im Workspace, eine Datei (mit mehreren<br />

möglichen Endungen, unter Anderem .m) im Suchpfad, oder ein Ordner ist. Das Ergebnis 0 bedeutet,<br />

dass keine Übereinstimmungen gefunden wurden, währen die Zahlen 1-7 bedeuten, dass es welche gibt.<br />

Für die Bedeutung der Zahlen siehe help exist.<br />

Wird eine Funktion, die sich im Suchpfad befindet, zum ersten Mal aufgerufen, wird sie in den Speicher<br />

geladen. <strong>MATLAB</strong> kann im Allgemeinen feststellen, ob eine Funktionsdatei sich geändert hat, und<br />

kompiliert sie automatisch erneut, wenn sie aufgerufen wird. Um die Funktion fun aus dem Speicher zu<br />

löschen, benutzt man den Befehl clear fun. clear functions löscht alle Funktionen.<br />

4.5 Dualität von Befehl und Funktion<br />

Normalerweise werden vom Benutzer geschriebene Funktionen so aufgerufen: der Funktionenname gefolgt<br />

von einer Liste von Argumenten in Klammern. Doch manche <strong>MATLAB</strong>-internen Funktionen, wie zum<br />

Beispiel type und what, die im vorhergehenden Abschnitt behandelt wurden, werden normalerweise so<br />

aufgerufen, dass die Argumente vom Funktionennamen durch ein Leerzeichen getrennt werden. Diese ist<br />

keine Inkonsistenz von <strong>MATLAB</strong> sondern ein Beispiel für die Gleichheit von Befehl und Funktion.<br />

function comfun(x,y,z)<br />

%COMFUN Illustrative function with three string arguments.<br />

disp(x), disp(y), disp(z)<br />

32


Die Funktion comfun kann mit den Stringargumenten in Klammern (funktionale Form) oder mit den<br />

Stringargumenten getrennt durch Leerzeichen aufgerufen werden (Befehlsform):<br />

>> comfun(’ab’,’cd’,’ef’)<br />

ab<br />

cd<br />

ef<br />

>> comfun ab cd ef<br />

ab<br />

cd<br />

ef<br />

Die beiden Funktionsaufrufe sind gleichwertig. Andere Beispiele für die Dualität von Befehl und<br />

Funktion sind<br />

format long, format(’long’)<br />

disp(’Hello’), disp Hello<br />

diary mydiary, diary(’mydiary’)<br />

warning off, warning(’off’)<br />

Beachte, dass die Befehlsform nur dann verwendet werden sollte, wenn die Eingabeparameter der<br />

Funktion Strings sind.<br />

33


Kapitel 5<br />

Lineare Algebra mit <strong>MATLAB</strong><br />

5.1 Norm und Kondition<br />

Die Norm eines Vektors oder einer Matrix kann mit dem Befehl norm berechnet werden.<br />

Befehl:<br />

norm(A,p)<br />

wobei A eine m x n Matrix und p=1,2,inf oder fro ist.<br />

p Bedeutung<br />

1 1-Norm, d.h. max. Spaltensumme<br />

2 Spektralnorm, max. Singulärwert, (default)<br />

inf Maximumsnorm, d.h. max. Zeilensumme<br />

fro Frobeniusnorm, definiert als m<br />

i=1<br />

m<br />

i=1 ai,j<br />

Für höherdimensionale Matrizen sind Normberechnung für p = 2 relativ aufwendig und kostenintensiv<br />

– daher werden oft Abschätzungen verwendet.<br />

normest(A,tol)<br />

Mit Hilfe von normest wird die 2-Norm von A bis auf die durch tol gegebene Genauigkeit berechnet.<br />

Defaultwert für tol=1e-16.<br />

Oft werden lineare Gleichungssystem auf das Verhalten von Störungen untersucht (so genannten<br />

Stabilitätsanalyse). Ein Indikator hierfür ist die Kondition einer Matrix A, definiert als<br />

κp(A) = Ap · A −1 p<br />

Je nachdem ob κ groß bzw. klein ist, ist das System schlecht oder gut konditioniert.<br />

Befehl:<br />

cond(A,p)<br />

p ist wie für norm definiert.<br />

Anmerkung:<br />

Normalerweise wird die Kondition nur für quadratische, nicht singuläre Matrizen berechnet. Für p = 2<br />

kann auch die Kondition von rechteckigen Matrizen berechnet werden, wobei dann A ( − 1) durch die<br />

Pseudoinverse (genauer die Moore-Penrose-Inverse) ersetzt wird.<br />

Auch für die Kondition existieren Abschätzungsfunktionen, wie condest und rcond:<br />

[c,v]=condest(A)<br />

c Skalar<br />

v Vektor<br />

mit:<br />

und A · v1 = A1∗v1<br />

c<br />

Befehl:<br />

c ≤ κ1(A)<br />

34


cond(A)<br />

wobei für A singulär rcond(A)=0.<br />

5.2 Lineare Gleichungssysteme<br />

1<br />

(A) ≈ rcond(A)<br />

κ 1<br />

Ein lineares Gleichungssystem sieht grundsätzlich folgendermaßen aus:<br />

Ax = b<br />

mit einer Matrix A und einem Vektor b. Gesucht wird ein Vektor x der das System löst.<br />

5.2.1 A n × n Matrix<br />

Falls A eine quadratische, nicht singuläre Matrix ist, existiert eine eindeutige Lösung. In <strong>MATLAB</strong> wird<br />

diese wie folgt mit Hilfe des ’\’ berechnet.<br />

5.2.2 A m × n Matrix mit m > n<br />

x=A \ b<br />

Wenn A eine rechteckige Matrix ist, die mehr Zeilen als Spalten hat, spricht man von einem überbestimmten<br />

System, da mehr Bedingungen (Zeilen) als Unbekannte (Spalten) vorhanden sind. <strong>Eine</strong> eindeutige<br />

Lösung, so dass Ax = b, ist im Allgemeinen nicht möglich. Es kann allerdings eine Minimallösung angegeben<br />

werden, so dass A ∗ x − b2 = min! ist. (vgl. Numerik 1. „Lineare Ausgleichsrechnung“)<br />

In diesem Fall wird durch den ’\’ Operator das lineare Ausgleichsproblem gelöst, mit Hilfe der „least<br />

square solution“. Ist man nur an den nicht negativen Lösungen interessiert, ist der Befehl lsqnonneg zu<br />

empfehlen.<br />

x=lsqnonneg(A,b)<br />

wobei x nur Einträge größer, gleich Null enthält.<br />

5.2.3 A m × n Matrix mit m < n<br />

Falls A eine Matrix mit weniger Zeilen als Spalten ist, so ist das LGS unterbestimmt und es existieren<br />

entweder keine oder unendlich viele Lösungen. Falls das System unendlich viele Lösungen besitzt, gibt<br />

’A\b’ eine Lösung aus, die k nichtnull Elemente besitzt, wobei k der Rang der Matrix A ist. Sollte das<br />

System keine Lösungen haben gibt ’A\b’ eine Minimallösung aus, wie bei oben genannten überbestimmten<br />

Systemen.<br />

Falls man mehrere Gleichungssysteme, mit der selben Matrix A aber mit verschiedenen Seiten b (1) , . . . , b (n)<br />

auf einmal lösen möchte, geschieht das am einfachsten dadurch, dass man die b (i) s als Spalten einer Matrix<br />

B anordnet und den ’\’ Operator mit dieser Matrix aufruft. Das Ergebnis ist ein Matrix X mit<br />

x (1) , . . . x (n) als Spalten, die das jeweilige System zu gegebenem b (i) lösen.<br />

5.3 Inverse, Pseudoinverse und Determinante<br />

In manchen Fällen – nicht oft, aber hin und wieder, vor allem in Hausaufgaben – muss man die Inverse<br />

einer Matrix berechnen. In <strong>MATLAB</strong> geht das mit Hilfe des inv Befehls:<br />

X=inv(A)<br />

mit A ∗ X = X ∗ A = I, wobei A eine nicht singuläre, quadratische n × n Matrix sein muss.<br />

<strong>Eine</strong> Matrix A ist singulär, falls die Determinante von A = 0 ist. Befehl:<br />

det(A)<br />

35


mit A einer n × n Matrix. Für gewisse Zwecke, z.B. zur Lösung eines least squares Problem ist die<br />

so genannte Pseudoinverse einer Matrix A von Interesse. Die Pseudoinverse X von A erfüllt folgende<br />

Bedingungen:<br />

Befehl:<br />

pinv(A)<br />

XAX = X<br />

AXA = A<br />

(XA) T = XA<br />

(AX) T = AX<br />

wobei A hier nun auch eine rechteckige m × n Matrix sein kann.<br />

5.4 Zerlegungen<br />

Oben wurde bereits erwähnt, dass der ’\’ Operator lineare Gleichungssysteme löst, bzw. Näherungslösungen<br />

dazu angibt. <strong>MATLAB</strong> verwendet dazu geeignete Algorithmen, die sich je nach Matrix unterscheiden<br />

können.<br />

<strong>MATLAB</strong> unterstützt aber auch das Zerlegen von Matrizen mit speziellen Zerlegungen, z.B. die LRoder<br />

Cholesky-Zerlegung.<br />

5.4.1 LR-Zerlegung<br />

Befehl:<br />

[L,R]=lu(A) \\ [L,R,P]=lu(A)<br />

L untere Dreiecksmatrix mit 1 auf der Hauptdiagonale<br />

R obere Dreiecksmatrix<br />

wobei A eine quadratische n × n Matrix ist.<br />

Nicht jede Matrix A kann auf diese Weise zerlegt werden, es existieren Matrizen bei denen ’Pivoting’<br />

notwendig ist. Hierbei gibt der lu Befehl eine zusätzliche Permutationsmatrix P aus, sodass gilt: P ∗ A =<br />

L ∗ R. Wird P bei der Rückgabe von lu nicht aufgefangen so wird L = P T · L.<br />

Mit Hilfe der Zerlegung kann ein lineares Gleichungssystem dann wie folgt gelöst werden:<br />

[L,R]=lu(A);<br />

x=R\(L \ b);<br />

5.4.2 Cholesky-Zerlegung<br />

Falls A eine symmetrische, positiv definite (s.p.d.) Matrix ist, d.h. sie genügt:<br />

1. A T = A<br />

2. ∀x : x T Ax ≥ 0<br />

existiert, die Cholesky Zerlegung von A in eine obere Dreiecksmatrix R, so dass gilt:<br />

A = R T · R<br />

Anmerkung:<br />

In vielen Lehrbüchern wird die Cholesky-Zerlegung mit unteren Dreicksmatrizen L beschrieben. Beide<br />

Formulierungen sind äquivalent, da für L = R T gilt:<br />

Befehl:<br />

R=chol(A)<br />

[R,p]=chol(A)<br />

A = L · L T<br />

wobei A eine quadratische n × n Matrix ist. Falls A nicht positiv definit ist, ist p eine ganze Zahl größer<br />

0, andernfalls gleich 0.<br />

36


5.4.3 QR-Zerlegung<br />

Die oben genannten Zerlegungen sind jeweils nur für quadratische Matrizen geeignet. Die QR-Zerlegung<br />

jedoch arbeitet auch auf rechteckigen m x n Matrizen A , wobei A in eine orthogonale m x m Matrix Q<br />

und eine obere m x n Dreiecksmatrix R zerlegt wird.<br />

[Q,R]=qr(A) \\ [Q,R]=qr(A,0) \\ [Q,R,P]=qr(A)<br />

Falls m>n ist und die Variante qr(A,0) benutzt wird, ist Q eine spaltenorthogonale m × n und R<br />

eine n × n Matrix. Falls das Pivoting genutzt wird ([Q,R,P]=qr(A)) gilt: AP = QR wobei dann die<br />

Diagonalelemente von R dem Betrag nach, abfallend geordnet sind.<br />

Die QR-Zerlegung findet z.B. in der linearen Ausgleichsrechnung oder bei der Konstruktion von Orthonormalbasen<br />

Verwendung.<br />

5.4.4 Singulärwertzerlegung<br />

Ähnlich den Eigenwerten, charakterisieren die so genannten Singulärwerte unterschiedliche Eigenschaften<br />

einer Matrix. Jedoch sind für Eigenwerte quadratische Matrizen notwendig, die Singulärwertzerlegung<br />

hingegen arbeitet auch mit rechteckigen m × n Matrizen A. Es gilt:<br />

A = U · Σ · V<br />

mit U m × m und V n × n unitären Matrizen Σ m × n diagonal Matrix mit σi (Singulärwerte) auf der<br />

Hauptdiagonalen, wobei gilt:<br />

Befehl:<br />

[U,S,V]=svd(A)<br />

σ1 ≥ σ2 ≥ · · · ≥ σ min(m,n)<br />

Anmerkung:<br />

Mit Hilfe der Singulärwertzerlegung ist es möglich, verschiedene Dinge über die Matrix A auszusagen.<br />

So ist zum Beispiel die Anzahl der σi ungleich Null der Rang der Matrix A. Auch ist eine Orthonormalbasis<br />

des durch die Spalten von A aufgespannten Raumes in der Singulärwertzerlegung enthalten. Es sind die<br />

ersten k Spalten der Matrix U, wobei k der Rang von A ist.<br />

5.5 Eigenwertpropleme<br />

5.5.1 Eigenwerte<br />

Sei A eine quadratische n×n Matrix. Dann ist λ ∈ C ein Eigenwert von A, wenn es einen vom Nullvektor<br />

verschiedenen Vektor x gibt mit der Eigenschaft Ax = λx. Um diese Eigenwerte auszurechnen, berechnet<br />

man normalerweise das charakteristische Polynom p = det(Iλ − A). Somit gilt:<br />

p = pnλ n + · · · + p1λ + p0<br />

Die Koeffizienten pn, · · · , p0 des charakteristischen Polynoms erhält man mit dem Befehl poly(A).<br />

Die Eigenwerte bekommt man mittels e=eig(A). e ist ein Spaltenvektor der Länge n mit den Eigenwerten.<br />

Mehrfache Eigenwerte (algebraische Vielfachheit) werden stehen auch mehrfach in e. Mit [V,D]=eig(A)<br />

bekommt man eine n × n Diagonalmatrix D, die die Eigenwerte enthält, und eine n × n Matrix V, deren<br />

Spaltenvektoren, wenn möglich, eine Basis aus Eigenvektoren bilden, so dass V −1 AV = D.<br />

Falls man nicht n linear unabhängige Eigenvektoren erhält, ist die Matrix V nicht regulär. Dies verdeutlichen<br />

wir mit dem folgenden Beispiel:<br />

>> A=[2 -1;1 0]<br />

A =<br />

2 -1<br />

1 0<br />

>> [V,D]=eig(A)<br />

37


V =<br />

D =<br />

0.7071 0.7071<br />

0.7071 0.7071<br />

1 0<br />

0 1<br />

Wie man an diesem Beispiel auch sieht, normiert <strong>MATLAB</strong> die Eigenvektoren immer bzgl. der 2-Norm.<br />

Falls A eine hermitesche Matrix ist, d.h. A = A T , gibt es nur reelle Eigenwerte und eine Orthonormalbasis<br />

aus Eigenvektoren. So eine Basis ist in V gespeichert.<br />

>> [V,D]=eig([2 -1;-1 1])<br />

V =<br />

-0.5257 -0.8507<br />

-0.8507 0.5257<br />

D =<br />

0.3820 0<br />

0 2.6180<br />

Um die Kondition der Berechnung der einzelnen Eigenwerte zu berechnen, ist der Befehl [V,D,s]=condeig(A)<br />

implementiert. Die i-te Stelle im Vektor s entspricht der Kondition des i-ten Eigenwert.<br />

>> [V,D,s]=condeig([2 0.9;200 5]);<br />

>> [diag(D)’;s’]<br />

ans =<br />

-10.0000 17.0000<br />

7.4416 7.4416<br />

Wenn man eine sehr große quadratische Matrix A hat und sich nur für die 6 größten Eigenwerte<br />

interessiert, kann man sich durch eigs(A) eine Approximation an diese Eigenwerte anzeigen lassen. Für<br />

weitere Informationen help eigs.<br />

5.6 Matrixfunktionen<br />

Zum Lösen gewöhnlicher Differentialgleichungen wird oft die Exponentialfunktion mit einer Matrix als<br />

Argument benötigt. Diese ist auch wie folgt definiert:<br />

Von <strong>MATLAB</strong> wird dies direkt unterstützt:<br />

expm(A)<br />

exp(A) =<br />

wobei A eine quadratische n × n Matrix ist<br />

Anmerkung: Im Gegensatz zu der Funktion expm operiert exp nur auf den einzelnen Komponenten<br />

der Matrix A!<br />

Weiterhin sind in <strong>MATLAB</strong> folgenden Matrixfunktionen definiert:<br />

∞<br />

i=1<br />

• logm: Der Logarithmus einer Matrix als Umkehrfunktion der Exponentialfunktion, d.h. logm(expm(A))=A<br />

• sqrtm: Quadratwurzel aus A, d.h. B=sqtrm(A) mit B · B = A<br />

• funm: Mit Hilfe von funm können Funktionen als Argument Matrizen übergeben werden. Zum Beispiel<br />

funm(A,@sin) berechnet den Sinus der Matrix A.<br />

38<br />

A i<br />

i


Kapitel 6<br />

Eigene Funktionen<br />

<strong>Eine</strong> eigene Funktion steht sobald sie etwas komplexer wird in einer m-Datei. Der grundlegende Aufbau<br />

ist in Abschnitt 4.2 besprochen worden.<br />

Daneben ist es bei kurzen Funktionen oft praktisch, diese direkt zu definieren ohne eine neue Datei<br />

anlegen zu müssen. Dies funktioniert mit dem Befehl inline.<br />

>> f=inline(’exp(a+log(x))/42’,’x’,’a’)<br />

f =<br />

>> f(1,2)<br />

Inline function:<br />

f(x,a) = exp(a+log(x))/42<br />

ans =<br />

0.1759<br />

Erzeugt eine Funktion, die mit z.B.f(x, a) ausgewertet werden kann. Die Abfolge hinter der Funktionsvorschrift<br />

definiert die Reihenfolge der Argumente beim Funktionsaufruf.<br />

Meistens geht man bei der Entwicklung von Funktionen von einem einfachen, meistens eindimensionalen<br />

Beispiel aus und versucht an Hand von diesem zu einer vektorwertigen Funktion zu gelangen. Dies<br />

geschieht in Matlab mit Hilfe des vectorize Befehls.<br />

vectorize(FUNKTION)<br />

Der Befehl erzeugt aus einer gegebenen Funktion eine neue, die auf komponentenweise auf den Elementen<br />

von Vektoren bzw. Matrizen operiert.<br />

6.1 Referenzen<br />

Wie im vorhergehende Kapitel besprochen wurde, können mit Hilfe von funm Funktionen mit Matrizen<br />

als Argument ausgewertet werden. Hierzu wird eine so genannte Referenz auf eine Funktion übergeben.<br />

Diese Referenz ist nichts anderes als ein Verweis auf eine Funktion, die dann im Laufe des Aufrufs von<br />

funm mit feval ausgewertet wird.<br />

feval(@Funktionsname,x1,...,xn)<br />

@Funktionsname erzeugt den Verweis auf die Funktionen x1, . . . , xn sind die Argumente die an „Funktionsname“<br />

zur Auswertung übergeben werden sollen.<br />

In neueren Matlabversionen ist es möglich. <strong>Eine</strong>r Referenz direkt die Argument zu übergeben, dies<br />

sollte allerdings aus Gründen der Abwärtskompatibilität zu älteren Matlabversionen unterlassen werden.<br />

Beispiel:<br />

• neuere Matlabversion :<br />

func_handle=@test_function; func_handle(4)<br />

erzeugt eine Funktionsreferenz auf test_function und wertet dann die Referenz an der Stelle 4<br />

aus.<br />

39


• ältere Matlabversionen > diffd(@sin, 0.5)<br />

ans =<br />

0.8776<br />

>> cos(0.5)<br />

ans =<br />

0.8776<br />

6.2 Subfunktionen<br />

Zu einem ’sauberen’ Programmierstil gehört, dass man sich wiederholende Operationen ausgliedert in so<br />

genannte Subfunktionen. Da diese in der Regel nur im Kontext des entsprechenden M-Files Sinn machen,<br />

werden sie einfach an die Hauptfunktion angefügt. Sie werden wie jede andere Funktion definiert durch:<br />

function [RÜCKGABEWERTE]=FUNKTIONSNAME (EINGABEPARAMETER)<br />

Sie sind jedoch nur sichtbar für alle anderen Unterroutinen und die Hauptfunktion.<br />

function y=hauptfunktion(x)<br />

% Hier wird etwas gemacht, wozu man immer wieder die Wurzel<br />

% aus u+u^2 durch pi braucht. Der Aufruf erfolgt mit subfunktion(u).<br />

function t=subfunktion(u)<br />

t=sqrt(u+u^2)/pi;<br />

6.3 Globale Variablen und Rekursion<br />

Oft stellt sich das Problem, dass man Konstanten oder Verweise, in allen Funktionen zur Verfügung haben<br />

muss. Anstatt diese nun von Funktion zu Funktion immer und immer wieder zu übergeben werden sie<br />

als ’global’ deklariert.<br />

Falls man nun in all seinen Funktionen auf den Wert der Variable GLOB_VAR zugreifen will, deklariert<br />

man sie im Command Window mit ’global GLOB_VAR und verweist beim schreiben seiner Funktionen mit<br />

’global GLOB_VAR’ darauf dass die verwendete Variable schon vorhanden ist. Allerdings ist auch Vorsicht<br />

geboten beim Umgang mit globalen Variablen, da sie nicht schreibgeschützt sind, d.h. es ist möglich ihren<br />

Wert in Funktionen zu verändern.<br />

Rekursion bezeichnet einen Aufruf einer Funktion durch sich selbst. Am besten erklärt sich das an<br />

Hand eines Beispiels. Die Fakultät einer natürlichen Zahl n ist definert durch:<br />

n! = 1 · 2 · 3 · · · (n − 1) · n<br />

In Matlab mit Hilfe der Rekursion führt das zu folgendem:<br />

40


function ret_val=fak(n)<br />

if (n


Kapitel 7<br />

Ein- und Ausgabe<br />

Im letzten Kapitel haben wir gelernt wie man eigene Funktionen korrekt in <strong>MATLAB</strong> schreibt – aber<br />

diese konnten weder Daten einlesen noch Daten ausgeben. Dieses Manko wollen wir in diesem Kapitel<br />

beseitigen, da insbesondere viele Funktion direkte Eingaben vom Benutzer erwarten.<br />

7.1 Direkte Eingabe<br />

Direkte Eingabe heißt, dass der Nutzer des Programmes aufgefordert wird, Daten einzugeben.<br />

x=input(’Beschriftungstext’)<br />

x=input(’Beschriftungstext’,’s’)<br />

Wird die Funktion mit nur einem Parameter aufgerufen erwartet <strong>MATLAB</strong> die Eingabe im <strong>MATLAB</strong>-<br />

Syntax:<br />

>> x=input(’Bitte Zahl eingeben: ’);<br />

Bitte Zahl eingeben: sin(0.5)<br />

>> x<br />

x =<br />

0.4794<br />

Mittels eines zweiten Parameters ’s’ kann man <strong>MATLAB</strong> anweisen, die Eingabe immer als Text zu<br />

interpretieren.<br />

>> x=input(’Bitte Zahl eingeben: ’,’s’);<br />

Bitte Zahl eingeben: sin(0.5)<br />

>> x<br />

x =<br />

sin(0.5)<br />

Zur Abfrage von Koordinaten in einer graphischen Oberfläche wird die Funktion ginput verwendet.<br />

[x,y] = ginput(n)<br />

x x Koordinaten relativ zu dem geklickten Fenster<br />

y y Koordinaten relativ zu dem geklickten Fenster<br />

n Anzahl der Klicks die abgefangen werden sollen<br />

Im Vektor x werden folglich die x-Koordinaten der nächsten n Mausklicks gespeichert. Für den Vektor<br />

y gilt das Entsprechende. Diese Art der Eingabe ist besonders bei einem schon bestehenden Plot sinnvoll.<br />

Um zwischen zwei Befehlen n Sekunden zu warten, gibt es den <strong>MATLAB</strong>-Befehl pause(n). Dies wird<br />

üblicherweise bei Anzeigen von verschiedenen Plots angewandt.<br />

42


7.2 Bildschirmausgabe<br />

Einfache Ausgaben können über den Befehl disp erfolgen:<br />

disp(’Zeichenfolge’)<br />

disp(a)<br />

Bei Ausgabe einer Zeichenfolge muss disp verwendet werden, bei Aufruf von disp mit einer Variablen<br />

als Argument wird der Inhalt der Variablen formatiert ausgegeben (formatiert wie am interaktiven<br />

Prompt). Für komplexere und formatierte Ausgaben kann man den Befehl fprintf verwenden:<br />

fprintf(’FORMATSTRING’,Wert)<br />

FORMATSTRING Ein Formatierungsstring der Form %a.b(e/f)\n.<br />

a Anzahl der Stellen vor dem Komma<br />

b Anzahl der Stellen hinter dem Komma<br />

e/f Exponential oder Gleitkommadarstellung<br />

\n Nach Ausgabe eine neue Zeile beginnen.<br />

Wert Werte die ausgegeben werden sollen.<br />

Ein Minus hinter dem % Zeichen erzwingt eine linksbündige Ausgabe:<br />

fprintf(’%-3.5f\n%3.5f\n’, 9, 103)<br />

9.00000<br />

103.00000<br />

Für die Ausgabe von mehreren Werten müssen diese in dem Formatstring gekennzeichnet werden. Es<br />

können auch Beschriftungen eingefügt werden z.B.:<br />

fprintf(’Skalarprodukt von [1 1] und [1 2]: %3.5f\n’,[1,1]*[1;2])<br />

Skalarprodukt von [1 1] und [1 2]: 3.00000<br />

Des weiteren ist es möglich, auch komplette Matrizen zeilenweise ausgeben zu lassen:<br />

A=[1 2 3; 4 5 6; 7 8 9];<br />

fprintf(’a1=%g, a2=%g, a3=%g\n’, A);<br />

a1=1, a2=4, a3=7<br />

a1=2, a2=5, a3=8<br />

a1=3, a2=6, a3=9<br />

Um ’, % und \ in einem Formatstring auszugeben, müssen ’’, \% und \\ verwendet werden. Für die<br />

kombinierte Ausgabe von Zahlen und Zeichenketten ist es auch möglich, die beiden zu verbinden, indem<br />

man die Zahlen in Strings umwandelt mit Hilfe von num2str bzw. int2str:<br />

disp([’a’, num2str(4)])<br />

a4<br />

7.3 Speichern und Laden<br />

<strong>MATLAB</strong> unterstützt das einfache Speichern und Laden von Variablen. Mit dem Befehl save können<br />

Variablen in Dateien geschrieben werden.<br />

>> A=magic(10);<br />

>> B=magic(3);<br />

>> save ’magic’ A B<br />

Die von <strong>MATLAB</strong> geschriebenen Dateien enden auf ’.mat’ und sind in einem binären Format, welches<br />

-je nach <strong>MATLAB</strong> Version- auch komprimiert ist. Gibt man dem save Befehl nur einen Dateinamen als<br />

Argument, wird der komplette Workspace in der Datei gespeichert.<br />

Um gespeicherte Variablen zu laden gibt es den load Befehl. Er hat die gleiche Syntax wie das<br />

save Kommando. Um sich den Inhalt einer ’.mat’ Datei anzuzeigen kann man den Befehl whos -file<br />

verwenden.<br />

43


whos -file ’magic’<br />

Name Size Bytes Class Attributes<br />

A 10x10 800 double<br />

B 3x3 72 double<br />

>> clear A B<br />

>> B<br />

??? Undefined function or variable ’B’.<br />

>> load ’magic’ B<br />

>> B<br />

B =<br />

8 1 6<br />

3 5 7<br />

4 9 2<br />

Im obigen Beispiel haben wir mit dem clear Befehl die Variablen aus dem Workspace gelöscht.<br />

7.4 Indirekte Eingabe und Ausgabe<br />

Indirekte Eingabe und Ausgabe heißt, dass man aus einer *.txt-Datei Daten einliest bzw. in diese Datei<br />

Daten, die z.B. eine Funktion geliefert hat, reinschreibt.<br />

Zuerst muss man Matlab sagen, in welcher Datei es nach Daten suchen oder Daten schreiben soll.<br />

Dies wird durch den Befehl fid=fopen(’myoutput.txt’,’r/w’) erledigt, wobei r für das Einlesen steht<br />

bzw. w für das Eingeben von Daten. Mit fprintf kann man dann Daten in myoutput.txt schreiben.<br />

>> fid=fopen(’myoutput.txt’,’w’);<br />

>> a=[1 2 3 4];<br />

>> for i=1:4<br />

fprintf(fid,’Das %g. Element des Vektors a: %g\n’,i,a(i));<br />

end<br />

>> fclose(fid)<br />

Nun enthält myoutput.txt erwartungsgemäß folgendes:<br />

Das 1. Element des Vektors a: 1<br />

Das 2. Element des Vektors a: 2<br />

Das 3. Element des Vektors a: 3<br />

Das 4. Element des Vektors a: 4<br />

Diese Datei kann folgendermaßen eingelesen werden:<br />

>> fid=fopen(’myoutput.txt’,’r’);<br />

>> X=fscanf(fid,’Das %g Element des Vektors a: %g\n’)<br />

X =<br />

1<br />

1<br />

2<br />

2<br />

3<br />

3<br />

4<br />

4<br />

>> fclose(fid);<br />

44


scanf funktioniert also folgendermaßen: Überspringe ’Das ; lese irgendeine floating point Zahl (%g) ein,<br />

überspringe wieder Element des Vektors a: und lese die zweite floating point Zahl ein. Schreibe alle<br />

Zahlen der Reihe nach in den Vektor X.<br />

Mit reshape formt man X in eine Matrix um:<br />

>> X=reshape(X,2,4)<br />

X =<br />

1 2 3 4<br />

1 2 3 4<br />

Wenn man nur eine Matrix mit lauter reelen Zahlen einlesen will, macht man dies folgendermaßen.<br />

In Matrix.txt steht z.B.<br />

1 4 6 7<br />

7 9 10 11<br />

99 1 5 6<br />

1 103 4 89<br />

Nun muss man nur die Dimensionen der Matrix fscanf bekannt machen.<br />

>> fid=fopen(’Matrix.txt’,’r’);<br />

>> X=fscanf(fid,’%g’,[4,4]);<br />

>> X=X’<br />

X =<br />

1 4 6 7<br />

7 9 10 11<br />

99 1 5 6<br />

1 103 4 89<br />

>> fclose(fid)<br />

Außerdem können Dateien, die nur Zahlen erhalten, einfacher mit fread und fwrite bearbeitet werden.<br />

Informieren Sie sich dazu in der Hilfe.<br />

45


Kapitel 8<br />

Optimierung von M-Files<br />

Bei großen Problemen ist es sinnvoll und notwendig, Algorithmen effizient zu implementieren. Durch<br />

die Beachtung einiger Regeln kann man enorme Zeitgewinne erreichen (vor allem in älteren <strong>MATLAB</strong>-<br />

Versionen ohne JIT-Compiler).<br />

8.1 Vektorisierung<br />

In <strong>MATLAB</strong> sind Matrix- und Vektoroperationen annähernd optimal implementiert. Deshalb sollte man<br />

so oft wie möglich auf sie zurückgreifen, insbesondere for-Schleifen sollten möglichst ersetzt werden. Dazu<br />

ein Beispiel:<br />

>> n = 5e5; x = randn(n,1);<br />

>> tic, s = 0; for i=1:n, s = s+x(i)^2; end, toc<br />

elapsed time is 1.532000 seconds<br />

>> tic t=sum(x.^2); toc<br />

elapsed time is 0.046000 seconds<br />

>>s-t<br />

ans = 0<br />

>> 0.046/1.532<br />

ans = 0.0300<br />

Offensichtlich wird in beiden Fällen die Summe der Quadrate der Elemente von x berechnet, beide<br />

Male mit dem selben Ergebnis. Der Zeitgewinn ist allerdings phänomenal: Durch die vektorielle Implementierung<br />

benötigt man lediglich 3% der Zeit der intuitiven Version mittels einer for-Schleife. 1<br />

Weitere Beispiele:<br />

• Berechnung der Fakultät:<br />

>> n=1e7;<br />

>> p1=1; for i=1:n, p=p*i; end %9.625 sec<br />

>> p2=prod(1:n) %0.531 sec<br />

• Ersetzen zweier Zeilen einer Matrix durch Linearkombinationen:<br />

⎛<br />

⎜<br />

⎝<br />

←− A1 −→<br />

.<br />

←− Aj −→<br />

.<br />

.<br />

←− Ak −→<br />

.<br />

⎞ ⎛<br />

⎟ ⎜<br />

⎟ ⎜<br />

⎟ ⎜<br />

⎟ ⎜<br />

⎟ ⎜<br />

⎟ ⎜<br />

⎟ ↩→ ⎜<br />

⎟ ⎜<br />

⎟ ⎜<br />

⎟ ⎜<br />

⎟ ⎜<br />

⎠ ⎝<br />

←− A1 −→<br />

.<br />

←− c ∗ Aj − s ∗ Ak −→<br />

.<br />

.<br />

←− s ∗ Aj + c ∗ Ak −→<br />

.<br />

←− An −→<br />

←− An −→<br />

1 Dieses Missverhältnis ist in aktuelleren <strong>MATLAB</strong> Versionen nicht mehr so drastisch, trotzdem hat man häufig noch<br />

einen Unterschied vom Faktor 4.<br />

46<br />

⎞<br />

⎟<br />


temp = A(j,:);<br />

>> A(j,:) = c*A(j,:) - s*A(k,:);<br />

>> A(k,:) = s*temp + c*A(k,:);<br />

>> A([j k],:) = [c -s;s c]*A([j k],:);<br />

8.2 Preallokierung von Speicher<br />

<strong>Eine</strong> bequeme Eigenschaft von <strong>MATLAB</strong> besteht darin, dass Arrays (Vektoren) vor ihrer Benutzung<br />

nicht deklariert werden müssen, und man sich ins Besondere die Festlegung auf eine Größe (Höchstzahl<br />

der Elemente) spart. Werden an ein vorhandenes Array neue Elemente angehängt, wird die Dimension<br />

automatisch angepasst. Dafür muss immer neuer Speicher belegt werden – in Extremfällen kann dieses<br />

Vorgehen deshalb zu Ineffizienz führen:<br />

>> clear;<br />

>> n=1e4;<br />

>> tic, x(1:2) = 1; for i=3:n, x(i)=0.25*x(i-1)^2-x(i-2); end, toc<br />

elapsed time is 5.547000 sec<br />

>> clear<br />

>> n=1e4<br />

>> tic, x=ones(n,1); for i=3:n, x(i)=0.25*x(i-1)^2-x(i-2); end, toc<br />

elapsed time is 0.062000 sec<br />

Es ist zu erkennen, dass die arithmetischen Operationen im Vergleich zur Speicher-Allokierung einen<br />

verschwindend geringen Anteil an der Rechenzeit haben.<br />

47


Kapitel 9<br />

Tipps und Tricks<br />

9.1 Leere Arrays<br />

Wir haben die Möglichkeik Arrays der Dimensionen (4,0), (0,7) oder auch (0,0) zu erzeugen, im Folgenden<br />

„leere Arrays“ genannt. Die Regeln für Operationen mit leeren Arrays werden aus denen für „normale“<br />

Arrays hergeleitet. So zum Beispiel bei der Matrix-Multiplikation:<br />

>> k = 5; A = ones(2,k); B = ones(k,3); A*B<br />

ans=<br />

5 5 5<br />

5 5 5<br />

>> k = 0; A = ones(2,k); B = ones(k,3); A*B<br />

ans=<br />

0 0 0<br />

0 0 0<br />

Und wofür das Ganze? Es unterstützt uns bei unserem Vorhaben, for-Schleifen zu vermeiden – wie<br />

das folgende Beispiel zeigt:<br />

for i=j-1:-1:1<br />

s=0;<br />

for k=i+1:j-1<br />

s=s+R(i,k)*R(k,j);<br />

end<br />

end<br />

for i=j-1:-1:1<br />

s=R(i,i+1:j-1)*R(i+1:j-1,j);<br />

end<br />

Im Fall i=j-1 wird R(i,i+1:j-1) zu einer 1 × 0 - Matrix, R(i+1:j-1,j) zu einer 0 × 1 - Matrix und wir<br />

erhalten als Produkt das die 1 × 1-Matrix.<br />

9.2 ∞ und −∞<br />

Über den Nutzen von ∞ und −∞ im Zusammenhang mit der Achsenbeschriftung bei plots wird unten<br />

noch etwas gesagt. Ein weiteres Gebiet, an dem uns damit geholfen wird, sind die p-Normen. Möchte<br />

man nämlich die zu p gehörige q-Norm berechnen, so dass p −1 + q −1 = 1 gilt, muss man sich um die<br />

Spezialfälle p = 1 (⇒ q = ∞) bzw. p=∞ keine Gedanken machen, sondern kann ruhigen Gewissens<br />

q=1/(1-1/p) berechnen:<br />

>> x=1:10; p=1;<br />

>> norm(x,p)<br />

ans = 55<br />

48


norm(x,1/(1-1/p)<br />

ans = 10;<br />

49


Kapitel 10<br />

Grafiken mit <strong>MATLAB</strong> erstellen<br />

10.1 Grafiken<br />

In <strong>MATLAB</strong> ist es relativ leicht verschiedenste Arten von Grafiken zu erzeugen. Das Erscheinungsbild<br />

kann sehr individuell gestaltet werden. Beispielsweise kann man Farben, Achsenskalierungen und Beschriftungen<br />

den eigenen Vorstellungen anpassen. Grundsätzlich bestehen zur Modifikation von Grafiken<br />

zwei Möglichkeiten, einerseits direkt über die Kommandozeile oder alternativ interaktiv mit der Maus in<br />

der vorhandenen Grafik. Wir werden uns auf die erste Variante beschränken, aber es ist durchaus ratsam,<br />

auch mal mit den „fertigen“ Grafiken rumzuspielen.<br />

10.2 2-dimensionale Plots<br />

Die einfachste Variante zweidimensionale Plots zu erzeugen, besteht darin zwei Vektoren mit gleichen<br />

Dimensionen zu koppeln. Hat man zwei solcher Vektoren (x und y) gegeben, werden mit dem Befehl<br />

plot(x,y) die jeweiligen x(i) und y(i) als zusammengehörig erkannt und ein dementsprechender Plot<br />

erzeugt.<br />

Beispiel:<br />

>> x = [1.5 2.2 3.1 4.6 5.7 6.3 9.4];<br />

>> y = [2.3 3.9 4.3 7.2 4.5 3.8 1.1];<br />

>> plot(x,y)<br />

Mit zusätzlichen Angaben kann man das Aussehen modifizieren. Ein allgemeinerer Aufruf der Funktion<br />

plot hat die Form plot(x,y,String ), wobei sich der String aus bis zu drei Angaben (Farbe, Knoten,<br />

Linienart) zusammensetzt. Die möglichen Eingaben können Tabellen 10.1 entnommen werden:<br />

50


Farbe<br />

r Red<br />

g Green<br />

b Blue<br />

c Cyan<br />

m Magenta<br />

y Yellow<br />

k Black<br />

w White<br />

Marker<br />

◦ Kreis<br />

∗ Stern<br />

. Punkt<br />

+ Plus<br />

x Kreuz<br />

s Quadrat<br />

d Diamant<br />

^ Dreieck nach oben<br />

v Dreieck nach unten<br />

> Dreieck nach rechts<br />

< Dreieck nach links<br />

p Fünfpunktestern<br />

h Sechspunktestern<br />

Linienart<br />

- durchgezogene Linie<br />

– gestrichelte Linie<br />

: gepunktete Linie<br />

-. gepunktet und gestrichelte Linie<br />

Tabelle 10.1: Parameter für das Aussehen eines Plots<br />

Ein typischer Aufruf hätte die Form plot(x,y,’mx:’), das gleiche Resultat erhält man auch mit<br />

plot(x,y,’m:x’), woran man sieht, dass die Reihenfolge der Angabe irrelevant ist.<br />

Es ist auch möglich mehr als einen Graphen in das Koordinatensystem zu legen:<br />

>> x = [1.5 2.2 3.1 4.6 5.7 6.3 9.4];<br />

>> y = [2.3 3.9 4.3 7.2 4.5 3.8 1.1];<br />

>> a = 1:.1:10;<br />

>> b = 1./a;<br />

>> plot(x,y,’rp--’,a,b,’mx:)<br />

51


Es werden allerdings nicht nur Vektoren als „Datenquellen“ akzeptiert, sondern auch Matrizen.<br />

Wenn x ein m-dimensionaler Vektor und Y eine m x n Matrix ist, bewirkt plot(x,Y) das gleiche wie<br />

plot(x,Y(:1),x,Y(:2),...,x,Y(:,n)). Wenn zusätzlich X auch eine m x n Matrix ist, kann man mit<br />

plot(X,Y) die jeweils korrespondierenden Spalten der beiden Matrizen zu einem Graph verbinden, es<br />

handelt sich also um eine verkürzte Schreibweise von plot(X(:1),Y(:1),...,X(:,n),Y(:,n). Nun stellt<br />

sich die Frage, was passiert, wenn die Einträge in den beteiligten Vektoren und Matrizen nicht reellwertig<br />

sondern komplex sind. In diesem Fall wird der imaginäre Teil ignoriert. Allerdings gibt es eine Ausnahme<br />

- übergibt man plot als einziges Argument eine komplexe Matrix Z, erhält man das identische Resultat<br />

wie mit dem Kommando plot(real(Z),imag(Z)). plot können weitere Attribute übergeben werden,<br />

beispielsweise LineWidth:<br />

>> x = [1.5 2.2 3.1 4.6 5.7 6.3 9.4];<br />

>> y = [2.3 3.9 4.3 7.2 4.5 3.8 1.1];<br />

>> plot(x,y,’LineWidth’,2)<br />

Das Resultat sieht folgendermaßen aus:<br />

Für manche Anwendungen ist es sinnvoller, die Achsen logarithmisch zu skalieren. Dazu verwendet<br />

man statt plot eine der folgenden Anweisungen:<br />

• semilogx(x,y), die x-Achse wird logarithmisch skaliert<br />

• semilogy(x,y), die y-Achse wird logarithmisch skaliert<br />

52


• loglog(x,y), beide Achsen werden logarithmisch skaliert<br />

Beispiel:<br />

Wir wollen den Fehler bei der quadratischen Taylor-Approximation bei kleinen Zahlen visualisieren<br />

und zeigen, dass er sich proportional zu h3 verhält. Dazu betrachten wir |1 + h + h2 − exp(h)| und zum<br />

2<br />

Vergleich h3 jeweils ausgewertet für h = 10−4 , 10−3 , 10−2 , 10−1 , 1 und mit logarithmischer Skalierung:<br />

>> h = 10.^[0:-1:-4];<br />

>> taylor = abs((1+h+h.^2/2)-exp(h));<br />

>> loglog(h,taylor)<br />

>> hold on<br />

>> xlabel(’h’)<br />

>> ylabel(’absoluter Fehler’)<br />

>> title(’Fehler in quadratischer Taylor-Entwicklung’)<br />

>> plot(h,h.^3,’--’)<br />

Das Ergebnis bestätigt unsere Theorie:<br />

Neben loglog haben wir noch einige weitere neue Befehle benutzt, die allerdings mit Ausnahme von<br />

hold on selbsterklärend sein sollten. hold on sorgt dafür, dass beim Plotten von weiteren Funktionen<br />

die bisherigen erhalten bleiben und nicht - wie standardmaßig eingestellt bzw. bei hold off - zunächst<br />

das figure-Fenster „geleert“ und erst dann der neue Plot eingefügt wird. Das ist in unserem Beispiel<br />

durchaus sinnvoll, da wir so überprüfen können, ob die beiden Geraden tatsächlich annähernd parallel<br />

sind. Trotzdem ist es komisch, dass <strong>MATLAB</strong> grundsätzlich in das figure-Fenster mit der Nummer 1<br />

zeichnet. Das muss doch auch anders gehen?! Tut es auch! Mit dem Befehl figure wird ein neues figure-<br />

Fenster geöffnet, mit figure(n) kann man ein beliebiges figure-Fenster aktivieren, so dass sich alle<br />

folgenden (Grafik-) Befehle auf dieses beziehen.<br />

Viele Eigenschaften der Achsen können mit dem axis-Kommando beeinflusst werden. Mögliche Einstellungen<br />

sind:<br />

• axis [xmin xmax ymin ymax]<br />

• axis auto<br />

• axis equal<br />

• axis off<br />

• axis square<br />

• axis tight<br />

53


Für den Fall, dass man nur die Grenzen einer Achse festlegen möchte, stehen die Befehle xlim([xmin,xmax])<br />

und ylim([ymin,ymax]) zur Verfügung. Sollte man sich an einem Ende des Intervalls nicht festlegen wollen<br />

oder können, sorgt die Angabe von -inf bzw. inf dafür, dass sich <strong>MATLAB</strong> darum kümmert. Warum<br />

es an manchen Stellen sinnvoll ist, die Achseneinstellungen selbst vorzunehmen, zeigt folgendes Beispiel:<br />

Wir betrachten die Funktion<br />

Achsen, dann greifen wir manuell ein.<br />

>> x = linspace(0,3,500);<br />

>> plot(x,1./(x-1).^2+3./(x-2).^2)<br />

>> grid on<br />

>> ylim([0 50])<br />

1<br />

(x−1) 2 + 3<br />

(x−2) 2 , zunächst übernimmt <strong>MATLAB</strong> selbst die Begrenzung der<br />

Weiter oben haben wir ja schon gesehen, wie man seinem Plot einen Titel verpasst, doch man kann<br />

auch Text an einer beliebigen Stelle einfügen und sogar einer automatisch erstellten Legende kann<br />

man sich bedienen. Um Text einzufügen, reicht der Befehl text(x,y,’string), wobei (x, y) die Koordinate<br />

festlegt, an der der Text beginnen soll. Zum Einfügen der Legende lautet das Kommando<br />

legend(’string1’, ... ,’stringn’, Position), die Reihenfolge und die Anzahl der übergebenen<br />

Strings sollte mit der im plot- bzw loglog- Befehl übereinstimmen. Mögliche Werte für Position:<br />

• -1: rechts des Plots<br />

• 0: <strong>MATLAB</strong> entscheidet<br />

54


• 1: rechts oben<br />

• 2: links oben<br />

• 3: links unten<br />

• 4: rechts unten<br />

Es ist möglich (und teilweise auch notwendig) in Strings TEX-Code zu benutzen. Um zum Beispiel<br />

folgenden Text am Punkt (−0.6, 0.7) in einer Grafik einzufügen: (n + 1)Pn+1(x) = (2n + 1)xPn(x) −<br />

nPn−1(x) schreibt man idealerweise:<br />

>> text(-.6,.7,’(n+1)P_{n+1}(x)=(2n+1)xP_n(x)-nP_{n-1}(x)’)<br />

10.3 Mehrere Plots in einem Fenster<br />

Der Befehl subplot(m,n,p) teilt das figure-Fenster in m Zeilen und n Spalten auf. p ist ein Skalar und<br />

bezeichnet das aktive Feld.<br />

>> subplot(2,2,1), fplot(’exp(sqrt(x)*(sin(12*x))’,[0 2*pi])<br />

>> subplot(2,2,2), fplot(’sin(round(x))’,[0 10], ’--’)<br />

>> subplot(2,2,3), fplot(’cos(30*x)/x’,[0.01 1 -15 20], ’-.’)<br />

>> subplot(2,2,4), fplot(’[sin(x), cos(2*x),1/(1+x)’,[0 5*pi -1.5 1.5])<br />

Hier haben wir eine neue Funktion genutzt: fplot. <strong>MATLAB</strong> wertet dabei die Funktion an „genug“<br />

Stellen aus, um einen realitätsnahen Graph zu erhalten. Natürlich können auch fplot weitere Parameter<br />

übergeben werden. Mehr dazu findet man - wie zu jeder anderen Funktion auch - unter doc fplot. Auch<br />

eine unregelmäßige Aufteilung des figure-Feldes ist möglich:<br />

>> x = linspace(0,15,100);<br />

>> subplot(2,2,1), plot(x,sin(x))<br />

>> subplot(2,2,2), plot(x,round(x))<br />

>> subplot(2,2,3:4), plot(x, sin(round(x)))<br />

55


10.4 3-dimensionale Plots<br />

Analog zum Befehl plot im zweidimensionalen existiert auch der Befehl plot3 zum Plotten von Kurven<br />

in 3-D. Im Grunde funktioniert er genauso.<br />

>> t = -5:.005:5;<br />

>> x = (1+t.^2).*sin(20*t);<br />

>> y = (1+t.^2).*cos(20*t);<br />

>> z = t;<br />

>> plot3(x,y,z)<br />

>> grid on<br />

plot3 ist zwar ganz nett, kann aber nur zur Visualisierung von Kurven f : R → R 3 genutzt werden,<br />

nicht aber von Funktionen g : R 2 → R, anschaulich gesprochen werden ausschließlich Linien und nie<br />

Flächen dargestellt.<br />

<strong>Eine</strong>n ersten Ausweg aus diesem Dilemma bietet der Befehl ezcontour, der für eine Funktion f :<br />

[xmin, xmax] × [ymin, ymax] → R eine Höhenkarte erzeugt, indem man ezcontour(’f’,[xmin xmax<br />

ymin ymax]); ausführt.<br />

Ähnliches liefert auch die Funktion contour, ihr müssen allerdings zwei Vektoren x und y, sowie eine<br />

Matrix Z = (zi,j) mit zi,j = f(xi, yi) übergeben werden:<br />

56


subplot(211)<br />

>> ezcontour(’sin(3*y-x^2+1)+cos(2*y^2-2*x)’,[-2 2 -1 1]);<br />

>> x = -2:.01:2; y = -1:.01:1;<br />

>> [X,Y] = meshgrid(x,y);<br />

>> Z = sin(3*Y-X.^2+1)+cos(2*Y.^2-2*X);<br />

>> subplot(212)<br />

>> contour(x,y,Z,20)<br />

Um Z zu berechnen haben wir uns hier komponentenweisen Operationen auf Matrizen bedient. Es ist<br />

leicht einzusehen, dass x und y dazu in zwei Matrizen X und Y konvertiert werden müssen, deren Zeilen<br />

bzw. Spalten Kopien der Ursprungsvektoren sind. Genau das erreichen wir durch den Befehl meshgrid<br />

in der vierten Zeile. Beispielsweise liefert [X,Y]=meshgrid(1:4,5:7) die beiden Matrizen<br />

X =<br />

Y =<br />

1 2 3 4<br />

1 2 3 4<br />

1 2 3 4<br />

5 5 5 5<br />

6 6 6 6<br />

7 7 7 7<br />

Natürlich können contour auch mehr als drei Argumente übergeben werden, so dass zum Beispiel die<br />

Anzahl der unterschiedlichen Höhen beeinflusst werden kann. Für Einzelheiten in der Hilfe nachschauen,<br />

bei der Gelegenheit auch mal clabel nachschlagen.<br />

Die Befehle mesh und meshc erwarten als Eingabe die gleichen Datentypen wie contour, sie liefern<br />

uns endlich dreidimensionale Plots, wie wir sie uns vorstellen, meshc legt in die x-y-Ebene zusätzlich eine<br />

Höhenkarte.<br />

>> x = 0:.1:pi; y = 0:.1:pi;<br />

>> [X,Y] = meshgrid(x,y);<br />

>> Z = sin(Y.^2+X)-cos(Y-X.^2);<br />

>> subplot(221)<br />

>> mesh(Z)<br />

>> subplot(222)<br />

>> meshc(Z)<br />

>> subplot(223)<br />

>> mesh(x,y,Z)<br />

57


axis([0 pi 0 pi -5 5])<br />

>> subplot(224)<br />

>> mesh(Z)<br />

hidden off<br />

Es fällt auf, dass nur netzartige Strukturen entstanden sind. Ausgefüllt bekommt man die Graphen<br />

durch die Befehle surf bzw. surfc. Ein ähnliches Resultat liefert auch waterfall.<br />

>> Z = membrane; FS = ’FontSize’;<br />

>> subplot(221), surf(Z), title(’\bf{surf}’,FS,14)<br />

>> subplot(222), surfc(Z), title(’\bf{surfc}’,FS,14), colorbar<br />

>> subplot(223), surf(Z), shading flat<br />

>> title(’\bf{surf} shading flat’,FS,14)<br />

>> subplot(224), waterfall(Z), title(’\bf{waterfall}’,FS,14)<br />

10.4.1 Animationen<br />

Es gibt zwei Möglichkeiten, animierte Plots zu erzeugen.<br />

• Durch Erzeugen einer Sequenz von figures, die gespeichert und in Form eines Films abgespielt wird:<br />

58


Z = peaks; surf(Z)<br />

>> axis tight<br />

>> set(gca,’nextplot’,’replacechildren’)<br />

>> for j = 1:11<br />

>> surf(cos(2*pi*(j-1)/10).*Z,Z)<br />

>> F(j) = getframe;<br />

>> end<br />

>> movie(F)<br />

• Durch Manipulation der Objektattributte XData, YData und ZData, beispielsweise durch Aufruf<br />

der Funktion comet oder comet3:<br />

>> x = linspace(-2,2,500);<br />

>> y = exp(x).*sin(1./x);<br />

>> comet(x,y)<br />

>> t = -pi:pi/500:pi;<br />

>> comet3(sin(5*t),cos(3*t),t)<br />

10.5 Diagramme<br />

10.5.1 Balkendiagramme<br />

Zum Erzeugen von Balkendiagrammen stehen uns im zweidimensionalen die Funktionen bar und barh,<br />

im dreidimensionalen die Funktionen bar3 und barh3 zur Verfügung, das ’h’ steht dabei für horizontal,<br />

wir erhalten also waagerechte Balken. Balkendiagramme aggieren auf Matrizen. Deshalb erzeugen wir<br />

uns zunächst eine Beispiel-Matrix, die uns durch dieses Kapitel begleitet:<br />

>> Y = [7 6 5; 6 8 1; 4 5 9; 2 3 4; 9 7 2];<br />

<strong>MATLAB</strong> gruppiert jeweils die Elemente einer Zeile<br />

>> subplot(2,2,1), bar(Y)<br />

Durch zusätzliche Übergabe eines Vektors x kann man die Beschriftung der x-Achse ändern.<br />

>> x = 0:5:20;<br />

>> subplot(2,2,2), bar(x,Y)<br />

Bisher wurde das Attribut grouped verschwiegen, eigentlich müsste der Aufruf bar(x,Y,’grouped’)<br />

heißen, allerdings wird grouped als Standard angenommen. Die Alternative dazu lautet stacked.<br />

>> subplot(2,2,3), bar(Y,’stacked’)<br />

>> subplot(2,2,4), barh(Y)<br />

Im Dreidimensionalen funktionieren diese Befehle natürlich auch.<br />

59


10.5.2 Tortendiagramme<br />

Tortendiagramme werden mit pie bzw. pie3 erzeugt und erwarten als Parameter einen Vektor. Es besteht<br />

die Möglichkeit einige Tortenteile „herauszutrennen“ bzw. die Torte alternativ zu beschriften:<br />

>> x = [1.5 3.4 4.2];<br />

>> subplot(2,2,1), pie(x)<br />

>> subplot(2,2,2), pie(x,[0,0,1])<br />

>> subplot(2,2,3), pie(x,{’aaa’,’bbb’,’ccc’})<br />

>> subplot(2,2,1), pie3(x,[0,1,0])<br />

60


Kapitel 11<br />

Troubleshooting<br />

11.1 Errors und Warnings<br />

Es ist bestimmt schon jedem ein Tipp- oder Programmierfehler unterlaufen, der von <strong>MATLAB</strong> durch<br />

einen Error quittiert wird:<br />

>> mod(3,sqrt(-2))<br />

??? Error using ==> mod<br />

Arguments must be real.<br />

Zusätzlich zum Wort Error besteht die Fehlermeldung aus einem erläuternden Text - wie aussagekräftig<br />

auch immer der sein mag...<br />

Auf jeden Fall ist es auch möglich sich selbst solche Fehlermeldungen ausgeben zu lassen, das folgende<br />

Beispiel sollte selbserklärend sein:<br />

if ~isreal(arg2), error(’Arguments must be real.’), end<br />

Die Funktion warning zeigt, wie error, sein Argument an, stoppt die Ausführung des Programms aber<br />

nicht. Warum dann nicht einfach disp benutzen? Das hat vor allem zwei Gründe - zum einen kann man<br />

mit warning(’off’), die Warnmeldungen einfach unterdrücken, zum anderen ist es auch möglich alle<br />

aufgetretenen Fehler in einer Variable zu speichern: warns=warning.<br />

11.2 Debugging<br />

Die einfachste Möglichkeit, sich wichtige Zwischenergebnisse bei der Berechnung anzeigen zu lassen, besteht<br />

darin, die gewünschte Variable ohne Semikolon in den Code zu schreiben.<br />

Ein mächtiges Werkzeug von <strong>MATLAB</strong> ist aber auch der so genannte Keyboard-Modus. Er kann an<br />

einer bestimmten Stelle durch die Eingabe von keyboard oder alternativ mit zum Beispiel dbstop at<br />

5 in fak aufgerufen werden. Auf diese Art und Weise lässt sich auch die nützliche Version dbstop if<br />

error implementieren.<br />

Im Keyboard-Modus steht eine Kommandozeile zur Verfüegung, so dass man sowohl Werte von Variablen<br />

abfragen als auch verändern kann.<br />

61


Kapitel 12<br />

Weiterführende<br />

<strong>MATLAB</strong>-Funktionen<br />

Im abschließenden Kapitel sollen noch kurz einige, der vielen weiteren Möglichkeiten mit <strong>MATLAB</strong><br />

zu programmieren vorgestellt werden. Dies erfolgt beispielhaft an einigen interessanten Toolkits, der<br />

Möglichkeit GUIs zu erstellen und <strong>MATLAB</strong> mit anderen Programmiersprachen zu kombinieren.<br />

12.1 Toolkits<br />

Die Funktionalität von <strong>MATLAB</strong> wurde von einigen Toolboxen erweitert.Um herauszufinden, ob eine<br />

Toolbox bereits installiert ist, schaut man die Liste durch, die <strong>MATLAB</strong> nach dem Kommando ver<br />

ausgibt. Wenn der Name der gewünschten Toolbox enthalten ist, so ist diese auch vorhanden.<br />

Es gibt eine Vielzahl solcher Toolboxen z.B. zur Optimierung, für Neuronale Netzwerke, Splines,Partielle<br />

Differentialgleichungen oder für Wavelets. <strong>Eine</strong> aktuelle Liste solcher Toolboxen findet sich unter<br />

http://www.mathworks.com/products/product_listing/index.html<br />

wo es auch entsprechende Dokumentationen gibt. Außerdem gibt es noch eine Vielzahl von Toolboxen,<br />

die von Privatpersonen oder Organisationen zur Verfügung gestellt werden. Diese haben meist sehr<br />

spezielle Zielsetzungen (z.B. INTLAB, Hidden Markow Modell Toolbox, Bioelectromagnetism Toolbox).<br />

Wir werden uns nun mit einer kleinen Auswahl beschäftigen.<br />

12.1.1 Symbolic Math Toolbox<br />

Um auch symbolische Rechnungen (wie im Maple) in <strong>MATLAB</strong> zu machen, benötig man die Symbolic<br />

Math Toolbox. Diese basiert auf MAPLE und liefert einen Teil der dort vorhandenen Funktionen in<br />

<strong>MATLAB</strong>-Syntax mit. Um symbolische Variablen einzuführen, verwendet man den Befehl sym oder syms:<br />

>> b = sym(sqrt(2))<br />

>> syms x y n a<br />

>> f = sin(x*y)/(x*y)<br />

Um diese Variablen wieder in numerische umzuwandeln, verwendet man vpa und um die Genauigkeit<br />

festzulegen digits:<br />

>> digits(25)<br />

>> vpa(b)<br />

Außerdem kann man den symbolischen Variablen auch Werte zuweisen:<br />

>> solve(a*x^2+b*x+c)<br />

>> subs(y,{a,b,c},{1,-1,-1})<br />

Differential- und Integralrechnung<br />

Nachdem man eine Funktion f mit symbolischen Variablen erzeugt hat, kann man diese nun auch ableiten<br />

mit diffoder integrieren mit int:<br />

62


diff(f)<br />

>> int(f)<br />

Außerdem lassen sich auch Grenzwerte symbolisch berechnen mit limit:<br />

>> limit((1 + x/n)^n,n,inf)}<br />

Vereinfachung<br />

Um die Ausgabe leichter lesbar zu machen gibt es das pretty- Kommando:<br />

>> pretty(f)<br />

Um Ausdrücke zu vereinfachen, kann man entweder simplify oder simple verwenden, wobei simple<br />

den Ausdruck sucht, der am kürzesten ist:<br />

>> simplify((1/a^3+6/a^2+12/a+8)^(1/3))<br />

>> simple((1/a^3+6/a^2+12/a+8)^(1/3))<br />

Gleichungssysteme lösen<br />

Desweiteren kann man auch Gleichungen mit solve und Differentialgleichungen mit dsolve lösen:<br />

>> solve(’cos(n*x)+sin(x)=1’)<br />

>> dsolve(’Dy=1+y^2’)<br />

12.1.2 Image Processing Toolbox<br />

Die Image Processing Toolbox bietet die Möglichkeit auf Bilder zuzugreifen, sie zu verändern und zu<br />

speichern.<br />

Lesen und Schreiben von Bildern<br />

Dazu lädt man zuerst ein Bild mit dem Befehl imread. Dieser unterstützt unter anderm die Formate<br />

JPEG, TIFF, GIF, BMP oder PNG. Mit imwrite kann man Bilder speichern. Der Befehl imfinfo gibt<br />

Informationen:<br />

>> A = imread(’test.jpg’);<br />

>> imwrite(A,’test2.jpg’);<br />

>> imfinfo(’test.jpg’)<br />

Anzeigen und Bearbeiten von Bildern<br />

Das Bild kann man sich mit dem Befehl imshow anzeigen lassen:<br />

>> imshow(A)<br />

Den Kontrast eines Graustufenbildes kann man mit dem Befehl imadjust verbessern. Mit dem Befehl<br />

imfilter kann man beliebige Filter auf ein Bild anwenden. <strong>Eine</strong> Auswahl solcher Filter stellt fspecial<br />

zur Verfügung.<br />

>> imadjust(A)<br />

>> h=fspecial(’sobel’)<br />

>> imfilter(A,h)<br />

12.2 Der <strong>MATLAB</strong> C-Compiler<br />

Mit dem <strong>MATLAB</strong> Compiler kann man auch Standalone Anwendungen erstellen oder C-, C++ Shared<br />

Libraries. Dazu muss auf dem System erstmal die <strong>MATLAB</strong> Component Runtime installiert sein. (im<br />

63


<strong>MATLAB</strong>-Verzeichnis unter root\toolbox\compiler\deploy\win32). Anschließend muss man den Compiler<br />

konfigurieren. Dazu ruft man in <strong>MATLAB</strong> mbuild -setup auf und wählt dort das Verzeichnis, in<br />

dem der C-Compiler liegt. Danach kann man mit mcc die eigenen m-Dateien kompilieren. Wenn man eine<br />

Standalone Anwendung erstellen möchte verwendet man:<br />

>> mcc -m eigenefun.m<br />

Für ein C Shared Library:<br />

>> mcc -l eigenefun.m<br />

Für ein C++ Shared Library:<br />

>> mcc -l eigenefun.m -W cpplib -T link:lib<br />

Um die so erzeugte Anwendung oder Bibliothek weiterzugeben, muss man natürlich die compilierte<br />

Datei weitergeben, außerdem die eigenefun.ctf und das <strong>MATLAB</strong> Component Runtime (unter Windows<br />

MCRInstaller.exe, unter Linux MCRInstaller.zip). Nun kann man auf jedem System über die Kommandozeile<br />

das Programm starten, dabei werden die evtl. vorhandenen Parameter einfach nach einem<br />

Leerzeichen angehängt.<br />

12.3 Andere Programmiersprachen mit <strong>MATLAB</strong> verwenden<br />

<strong>MATLAB</strong> ist sehr nützlich für mathematische Programmierung, bietet aber auch die Möglichkeit andere<br />

Programmiersprachen zu nutzen. So kann man z.B. bereits bestehende Programme in C oder Fortran<br />

einbinden oder Java-Klassen nutzen.<br />

12.3.1 Fortran und C<br />

Viele mathematische Programme sind in FORTRAN oder C geschrieben sind und man kann sie auch in<br />

MATAB nutzen, indem man sie etwas ändert und compiliert. Daher testen wir zuerst, ob unser Systm<br />

dafür passend konfigueriert ist. Dazu kompieren wir yprime.c ins aus \extern\examples\mex Arbeitsverzeichnis.<br />

Nun rufen wir mex auf:<br />

>> mex yprime.c<br />

Kann man nun yprime wie eine normale M-Funktion verwenden, funktioniert alles. >> yprime(1,1:4)<br />

Ansonsten sollte man mit mex -setup sicherstellen, dass ein geeigneter Compiler ausgewählt ist.<br />

Ebenso verfährt man mit Fortran-Programmen. Beim Aufruf des Compilers mex kann man auch noch<br />

eine Optionsdatei<br />

(z.B. aus \bin\win32\mexopts) mitgeben:<br />

>> mex yprime.c -f lccopts.bat<br />

Solche Optionsdateien kann man auch selbst erstellen, wenn man zum Beispiel einen nicht supporteten<br />

Compiler verwenden will, oder mehr Einfluss auf den Compilationsprozess nehmen will.<br />

Um ein C bzw. Fortran-Programm <strong>MATLAB</strong> kompatibel anzupassen, benötigt man eine Gatewayroutine.<br />

Außerdem muss im C-Header auch # include „mex.h“ stehen. Die Gatewayroutine stellt die<br />

Schnittstelle zwischen <strong>MATLAB</strong> und C dar:<br />

void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const<br />

mxArray*prhs[] )}<br />

nlhs gibt die Anzahl der Ausgabeparameter,nrhs sie Anzahl der Eingabeparameter an. Die Parameter<br />

plhs und prhs enthalten die Pointer auf die entsprechenden Eingabe-/Ausgabevektoren. Danach<br />

kommt C Code, der die Eingaben prüft und die Datenstrukturen (natürlich <strong>MATLAB</strong> kompatibel, z.B.<br />

mxArray) für die Ausgabe anlegt. Die eigentliche C Routine ist meist eine eigene Funktion, die von hier<br />

aus aufgerufen wird und deren Ergebnis dann durch die Gatewayroutine an <strong>MATLAB</strong> zurückgegeben<br />

wird.<br />

Ruft man nun die Funktion in Matlab auf, findet <strong>MATLAB</strong> die MEX-Datei vor M-Dateien mit<br />

gleichem Namen. Dies kann man sich für die <strong>MATLAB</strong> Hilfe zunutze machen. Da die MEX-Datei keine<br />

für <strong>MATLAB</strong> lesbare Hilfe hat, sucht <strong>MATLAB</strong> weiter und gibt die Hilfe einer gleichnamigen M-Datei<br />

aus, falls vorhanden.<br />

Auch Fortran benötigt eine Gatewayroutine, die der in C sehr ähnlich sieht:<br />

subroutine mexFunction(nlhs, plhs, nrhs, prhs)<br />

64


integer plhs(*), prhs(*)<br />

integer nlhs, nrhs,<br />

die anschließend die Eingaben prüft, den Ausgabevektor initialisiert und die eigentliche Funktion aufruft.<br />

Außerdem kann man auch Matlab Routinen in C oder Fortran verwenden. Dazu läuft eine seperate<br />

<strong>MATLAB</strong> Engine, die das C bzw. Fortran Programm ansteuern kann. Dazu muss engine.h eingebunden<br />

sein. Mit engOpen(“\0“) startet man die <strong>MATLAB</strong>-Engine. Man erhält dabei einen Pointer auf die Engine.<br />

Nun kann man Matlab kompatible Variablen deklarieren und mit engPutVariable an Matlab geben.<br />

Die Auswertung eines Ausdrucks erfolt mit engEvalString. Wenn man alle Auswertungen ausgeführt<br />

hat, gibt man den Speicher wieder frei und schließt die <strong>MATLAB</strong> Engine mit engClose, z.B.:<br />

Engine *ep;<br />

ep = engOpen("’\0"’); T = mxCreateDoubleMatrix(1, 10, mxREAL);<br />

engPutVariable(ep, "’T"’, T);<br />

engEvalString(ep,"’D=.5.*(-9.8).*T.^2;"’);<br />

mxDestroyArray(result);<br />

engClose(ep);<br />

Matlab in Fortran einzubinden funktioniert analog.<br />

12.3.2 Java<br />

<strong>MATLAB</strong> liefert außerdem bei seiner Installation eine JVM (Java Virtual Machine) mit und bietet die<br />

Möglichkeit auf Java-Objekte zuzugreifen. Dabei kann man den Pfad entweder statisch in der classpath.txt<br />

(unter \toolbox\local) oder dynamisch mit javaaddpath C:\Java einbinden. Wenn man jar-Archives einbinden<br />

will, muss man ihren vollständigen Pfad inklusiv ihrem Namen angeben, bei normalen Javaklassen<br />

reicht der Pfad zu einem Elternverzeichnis um alle Klassen darin in <strong>MATLAB</strong> verfügbar zu machen. Nun<br />

kann man wie man es aus Java gewohnt ist, mit dem Konstruktor Instanzen einer Java-Klasse erzeugen<br />

und bearbeiten: >> frame = java.awt.Frame(’Frame A’);<br />

>> frame.setSize(100,60);<br />

>> frame.setVisible(true);<br />

Mittels Java-Klassen kann man zum Beispiel Daten aus dem Internet holen:<br />

>> url = java.net.URL(’http://www.fs.tum.de/FSMPI/Kurse/Matlab/test.html’)<br />

>> is = openStream(url);<br />

>> isr = java.io.InputStreamReader(is);<br />

>> br = java.io.BufferedReader(isr);<br />

>> for k = 1:85<br />

s = readLine(br);<br />

end<br />

>> s = readLine(br);<br />

>> disp(s)<br />

12.4 GUIs programmieren<br />

Mit dem <strong>MATLAB</strong> Compiler haben wir eine Möglichkeit kennengelernt, Standalone Anwendungen zu<br />

erstellen, allerdings ist die Parameter-Übergabe wenig intuitiv. Daher ist es sinnvoll für solche Anwendungen<br />

eine GUI zu erstellen. <strong>MATLAB</strong> bietet dazu direkt Funktionen an oder ein graphisches Tool, mit<br />

dem man die Steuerelemente anordnen kann.<br />

12.4.1 GUI Kommandos<br />

Um Steuerelemente direkt zu programmieren, kann man das Kommando uicontrol verwenden. Dem<br />

Kommando werden verschiedene Werte mitgegeben, z.B. gibt ’Style’ an, was für ein Element man möchte<br />

(z.B. checkbox, edit, listbox, popupmenu pushbutton, radiobutton, slider, text). Man kann zum Beipiel<br />

65


einer figure einen Button zum Schließen des Fensters mitgeben:<br />

>> fh = figure(’NumberTitle’,’off’,’Name’,’GUI’);<br />

>> ah = axes(’Position’,[0.1 0.1 0.65 0.85]);<br />

>> membrane;<br />

>> ph = uicontrol(fh, ’Style’, ’pushbutton’, ’String’, ’Ende’, ’Units’, ’normalized’,<br />

’Position’, [0.8 0.08 0.18 0.12], ’ToolTipString’,’Schließt das Fenster’,’Callback’,<br />

’close(gcbf)’);<br />

12.4.2 GUIDE<br />

Guide ist ein graphisches Interface um GUIs zu erzeugen. Um es zu starten tippt man den Befehl guide.<br />

Nun kann man auf einem leeren GUI die Komponenten per Drag’n’Drop anordnen. Und mit dem Property<br />

Manager Eigenschaften zuordnen (z.B. Farbe, Text, Closefunction). Wenn man die fertige GUI<br />

gespeichert hat, findet man eine .fig und .m Datei desselben Namens. Bis jetzt haben wir nur eine Gui,<br />

die aber noch keine Funktionalität besitzt, wenn wir sie starten. Wenn wir die .m-Datei editieren, weisen<br />

wir nun die entsprechenden Funktionen zu. In der generierten M-Datei findet sich am Anfang eine Initialisierung,<br />

die man nicht änern sollte. Anschließend kommt die eigene Opening Function. Hier schreiben<br />

wir alle Funktionen hinein, die nur einmal und zwar beim Öffnen der Gui erledigt werden sollen (z.B.<br />

Beispielplot). Mit setappdata stellen wir dann die gebrechneten Daten der GUI zur Verfügung. Die Output<br />

Funktion verwenden wir, wenn wir Werte z.B. an eine weitere GUI weitergeben möchten (so muss<br />

man sie nicht öffentlich deklarieren). In der Callback Funktion implementieren wir die Funktionalität der<br />

einzelnen Elemente, z.B. Auslesen eines Wertes von einem Slider (hObject ist das Handle des Sliders):<br />

>> f = get(hObject,’Value’);<br />

66


Literaturverzeichnis<br />

[1] Stoer: Numerische Mathematik 1. Springer-Verlag, Berlin Heidelberg, New-York<br />

67


Index<br />

[], 21<br />

function, 31<br />

charakteristisches Polynom, 37<br />

Cholesky-Zerlegung, 36<br />

Debugging, 61<br />

Determinante, 35<br />

Eingabe, 42<br />

Funktionen<br />

addpath, 32<br />

all, 24<br />

and, 24<br />

any, 24<br />

axis, 53<br />

bar3, 59<br />

barh3, 59<br />

barh, 59<br />

bar, 59<br />

blkdiag, 13<br />

break, 28<br />

case, 29<br />

chol, 20<br />

clabel, 57<br />

clear, 32, 44<br />

comet3, 59<br />

comet, 59<br />

condest, 34<br />

continue, 28, 29<br />

contour, 56, 57<br />

cos, 19<br />

cumsum, 20<br />

dbstop, 61<br />

diag, 12<br />

diff, 20, 62<br />

digits, 62<br />

disp, 43, 61<br />

doc, 55<br />

dsolve, 63<br />

eigs, 38<br />

elseif, 27<br />

else, 27<br />

error, 61<br />

exist, 32<br />

expm, 38<br />

exp, 19, 38<br />

eye, 11<br />

ezcontour, 56<br />

68<br />

factorial, 19<br />

feval, 39<br />

figure, 53, 66<br />

find, 26<br />

fminsearch, 32<br />

for, 9, 14, 26–28, 46, 48<br />

fplot, 55<br />

fprintf, 43, 44<br />

fread, 45<br />

fscanf, 45<br />

fspecial, 63<br />

funm, 38, 39<br />

fwrite, 45<br />

gallery, 14<br />

ginput, 42<br />

global, 40<br />

guide, 66<br />

help, 31, 32<br />

hilb, 13<br />

hold, 53<br />

if, 26, 27, 29<br />

imadjust, 63<br />

imfilter, 63<br />

imfinfo, 63<br />

imread, 63<br />

imshow, 63<br />

imwrite, 63<br />

inline, 39<br />

int2str, 43<br />

int, 62<br />

invhilb, 13<br />

inv, 35<br />

isequal, 23<br />

isnan, 23<br />

keyboard, 61<br />

legend, 54<br />

length, 19<br />

limit, 63<br />

linspace, 14<br />

load, 43<br />

logical, 24<br />

loglog, 53<br />

logm, 38<br />

lookfor, 32<br />

lsqnonneg, 35<br />

lu, 36<br />

magic, 13<br />

max, 20<br />

meshc, 57


meshgrid, 57<br />

mesh, 57<br />

more, 32<br />

normest, 34<br />

norm, 20, 34<br />

not, 24<br />

num2str, 43<br />

numel, 19<br />

ones, 11<br />

or, 24<br />

pathtool, 32<br />

path, 32<br />

pause, 42<br />

pie3, 60<br />

pie, 60<br />

plot3, 56<br />

plot, 9, 50–52, 56<br />

poly, 37<br />

pretty, 63<br />

primes, 16<br />

prod, 20<br />

qr, 37<br />

randn, 11, 12<br />

rand, 11, 12<br />

rcond, 34<br />

repmat, 13<br />

reshape, 21, 45<br />

run, 32<br />

save, 43<br />

scanf, 45<br />

semilogx, 52<br />

semilogy, 52<br />

simple, 63<br />

simplify, 63<br />

sin, 19<br />

size, 19<br />

solve, 63<br />

sort, 20<br />

sqrtm, 38<br />

sub2ind, 16<br />

subplot, 55<br />

sum, 20<br />

surfc, 58<br />

surf, 58<br />

switch, 26, 29<br />

syms, 62<br />

sym, 62<br />

text, 54<br />

tril, 20<br />

triu, 20<br />

type, 32<br />

uicontrol, 65<br />

vectorize, 39<br />

ver, 62<br />

vpa, 62<br />

warning, 61<br />

waterfall, 58<br />

what, 32<br />

69<br />

which, 32<br />

while, 26, 28<br />

whos , 43<br />

xlim, 54<br />

xor, 24<br />

ylim, 54<br />

zeros, 11<br />

eig, 37<br />

hilb, 18<br />

hold, 9<br />

input, 42<br />

invhilb, 18<br />

spdiags, 10<br />

speye, 10<br />

subplot, 59, 60<br />

condeig, 38<br />

fopen, 44<br />

lu, 36<br />

norm, 34<br />

pinv, 36<br />

globale Variablen, 40<br />

GUI, 65<br />

GUIDE, 66<br />

Hilbertmatrix, 13<br />

Inverse, 35<br />

Keyboard-Modus, 61<br />

Komplexe Zahlen, 5<br />

Kondition, 34<br />

kubische Splines, 7<br />

leere Felder, 48<br />

lineare Gleichungssysteme, 35<br />

logical, 23<br />

logische Felder, 24<br />

LR-Zerlegung, 36<br />

magische Quadrate, 13<br />

Matrix, 11<br />

Moore-Penrose-Inverse, 34<br />

natürlicher Spline, 7<br />

Norm, 34<br />

NumPy, 5<br />

Octave, 5<br />

Operatoren, 23<br />

\, 35<br />

=, 23<br />

:, 14<br />

’, 16<br />

*, 17<br />

+, 17


-, 17<br />

.’, 16<br />

.*, 17<br />

:, 15<br />

=, 23<br />

Pseudoinverse, 36<br />

Python, 5<br />

QR-Zerlegung, 37<br />

Rekursion, 40<br />

SciLab, 5<br />

SciPy, 5<br />

symbolisches rechnen, 62<br />

Tortendiagramme, 60<br />

transponieren, 16<br />

Variablen<br />

ans, 5<br />

Vektor, 11<br />

Workspace, 43<br />

70

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!