Kurzes Tutorial: Octave/MATLABvon Christian HertaWas ist Matlab/OctaveMATLAB bzw. Octave sind numerische Berechnungs- und Simulationswerkzeuge. Sie besitzen hierfür eine eigene Syntax / Programmiersprache, die interpretiert wird. MATLAB und Octave sind größtenteils kompatibel, wobei MATLAB aber einen größeren Funktionsumfang besitzt. GNU Octave ist für viele Computersysteme kostenlos erhältlich. Eine Knoppix-Version (bootbares CD-Linux) mit Octave-Inhalt gibt es ebenfalls: http://pareto.uab.es/mcreel/Econometrics/Sowohl für Octave als auch für MATLAB gibt es etliche Toolboxen, die Funktionen für spezielle Probleme bereitstellen ( z.B. Statistik ). Für octave gibt es diese auf Octave-Forge und mit Octaviz ist eine Erweiterung zur Visualisierung verfügbar. Octave und MATLAB sind keine Computer-Algebra Systeme, d.h. sie können nicht symbolisch rechnen, wie z.B. MAPLE oder Mathematica. MATLAB besitzt hierfür jedoch eine auf MAPLE basierende Toolbox: Symbolics (im Rahmen dieses Tutorials wird jedoch hierauf nicht eingegangen). Dieses Tutorial sollte interaktiv mit einer Matlab/Octave Umgebung durchgearbeitet werden. Die Eingabe in der Matlab/Octave-Umgebung wird dabei mit >>gekennzeichnet. Inhalt
DatenstrukturenSkalare, Vektoren und MatrizenDie wichtigste Datenstruktur in MATLAB/Octave ist die Matrix. Daher auch der Name MATLAB, der eine Abkürzung für MATrix LABoratory ist. Auch Skalare werden intern als 1x1 Matrix behandelt.Beispiel für ein Skalar: Die Definition der Variable skalar
als Skalar mit Wert 5.
Variablennamen, wie hier skalar
können beliebig
gewählt werden. Zur Wert-Zuweisung benutzt man den
Operator = .
>> skalar = 5Matlab/Octave antwortet darauf mit: skalar = 5Will man diese Ausgabe unterdrücken, so kann man dies mit einem Semikolon am Ende der Zeile bewirken. >> skalar = 5;Ein Vektor ist eine Matrix, wobei eine Spalte bzw. Reihe die Länge 1 besitzt. Definiere Zeilenvektor zeilenVektor
der Länge 3:
>> zeilenVektor = [ 2 4 8 ]Antwort von Matlab/Octave: zeilenVektor = 2 4 8Optional kann man die Werte mit Kommas trennen. >> zeilenVektor = [ 2, 4, 8 ]Antwort von Matlab/Octave: zeilenVektor = 2 4 8Will man einen Spalten-Vektoren definieren, so ersetzt man das Komma durch Semikolon: Definiere einen Spalten-Vektor spaltenVektor der Länge 3:
>> spaltenVektor = [ 1; 3; 9 ]
spaltenVektor =
1
3
9
Hier schreibt Matlab/Octave die Antwort, wie gewünscht,
in verschiedene Zeilen, d.h. der Vektor besitzt
nur eine Spalte (Spaltenvektor).
Will man einen Spaltenvektor in einen Zeilenvektor
umformen, kann man dies folgendermaßen
bewerkstelligen:
>>spaltenVektor_1 = zeilenVektor'
spaltenVektor_1 =
2
4
8
Die Konvertierung von Zeilenvektoren in Spaltenvektoren
funktioniert analog.
>>zeilenVektor_1 = spaltenVektor'
zeilenVektor_1 =
1 3 9
Der Übergang zu echten Matrizen ist einfach:
>>Matrix_3x3 = [ 1, 2, 3; 4, 5, 6; 7, 8, 9 ] Matrix_3x3 = 1 2 3 4 5 6 7 8 9Auf die einzelnen Elemente kann durch Angabe der Indizes (beginnend mit 1) zugegriffen werden: >>Matrix_3x3(2,3)
ans = 6
Hier wurde das Ergebnis nicht in einer
Variablen gespeichert.
Die Ausgabe erfolgt dann in ans
(für answer).
Matlab/Octave kennt auch komplexe Zahlen: >>komplexeMatrix_3x2 = [ 1 + 3i, 2 + 5i; 3, 7i; 4 + 3i , 2]
komplexeMatrix_3x2 =
1 + 3i 2 + 5i
3 + 0i 0 + 7i
4 + 3i 2 + 0i
Matrizen lassen sich auch mit Hilfe des (.)- und
(')-Operators transponieren, bzw.
transponieren und konjugieren:
>>transponiertMatrix = komplexeMatrix_3x2.'
transponierteMatrix =
1 + 3i 3 + 0i 4 + 3i
2 + 5i 0 + 7i 2 + 0i
>>transponiertUndkonjugierteMatrix = komplexeMatrix_3x2'
transponiertUndkonjugierteMatrix =
1 - 3i 3 - 0i 4 - 3i
2 - 5i 0 - 7i 2 - 0i
ZeichenfolgenZeichenfolgen (Strings) werden zwischen einfachen oder doppelten Anführungszeichen eingeschlossen. >>zeichenFolge = ["eine ", "Zeichenfolge"]
zeichenFolge = eine Zeichenfolge
Intern speichert Matlab/Octave Zeichenfolgen
als Matrizen von Zeichen.
Das bedeutet, dass folgende Definition analog der obigen ist.
>>gleicheZeichenFolge = ["eine Zeichenfolge"]
gleicheZeichenFolge = eine Zeichenfolge
StructsErgänzend sei erwähnt, dass es Strukturen (struct) wie in der Programmiersprache C gibt.WorkspaceInformationen über alle definierten Variablen, den Workspace, erhält man mit dem Befehl
>>who
*** local user variables:
Matrix_3x3 skalar spaltenVektor_1 zeilenVektor
komplexeMatrix_3x2 spaltenVektor zeichenFolge zeilenVektor_1
Noch mehr Information, wie z.B. die Dimensionen der Matrizen, gibt es mit
>>whos *** local user variables: prot type rows cols name ==== ==== ==== ==== ==== rwd matrix 3 3 Matrix_3x3 rwd complex matrix 3 2 komplexeMatrix_3x2 rwd scalar 1 1 skalar rwd matrix 3 1 spaltenVektor rwd matrix 3 1 spaltenVektor_1 rwd string 1 25 zeichenFolge rwd matrix 1 3 zeilenVektor rwd matrix 1 3 zeilenVektor_1Variablen, die man nicht mehr benötigt, können mit clear gelöscht werden, z.B. >>clear Matrix_3x3
Alle Variablen löscht man mit
>>clear all
Arithmetische OperatorenMatrixoperatorenBei den arithmetischen Operationen (wie +,-,* usw.) ist zu beachten, dass alle diese Operationen als Matrixoperationen verstanden werden müssen. Ist eine Matrixoperation nicht definiert, so ergibt der korrepondierende Matlab/Octave Aufruf eine Fehlermeldung. Beipiel: Definition von 2 Matrizen:>>A_2x3 = [1, 2, 3; 5, 6, 7]; >>B_3x3 = [9, 8, 7; 6, 5, 4; 3, 2, 1];Das Matrixprodukt zwischen A_2x3 und B_3x3 ist definiert: >>A_2x3 * B_3x3 ans = 30 24 18 102 84 66Das Produkt zwischen B_3x3 und A_2x3 aber nicht! Also erhält man eine Fehlermeldung (hier unter Octave): >>B_3x3 * A_2x3 error: operator *: nonconformant arguments (op1 is 3x3, op2 is 2x3) error: evaluating binary operator `*' near line 68, column 7Unter Matlab erhält man als Fehler: Inner matrix dimensions must agree Übung: Probieren Sie alle möglichen Arten von Multiplikationen, Additionen und Subtraktionen zwischen Matrizen, Vektoren und Skalaren aus! FeldoperatorenAußer den Matrixoperationen gibt es in vielen Fällen auch entsprechende Operationen, die elementweise zwischen den einzelnen Elementen der Matrizen (Vektoren) ausgeführt werden sollen. Diese werden in Matlab/Octave durch das Voranstellen eines Punktes (.) gekennzeichnet. Beispiel: >>A_2x3 = [1, 2, 3; 5, 6, 7];
>>C_2x3 = [1, 1, 2; 2, 3, 3];
>>A_2x3 .* C_2x3
ans =
1 2 6
10 18 21
Dagegen ist das Matrixprodukt
A_2x3 * C_2x3 nicht definiert.
PotenzenBei der Potenzierung unterscheidet man wieder zwischen der Matrix- und der elementweisen Operation.Die Matrixoperation wird mit dem Operator ^ dargestellt. Diese ist als Multiplikation der Matrix mit sich selbst (x-mal) zu verstehen und ist somit nur für quadratische Matrizen definiert. Beipiel: >>B_3x3 = [9, 8, 7; 6, 5, 4; 3, 2, 1];
>>B_3x3^2
ans =
150 126 102
96 81 66
42 36 30
Die elementweise Potenzierung mit Hilfe
des Operators .^
dagegen ist eine
Feldoperation zwischen den einzelnen
Komponenten der Matrizen.
>>A_2x3 = [1, 2, 3; 5, 6, 7]; >>C_2x3 = [1, 1, 2; 2, 3, 3]; >>A_2x3 .^ C_2x3 ans = 1 2 9 25 216 343 Inversion, Division und GleichungssystemeFür Matrizen sind Divisionen nicht direkt definiert. Betrachtet man allerdings eine Division als Multiplikation mit dem Inversen, so erhält man eine rechte und eine linke Division (für invertierbare quadratische Matrizen):d/e entspricht d * e^-1 d\e entspricht d^-1 * e Zuerst die Inversion: >>d = [2, 1; 3, 4];
>>d^-1
ans =
0.80000 -0.20000
-0.60000 0.40000
Die Inversion kann auch mit Hilfe der Funktion
inv(argument) ausgeführt werden.
>>e = [1, 3; 2, 3]; >>inv(e) ans = -1.00000 1.00000 0.66667 -0.33333Die rechte Division d/e entspricht d * e^-1: >> d * e^-1 ans = -1.33333 1.66667 -0.33333 1.66667Direkt: >>d/e ans = -1.33333 1.66667 -0.33333 1.66667Und die linke Division d\e, die d^-1 * e entspricht. >>d^-1 * e ans = 0.40000 1.80000 0.20000 -0.60000oder direkt: >>d\e ans = 0.40000 1.80000 0.20000 -0.60000Mit Hilfe der Inversion bzw. Division lassen sich lineare Gleichungssysteme lösen. Diese lassen sich als Matrix-Vektor Gleichung schreiben. (Zur allgemeinen Lösbarkeit solcher linearen Gleichungssysteme vgl. Lehrbücher der linearen Algebra). A * x = y mit A: invertierbare (nicht singuläre) Koeffizientenmatrix (dim x dim) x: gesuchter Spaltenvektor (dim x 1) y: Spaltenvektor der Inhomogenitäten (dim x 1) Die Lösung für x ist somit: x = A^-1 * y Beispiel: >> A = [1, 3; 2, 3]; >> y = [1; 3]; >> x x = 2.00000 -0.33333Überprüfung: >>A * x ans = 1 3 Vergleichsoperatoren, Logische Operatoren und WahrheitswerteDie beiden Wahrheitswerte (falsch und wahr) werden mit den beiden Zahlen 0 und 1 codiert. Außerdem gelten im logischen Kontext alle Zahlen ungleich Null als wahr.Vergleichsoperatoren (relationale Operatoren): < <= > >= == !=(ungleich) sind Feldoperatoren, d.h. sie vergleichen alle Einträge zwischen zwei Matrizen, Vektoren bzw. Skalaren. Beide Operanden müssen dabei wieder die gleichen Längen in allen Dimensionen besitzen oder ein Operand muss ein Skalar sein. Beispiel: >> a = [1, 3; 2, 3]; >> b = [1, 4; 3, 3]; >> a != b ans = 0 1 1 0Beispiel für einen Vergleich zwischen einer Matrix und einem Skalar:
>> c = 3;
>> a == c
ans =
0 1
0 1
Die wichtigsten logischen
(Feld-)Operatoren sind:
Und: & Oder: | Nicht: ~ xor(operand1, operand2) >>a = [0, 1; 0, 1];
>>b = [1, 0; 0, 1];
>>xor(a,b)
ans =
1 1
0 0
>>a & b
ans =
0 0
0 1
Weitere VariablendefinitionsmöglichkeitenVektoren und Matrizen können auf verschiedene Weise (um-)definiert werden: Eine Matrix kann um eine weitere Zeile ergänzt werden:>>matrix = [1, 2 , 3; 4, 5, 6]; >>matrix = [matrix; 7, 8, 9] ans = 1 2 3 4 5 6 7 8 9oder um eine weitere Spalte : >> matrix = [ matrix, [10; 11; 12] ] matrix = 1 2 3 10 4 5 6 11 7 8 9 12Zum Löschen der Zeilen oder Spalten muss man diese mit einem leeren Vektor [] überschreiben. Zur Indizierung aller Elemente in der gewünschten Zeile oder Spalte benutzt man den Platzhalter : ,der alle Indizes anspricht. Löschen der ersten Spalte >>matrix(:,1) = [] matrix = 2 3 10 5 6 11 8 9 12 und anschließend der zweiten Zeile: >>matrix(2,:) = [] matrix = 2 3 10 8 9 12Auf die gleiche Weise kann man natürlich auch ganze Zeilen und Spalten auf einmal mit neuen Werten belegen: >>matrix(:,2) = [1; 2] matrix = 2 1 10 8 2 12Ein Vektor lässt sich mit konstantem Inkrement automatisch erzeugen: (Startwert: Inkrement: maximaler Endwert) Also ein Zeilen-Vektor: >>vector = (-0.5:0.3:0.5)
vector =
-0.50000 -0.20000 0.10000 0.40000
Ein Spalten-Vektor:
>>vector = (-1:0.5:1)' vector = -1.00000 -0.50000 0.00000 0.50000 1.00000Slicing, das sind Ausschnitte aus Vektoren, kann man ebenfalls direkt erhalten: vektor(m:n) ist das Slice des Vektors
vektor vom m-ten bis zum n-ten Eintrag:
>>vector(3:5)
ans =
0.00000
0.50000
1.00000
Bei Matrizen erhält man so Submatrizen:
>>vector = (1:0.1:1.5); >>matrix = [vector ; vector * 2; vector * 3 ] matrix = 1.0000 1.1000 1.2000 1.3000 1.4000 1.5000 2.0000 2.2000 2.4000 2.6000 2.8000 3.0000 3.0000 3.3000 3.6000 3.9000 4.2000 4.5000 >>matrix(2:3, 2:4) ans = 2.2000 2.4000 2.6000 3.3000 3.6000 3.9000 KonstantenMatlab/Octave kennt mathematische Konstanten, wie: pi, e
FunktionenHilfe zu einer Funktion erhält man durch das Kommandohelp function, wobei function
für die Funktion steht, zu der man Hilfe benötigt.
Der alleinige Aufruf von help
ergibt eine Übersicht über Matlab/Octave.
Probieren Sie es aus!
Mathematische FunktionenAlle gängigen mathematischen Funktionen sind in Matlab/Octave implementiert, z.B.:sin, cos, exp, log, atan, abs Benutzt man diese auf Vektoren bzw. Matrizen, werden die Funktionen elementweise angewendet. Beispiel: >>a = ( 0 : pi/5 : 2 * pi)' >>b = sin(a) b = 0.00000 0.58779 0.95106 0.95106 0.58779 0.00000 -0.58779 -0.95106 -0.95106 -0.58779 -0.00000 Vektor- und MatrixfunktionenEs gibt hilfreiche Vektor und Matrixfunktionen:length(v) gibt die Länge des
Vektors vector zurück.
size(matrix) gibt die Anzahl der
Zeilen und Spalten der Matrix matrix
als Zeilenvektor [Zeilen, Spalten] zurück.
eye(m,n) erzeugt eine m x n Matrix mit
1-ern auf der Hauptdiagonalen.
zeros(m,n) erzeugt eine Nullmatrix.
ones(m,n) erzeugt eine Matrix, deren Elemente gleich 1 sind.
rand(m,n) erzeugt eine
Zufallsmatrix mit gleichverteilten Einträgen
[0,1[.
Beispiel: >>eye(3,3) ans = 1 0 0 0 1 0 0 0 1 GraphikIm Rahmen dieser Einführung werden nur die wichtigsten Graphikfunktionen vorgestellt.2-dim GraphikfunktionenEinen 2-dim Funktionsplot erhält man mitplot(x-Vektor, y-Vektor).
Beispiel: >>a = ( 0 : pi/20 : 2 * pi); >>plot(a, sin(a))Die Art, wie der Graph geplottet werden soll, wird duch einen dritten Parameter eingestellt (durchgezogene Linien, Kreise, gepunktet, Beschriftung etc.) Beispiel Kreise (o) in rot(r) mit Graphbeschriftung "Sin": >>a = ( 0 : pi/20 : 2 * pi); >>plot(a, sin(a), "or;Sin;")Auch lassen sich mehrere Funktionen gleichzeitig plotten: >> plot (a, cos(a), ".;Cosinus;", a, sin(a), "+3;Sinus;");
Mehr Information zur Darstellung erhalten Sie über die Hilfe
help plot.
Mit xlabel("gewünschte Beschriftung
der x-Achse") bzw.
ylabel("gewünschte Beschriftung
der y-Achse")
lassen sich die x- bzw. y-Achse dann beschriften.
Mit title("gewünschte Überschrift")
wird die Überschrift gewählt.
Mit figure lässt sich ein neuer Graph öffnen.
Und mit axis(x-min, x-max, y-min, y-max)
aus diesem ein Ausschnitt wählen.
>>xlabel("Zeit / s")
>>ylabel("Amplitude / V")
>>titel("Nur ein Beispiel")
>>figure
>>axis([1,4,-0.5, 1])
3-dim Graphikfunktionen3-dim Graphikplot können mit Hilfe der Funktionmesh erzeugt werden.
Versuchen Sie folgendes Beispiel vollständig
zu verstehen!
x = (-10:0.5:10);
y = (-10:0.5:10)';
v = ones(length(x),1);
xx = v * x;
yy = y * v';
f = cos( (0.2*xx).^2 + (0.4*yy).^2 ) .* exp( -0.04 * (xx.^2 + yy.^2) );
axis([-10, 10, -10, 10]);
mesh(x, y, f)
Das Erzeugen des x- bzw. y-"Grids"
(hier Variablenname xx bzw.
yy) lässt sich einfacher
mit der Hilfsfunktion [xx, yy] = meshgrid(x,y)
bewerkstelligen:
x = (-10:0.5:10);
y = (-10:0.5:10)';
[xx, yy] = meshgrid(x, y);
f = cos( (0.2*xx).^2 + (0.4*yy).^2 ) .* exp( -0.04 * (xx.^2 + yy.^2) );
axis([-10, 10, -10, 10]);
mesh(x, y, f)
Input- und Output-RoutinenDer laufende Workspace kann gelesen und geschrieben werden:
>> save curWorkspacespeichert den Workspace im File curWorkspace ab.
>> load curWorkspacelädt den Workspace aus dem File curWorkspace wieder ein. Externe ascii-Dateien können auch mit load
geladen und geschrieben werden. In der ascii-Datei müssen
die Daten allerdings im Matrixformat vorliegen.
Beispiel:
Es existiert die Datei bsp.txt im laufenden Verzeichnis:
chris@aristoteles:~> more bsp.txt 1 1 1 2 1 4 2 3Diese Datei kann mit Hilfe von load
(standardmäßig in die Variable bsp) eingeladen werden,
falls man sich in Matlab/Octave im gleichen
Verzeichnis befindet oder das Verzeichnis im Suchpfad liegt
(siehe unten):
>>load bsp.txt
>>bsp
bsp =
1 1
1 2
1 4
2 3
Mit Hilfe von path kann man sich den
Suchpfad von Matlab/Octave anzeigen lassen.
>>path Octave's search path contains the following directories: . /usr/local/libexec/octave/2.1.57/site/oct/i686-pc-linux-gnu// /usr/local/libexec/octave/site/oct/api-v8/i686-pc-linux-gnu// /usr/local/libexec/octave/site/oct/i686-pc-linux-gnu// /usr/local/share/octave/2.1.57/site/m// /usr/local/share/octave/site/api-v8/m// /usr/local/share/octave/site/m// /usr/local/libexec/octave/2.1.57/oct/i686-pc-linux-gnu// /usr/local/share/octave/2.1.57/m//Mit Hilfe von path(path, "/home/chris/myOctave")
lässt sich ein Verzeichnis zum Suchpfad hinzufügen.
ProgrammierungScript-FilesMit einem beliebigen Texteditor (Mathlab besitzt einen eingebauten Editor) kann man Befehlssequenzen in einem ascii-File mit der Endung .m (sogenannte m-Files ) abspeichern. Liegen diese im Suchpfad lässt sich das Script aus der Matlab/Octave Komandozeile durch den Aufruf des Dateinamens (ohne die Endung .m) ausführen. Kommentare werden mit einem vorangestellten % gekennzeichnet. Die ersten zusammenhängenden Kommentarzeilen am Anfang der Datei werden als Scriptbeschreibung beim Aufrufhelp scriptname ausgegeben.
Man soll aber keine Dateinamen benutzen, die genauso wie eingebaute Befehle lauten. Dies lässt sich mit help name
überprüfen.
Beispiel: In die ascii-Datei myFirst.m wird das folgende Script geschrieben: % Nur ein Beispiel % 3D-Plot % dies wird nicht mehr als Hilfe ausgegeben x = (-10:0.5:10); y = (-10:0.5:10)'; v = ones(length(x),1); X = v * x; Y = y * v'; f = cos( (0.2*X).^2 + (0.4*Y).^2 ) .* exp( -0.04 * (X.^2 + Y.^2) ); axis([-10, 10, -10, 10]); mesh(x, y, f)Steht dieses im Suchpfad, so kann man es und die korrespondierende Hilfe aufrufen: >>myFirst
>>help myFirst
myFirst is the file: /home/chris/tmp/myFirst.m
Nur ein Beispiel
3D-Plot
Nach dem Aufruf sind die im Script-File definierten
Variablen im Workspace bekannt (im Gegensatz zu den
noch folgenden "selbstgeschriebenen"
Funktionen)
KontrollstrukturenMatlab/Octave besitzt die für Programmiersprachen üblichen Kontrollstrukturen.SchleifenDiefor-Schleife:
for i=0:-2:-10
printf("%d\n",i);
end
Die hier benutzte formatierte Ausgabe
ist analog zu der Sprache C.
Und die while-Schleife:
while a < A a=a+1; end BedingungenDie if-Anweisung:if a==0 error( "a ist 0!" ) else b=c/a; endDie switch-Anweisung: switch pnorm case 1; sum(abs(v)) case inf; max(abs(v)) otherwise sqrt(v *v) end Funktionen (selbstgeschrieben)Funktionen werden wie Scripte in einer m-Datei gespeichert und analog aufgerufen. Diesen kann man jedoch Parameter übergeben. In der ersten Zeile der ascii-Datei steht hierzu:function[Ausgabeparameter]= nameDerFunction(Eingabeparameter)
Die Funktion sollte dabei den gleichen Name wie die Datei (ohne die Endung .m) besitzen. Ausgabeparameter steht hier für eine Liste von
Parametern, in denen Ergebnisse gespeichert werden können.
Eingabeparameter steht hier für die Liste der
Eingabeparameter der Funktion.
Beispiel: Datei beispielPlot3d.m function [x, y] = beispielPlot3d(x_scale, y_scale, daemp) % Nur ein Beispiel % 3D-Plot als Function % usage: [x, y] = beispielPlot3d(x_scale, y_scale, daemp) % x % dies wird nicht mehr als Hilfe ausgegeben x = (-10:0.5:10); y = (-10:0.5:10)'; v = ones(length(x),1); X = v * x; Y = y * v'; f = cos( (x_scale*X).^2 + (y_scale*Y).^2 ) .* exp( -daemp * (X.^2 + Y.^2) ); axis([-10, 10, -10, 10]); mesh(x, y, f)Aufruf: >> beispielPlot(.4, 0.6, 0.02)Verdeutlichung der Ausgabeparameterliste: >>clear all >> [a, b] = beispielPlot3d( 0.4, 0.6 , 0.02);Welche Variablen befinden sich im Workspace und welchen Inhalt besitzen diese? Die Eingangsparameter werden durch Aufruf von Funktionen nicht verändert (call-by-value) und die Variablen in der Funktion sind nur in der Funktion bekannt. Eine Änderung der Variablen des aufrufenden Workspace ist lediglich über die Ausgabeparameter der Funktion möglich. Die Unterschiede zu Scripten sei hier noch einmal betont:
Menüleiste fehlt? Klick hier! Home Klick hier . |