Matlab Command Window

Im Command Window gibt man, wie der Name schon sagt, Befehle ein. Diese werden unmittelbar nach dem Prompt >> eingetippt.

Erste Befehle

Gibt man zum Beispiel a=5 ein, erscheint ein Feedback, dass die Variable a erstellt wurde, und sie den Wert 5 zugewiesen bekommen hat.

a = 5
a =  5

Matlab gibt nach Eingabe eines Kommandos immer eine Rückmeldung, in diesem Fall wird die Variable noch einmal ausgegeben. Diese Rückmeldung kann mit Hilfe des Semikolons unterdrückt werden:

b = 2*pi;

Beide Variablen sind nun im Workspace hinterlegt und können für weitere Berechnungen benutzt werden. Wir können uns zum Beispiel den Wert von b ausgeben lassen,

b
b =  6.2832

oder einfache Rechenoperationen ausführen:

b/a + 1i*sin(pi/8)
ans =  1.25664 + 0.38268i

Das Ergebnis der Rechnung wird unter dem Variablennamen ans im Workspace hinterlegt. Wir können dem Ergebnis explizit einen Variablennamen, hier c, zuordnen:

c = b/a + 1i*sin(pi/8)
c =  1.25664 + 0.38268i

Wenn wir möchten, können wir die Ausgabe des Ergebnisses unterdrücken, indem wir die Zeile mit einem Semikolon beenden:

d = exp(b/a - i*sin(pi/8));

Einige wichtige Punkte konnten wir bisher beobachten:

  • Variablenzuweisungen passieren von links nach rechts: Was rechts vom Gleichheitszeichen steht, wird der Variablen die links vom Gleichheitszeichen steht zugeordnet. Wenn es diese Variable nicht gibt, wird sie im Workspace hinterlegt.

  • Matlab bietet eine Vielzahl von mathematischen Funktionen an, die regelmäßig gebraucht werden, wie z.B. die Exponentialfunktion exp oder das Rechnen mit komplexen Zahlen. Dabei können sowohl 1i, 1j als auch i und j als Symbole für die komplexe Einheit verwendet werden. Die letzten beiden Varianten sind aber potenziell gefährlich, da es auch valide Variablennamen sind und es so zu Verwechslungen kommen kann.

  • Alle Variablen werden im Workspace hinterlegt und können anschließend für weitere Berechnungen verwendet werden.

  • In Matlab werden die skalaren Datentypen (integer, double, float, …) nicht explizit angegeben, wie man es von Sprachen wie C oder C++ vielleicht gewöhnt ist. Auch wenn die Variable a ganzzahlig ist, geht Matlab standardmäßig von double aus. Der Typ einer Variable lässt sich in Matlab durch die Funktion class() ausgeben:

class(a)
ans = double

Unter Umständen kann es sinnvoll sein, nochmal mit einem frischen Workspace zu starten. Der Inhalt des Workspace lässt sich mit dem Befehl clear leeren.

Vektoren und Matrizen

Matlab ist ein Kofferwort aus Matrix-Laboratory. Der Name impliziert schon, dass es sich ideal dazu eignet mit Matrizen und Vektoren zu arbeiten. Dabei wird nicht zwischen den beiden unterschieden: Ein Zeilenvektor mit \(n\) Einträgen ist einfach eine Matrix aus \(\mathbb{R}^{1 \times n}\), während ein Spaltenvektor mit \(n\) Einträgen eine Matrix aus \(\mathbb{R}^{n \times 1}\) ist.

In Matlab werden Matrizen mit eckigen Klammern geschrieben, ein Semikolon beendet eine Zeile:

e = [1, 2, 3, 4, 5] % ein Zeilenvektor
f = [1; 2; 3; 4; 5] % ein Spaltenvektor
e =

   1   2   3   4   5

f =

   1
   2
   3
   4
   5

Matrizen erzeugt man auf dieselbe Art:

A = [11, 12; 21, 22]
A =

   11   12
   21   22

Mit runden Klammern können wir auf einzelne Elemente zugreifen und auch überschreiben:

e(2)
ans =  2
e(1:3)
ans =

   1   2   3
e(3) = 42
e =

    1    2   42    4    5
e(3) = 3
e =

   1   2   3   4   5
A(2,2)
ans =  22
A(1,1) = 42
A =

   42   12
   21   22

Matlab verwendet ein sogenanntes column-major Speicherformat für Matrizen. Das heißt, dass Matrizen im Speicher spaltenweise gespeichert werden. Für die Matrix A sähe das in etwa so aus:

42 21 12 22

Wir können uns alle Elemente der Matrix A, so wie sie von Matlab gespeichert werden ausgeben, in dem wir den Index durch einen Doppelpunkt ersetzen:

A(:)
ans =

   42
   21
   12
   22

Für Matrizen kann man daher sowohl durch Angabe zweier Indizes als auch durch Angabe eines Index auf Elemente zugreifen:

A(3)
ans =  12
A(3) = 5
A =

   42    5
   21   22
A(1,2)
ans =  5

Produkte von Vektoren und Matrizen

Beim Produkt zweier Vektoren \(\mathbf{e}\) und \(\mathbf{f}\) (bzw. Matrixprodukt zweier Matrizen) ist stets darauf zu achten, dass die Dimensionen zueinander passen! Können wir die eben erstellten Vektoren \(e\) und \(f\) miteinander multiplizieren?

e*f
ans =  55

Aha, bei Multiplikation eines \((1,n)\)-dimensionalen Vektors \(\mathbf{e}\) mit einem \((n,1)\)-dimensionalen Vektor \(\mathbf{f}\) erhalten wir eine Zahl, bzw. eine \((1,1)\)-dimensionale Matrix mit nur einem Eintrag. Wir erhalten das Skalarprodukt

\[ \mathbf{e} \cdot \mathbf{f} = \sum_{i=1}^n e_i \cdot f_i. \]
f*e
ans =

    1    2    3    4    5
    2    4    6    8   10
    3    6    9   12   15
    4    8   12   16   20
    5   10   15   20   25

Die Multiplikation eines \((n,1)\)-dimensionalen Vektors \(\mathbf{f}\) mit einem \((1,n)\)-dimensionalen Vektor \(\mathbf{e}\) liefert also eine \((n,n)\)-dimensionale Matrix. Es handelt sich um das diadische Produkt

\[ A = \mathbf{f} \cdot \mathbf{e}, \hskip0.5cm A_{ij} = f_i \cdot e_j \]

Wie sieht es mit den folgenden Matrizen aus?

g = [1; 1; 1];
h = [2; 2; 2];
g*h
error: operator *: nonconformant arguments (op1 is 3x1, op2 is 3x1)

Nein! Es klappt nicht. Die Fehlermeldung gibt schon Auskunft darüber wieso: Die Dimensionen der Matrizen passen nicht zusammen.

Hinweis

Hier ist der Wortlaut der Octave-Fehlermeldung zu sehen. Matlab gibt an dieser Stelle die folgende Fehlermeldung wieder:

Error using  * 
Incorrect dimensions for matrix multiplication. Check that the number of columns in
the first matrix matches the number of rows in the second matrix. To perform
elementwise multiplication, use '.*'.

Wir behelfen uns eines Tricks: Ein nachgestelltes Apostroph gibt die transponierte Matrix aus.

g
g =

   1
   1
   1
size(g)
ans =

   3   1
g'
ans =

   1   1   1
size(g')
ans =

   1   3

Das Skalarprodukt von \(\mathbf{g}\) mit \(\mathbf{h}\) können wir also doch ausrechnen:

g'*h
ans =  6

Sehr häufig ist es nützlich, Operationen komponentenweise auszuführen. Nehmen wir zum Beispiel an, in einer kleinen Arbeitsgruppe arbeiten fünf Personen. Zwei Mitarbeiter:innen haben Vollzeitstellen, d.h. 39.5 Stunden pro Woche, eine:r Mitarbeiter:in hat eine halbe Stelle und zwei studentische Hilfskräfte unterstützen jeweils mit acht Stunden pro Woche. Die wöchentliche Arbeitszeit der Mitarbeiter:innen hinterlegen wir in einem Vektor

weekly_hours = [39.5, 19.5, 39.5, 8, 8];

Die stündlichen Bruttokosten der Stellen der Mitarbeiter:innen in € schreiben wir ebenfalls in einen Vektor:

costPerHour_brutto_euro = [57.5, 57.5, 40, 15, 15];

Wenn wir wissen möchten, wieviel die Mitarbeiter:innen jeweils pro Woche kosten, müssen wir die Vektoren komponentenweise miteinander multiplizieren. Das erreichen wir in Matlab, indem wir vor dem *-Operator einen Punkt voranstellen, es ist also eine punktweise Operation, und keine Matrixmultiplikation:

weekly_hours.*costPerHour_brutto_euro
ans =

   2271.25   1121.25   1580.00    120.00    120.00

Quiz: Wie berechnen wir die Gesamtkosten aller Mitarbeiter:innen pro Woche mit nur einer Zeile in Matlab?

Hinweis

Das Ergebnis lautet 5212.5 €.

% calculate weekly total cost

Spezielle Matrizen

Matlab hat einige Befehle, um spezielle Matrizen zu erstellen. Einige der wichtigsten sind:

A1 = eye(2);     % 2,2-Einheitsmatrix
A2 = ones(3,2);  % 3,2-Matrix gefuellt mit 1
A3 = zeros(2,4); % 2,4-Matrix gefuellt mit 0
A4 = rand(2);    % 2,2-Matrix mit gleichverteilten Zufallszahlen von 0 bis 1
A5 = randn(4);   % 4,4-Matrix mit normalverteilten Zufallszahlen um 0 und Standardabweichung 1

Funktionen komponentenweise ausführen

Viele der mathematischen Funktionen, wie sin, cos, exp, sqrt etc., können auch direkt auf Vektoren und Matrizen angewandt werden. Sie werden dann komponentenweise ausgeführt:

A4
disp('Die Wurzel der Elemente von A4:')
sqrt(A4)
A4 =

   0.44656   0.73537
   0.18055   0.95080

Die Wurzel der Elemente von A4:
ans =

   0.66825   0.85754
   0.42491   0.97509

Nehmen wir zum Beispiel an, wir haben \(n\) Vektoren \(\mathbf{v}_i = (x_i, y_i, z_i)\), \(i=1,...,n\). Wenn wir die \(x\)-, \(y\)-, und \(z\)-Komponenten der Vektoren als X, Y und Z speichern, können wir in nur einer Zeile den Betrag der Vektoren berechnen:

n=20;
X = randn(n,1);
Y = randn(n,1);
Z = randn(n,1);
% calculate magnitude of vectors
sqrt(X.^2 + Y.^2 + Z.^2)
ans =

   1.27082
   2.12935
   2.28378
   1.48039
   1.84512
   1.88619
   1.88152
   2.68298
   1.53354
   3.08340
   1.50169
   1.85289
   2.29875
   1.74458
   1.62807
   1.15378
   1.77924
   1.92541
   0.81153
   1.52136

Zusatzfrage: Wozu dienen die Punkte in der Vorschrift sqrt(X.^2 + Y.^2 + Z.^2)?

Concatenation und Slicing

Oft kann es sinnvoll sein, einzelne Vektoren oder Matrizen zu größeren zusammenzufügen. Das nennt man Concatenation. Die zuvor erstellten Matrizen X, Y, Z sind schließlich nicht unabhängig voneinander, sie bezeichnen die Komponenten von \(n\) Vektoren \(v_i\). Um dies zu verdeutlichen, können wir eine \((n,3)\)-Matrix erstellen, deren Zeilen die jeweiligen Vektoren \(v_i\) sind, und die Spalten die jeweiligen Komponenten X, Y und Z:

V = [X,Y,Z]
V =

  -0.322496   0.276267   1.197767
   0.184774  -1.895761   0.951878
  -0.901812   1.705073   1.222752
  -0.674568  -1.317111   0.041429
  -0.296170  -1.678014   0.707831
   1.467738  -0.762423   0.906740
  -1.074790  -0.040866  -1.543783
   0.568760   2.621381   0.057240
  -0.397382   1.169356  -0.909087
   1.089513  -2.831767   0.549000
   0.327851   1.032975  -1.039488
   0.145657  -0.836806   1.646732
  -1.588139  -1.661264  -0.047459
   1.391289   0.329041  -0.999795
  -1.326279   0.942947   0.049580
   0.103442  -1.022502   0.524393
  -0.293752  -1.692801  -0.462420
  -0.232870  -0.499655   1.844812
  -0.578842  -0.561705  -0.089501
   1.133429   0.979685   0.264775

Wie bei Matrixprodukten müssen wir auf die richtige Dimension achten. Was passiert genau bei folgendem Befehl?

V = [X,Y;Z]
error: vertical dimensions mismatch (20x2 vs 20x1)

Concatenation ist also das Zusammenfügen von Matrizen. Der gezielte Zugriff auf Subblöcke aus einer Matrix wird als Slicing bezeichnet. In Matlab wird dazu der :-Operator verwendet. Mit folgenden Befehlen erhält man die ersten fünf Zeilen der Matrix V:

V(1:5,:)
ans =

  -0.322496   0.276267   1.197767
   0.184774  -1.895761   0.951878
  -0.901812   1.705073   1.222752
  -0.674568  -1.317111   0.041429
  -0.296170  -1.678014   0.707831

Im Gegensatz zu C/C++, fangen wir bei Matlab immer bei 1 an zu zählen und nicht bei 0. Der Doppelpunkt nach dem Komma gibt Auskunft darüber, dass alle Spalten ausgegeben werden sollen. Wenn nur die ersten beiden Spalten ausgegeben werden sollen kann man V(1:5,1:2) eingeben.

Alle Vektoren, bis auf die ersten 15, erhalten wir mit Hilfe des Wortes end, das für die Größe der jeweiligen Dimension steht:

V(16:end,:)
ans =

   0.103442  -1.022502   0.524393
  -0.293752  -1.692801  -0.462420
  -0.232870  -0.499655   1.844812
  -0.578842  -0.561705  -0.089501
   1.133429   0.979685   0.264775

Wir können uns auch jeden zweiten Vektor ausgeben lassen, indem wir eine ganzzahlige Schrittweite mit angeben:

V(1:2:end,:)
ans =

  -0.322496   0.276267   1.197767
  -0.901812   1.705073   1.222752
  -0.296170  -1.678014   0.707831
  -1.074790  -0.040866  -1.543783
  -0.397382   1.169356  -0.909087
   0.327851   1.032975  -1.039488
  -1.588139  -1.661264  -0.047459
  -1.326279   0.942947   0.049580
  -0.293752  -1.692801  -0.462420
  -0.578842  -0.561705  -0.089501

Die Schrittweite kann auch negativ gewählt werden:

V(end:-1:1,:)
ans =

   1.133429   0.979685   0.264775
  -0.578842  -0.561705  -0.089501
  -0.232870  -0.499655   1.844812
  -0.293752  -1.692801  -0.462420
   0.103442  -1.022502   0.524393
  -1.326279   0.942947   0.049580
   1.391289   0.329041  -0.999795
  -1.588139  -1.661264  -0.047459
   0.145657  -0.836806   1.646732
   0.327851   1.032975  -1.039488
   1.089513  -2.831767   0.549000
  -0.397382   1.169356  -0.909087
   0.568760   2.621381   0.057240
  -1.074790  -0.040866  -1.543783
   1.467738  -0.762423   0.906740
  -0.296170  -1.678014   0.707831
  -0.674568  -1.317111   0.041429
  -0.901812   1.705073   1.222752
   0.184774  -1.895761   0.951878
  -0.322496   0.276267   1.197767

Zusatzfrage: Wie können wir uns die letzten fünf Zeilen einer Matrix ausgeben lassen, ohne explizit die Größe der Matrix zu kennen?

% get last 5 elements of V

Logische Indizierung

Der folgende Befehl liefert Auskunft darüber, welche Elemente der Matrix X größer oder gleich null sind:

X>=0
ans =

  0
  1
  0
  0
  0
  1
  0
  1
  0
  1
  1
  1
  0
  1
  0
  1
  0
  0
  0
  1

Das Ergebnis ist wieder eine Matrix, deren Einträge entweder 1 sind, falls der jeweilige Eintrag in X größer oder gleich null ist, oder 0 wenn der jeweilige Eintrag kleiner als null ist. Matlab speichert diese Werte nicht als double ab, sondern als logical-, d.h. boolsche Werte. Wir können dem Ergebnis der Abfrage wieder einen Namen geben:

Xpos = X>0;
class(Xpos)
ans = logical

Um nun alle Vektoren (Zeilen in V) zu erhalten, deren \(x\)-Komponente größer oder gleich null ist, kann diese logical-Matrix direkt als Zeilenindex verwendet werden.

V(Xpos,:)
ans =

   0.184774  -1.895761   0.951878
   1.467738  -0.762423   0.906740
   0.568760   2.621381   0.057240
   1.089513  -2.831767   0.549000
   0.327851   1.032975  -1.039488
   0.145657  -0.836806   1.646732
   1.391289   0.329041  -0.999795
   0.103442  -1.022502   0.524393
   1.133429   0.979685   0.264775

Zusatzfrage: Was macht der folgende Befehl?

V(V(:,2)<0,:)
ans =

   0.184774  -1.895761   0.951878
  -0.674568  -1.317111   0.041429
  -0.296170  -1.678014   0.707831
   1.467738  -0.762423   0.906740
  -1.074790  -0.040866  -1.543783
   1.089513  -2.831767   0.549000
   0.145657  -0.836806   1.646732
  -1.588139  -1.661264  -0.047459
   0.103442  -1.022502   0.524393
  -0.293752  -1.692801  -0.462420
  -0.232870  -0.499655   1.844812
  -0.578842  -0.561705  -0.089501

Zusatzfrage: Wie erhalten wir mit nur einem Befehl alle Vektoren, deren Betrag kleiner als 1 ist?

% get all rows with a magnitude < 1

Denken Sie daran, dass die Gleichheit zweier Variablen mit == abgefragt wird!

Gleichungssysteme lösen

Natürlich bietet Matlab auch viele weitere Funktionen rund um Matrizen und Vektoren, um uns das Leben zu erleichtern. So kann ein Gleichungssystem \(A\cdot \mathbf{x} = \mathbf{b}\) einfach und effizient mit dem sogenannten backslash-Operator gelöst werden.

A=[1,2,3;4,5,-6;7,8,9];
b=[0.1,0.2,0.3]';
x = A\b                     % x = inv(A)*b
x =

  -3.3333e-02
   6.6667e-02
  -1.4456e-18

Also ist Matlab ein Taschenrechner? Ja, genau! Aber ein ziemlich cooler, mit extrem vielen Funktionen und der Möglichkeit beliebig viele Variablen als Matrizen im Zwischenspeicher vorzuhalten.

Matlab ist aber auch noch mehr, nämlich eine Turing-vollständige Computersprache. Die Mächtigkeit von Matlab kommt erst zur Geltung, wenn wir anfangen Skripte und Funktionen zu schreiben.